[cig-commits] r11749 - in cs/portal/trunk/seismo/SeismoWebPortal: . designs/plone site static templates templates/SeismoWebPortal templates/registration

leif at geodynamics.org leif at geodynamics.org
Thu Apr 3 15:25:01 PDT 2008


Author: leif
Date: 2008-04-03 15:25:00 -0700 (Thu, 03 Apr 2008)
New Revision: 11749

Added:
   cs/portal/trunk/seismo/SeismoWebPortal/config.py
   cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/style.css
   cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/style.py
Removed:
   cs/portal/trunk/seismo/SeismoWebPortal/static/css/
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_form.html
Modified:
   cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/Document.html
   cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/Document.py
   cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/__init__.py
   cs/portal/trunk/seismo/SeismoWebPortal/forms.py
   cs/portal/trunk/seismo/SeismoWebPortal/gui.py
   cs/portal/trunk/seismo/SeismoWebPortal/list_detail.py
   cs/portal/trunk/seismo/SeismoWebPortal/models.py
   cs/portal/trunk/seismo/SeismoWebPortal/site/urls.py
   cs/portal/trunk/seismo/SeismoWebPortal/templates/404.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/500.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/desktop.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_search_results.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_upload.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineosmodel_upload.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/password_change_form.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/readme.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/registration_form.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dgloberequest_form.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/splash.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_detail.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_upload.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/user_map.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/userinfo_form.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/login.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset_done.html
   cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset_email.txt
   cs/portal/trunk/seismo/SeismoWebPortal/views.py
Log:
Removed hard-coded references to old URL root ("/specfem3dglobe/").
The portal now learns its root automatically.


Added: cs/portal/trunk/seismo/SeismoWebPortal/config.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/config.py	                        (rev 0)
+++ cs/portal/trunk/seismo/SeismoWebPortal/config.py	2008-04-03 22:25:00 UTC (rev 11749)
@@ -0,0 +1,2 @@
+
+root = None

Modified: cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/Document.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/Document.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/Document.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -18,7 +18,7 @@
     <!--[if lt IE 7]>
         <style type="text/css" media="all">@import url(http://www.geodynamics.org/cig/IEFixes.css);</style>
     <![endif]-->
-    <link href="/specfem3dglobe/css/style.css" type="text/css" rel="stylesheet" media="all" />
+    <link href="$root/designs/plone/style.css" type="text/css" rel="stylesheet" media="all" />
     <title>$title</title>
 </head>
 <body>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/Document.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/Document.py	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/Document.py	2008-04-03 22:25:00 UTC (rev 11749)
@@ -33,10 +33,10 @@
 currentTime=time.time
 __CHEETAH_version__ = '2.0rc7'
 __CHEETAH_versionTuple__ = (2, 0, 0, 'candidate', 7)
-__CHEETAH_genTime__ = 1206064108.9756939
-__CHEETAH_genTimestamp__ = 'Thu Mar 20 18:48:28 2008'
+__CHEETAH_genTime__ = 1207258007.506633
+__CHEETAH_genTimestamp__ = 'Thu Apr  3 14:26:47 2008'
 __CHEETAH_src__ = 'Document.html'
-__CHEETAH_srcLastModified__ = 'Thu Mar 20 18:47:45 2008'
+__CHEETAH_srcLastModified__ = 'Thu Apr  3 14:18:05 2008'
 __CHEETAH_docstring__ = 'Autogenerated by CHEETAH: The Python-Powered Template Engine'
 
 if __CHEETAH_versionTuple__ < RequiredCheetahVersionTuple:
@@ -103,8 +103,10 @@
     <!--[if lt IE 7]>
         <style type="text/css" media="all">@import url(http://www.geodynamics.org/cig/IEFixes.css);</style>
     <![endif]-->
-    <link href="/specfem3dglobe/css/style.css" type="text/css" rel="stylesheet" media="all" />
-    <title>''')
+    <link href="''')
+        _v = VFFSL(SL,"root",True) # '$root' on line 21, col 17
+        if _v is not None: write(_filter(_v, rawExpr='$root')) # from line 21, col 17.
+        write('/designs/plone/style.css" type="text/css" rel="stylesheet" media="all" />\n    <title>')
         _v = VFFSL(SL,"title",True) # '$title' on line 22, col 12
         if _v is not None: write(_filter(_v, rawExpr='$title')) # from line 22, col 12.
         write('''</title>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/__init__.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/__init__.py	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/__init__.py	2008-04-03 22:25:00 UTC (rev 11749)
@@ -2,8 +2,11 @@
 
 from Desktop import Desktop
 from Document import Document
+from style import style
 
+import SeismoWebPortal.config as config
 
+
 class PloneDesign(object):
 
     def render(self, item):
@@ -15,6 +18,7 @@
         template = self.newDocumentTemplate()
         template.title = item.title
         template.body = self.render(item)
+        template.root = config.root
         return template
 
     def renderDesktop(self, desktop):
@@ -69,3 +73,16 @@
         lastFormat = '<span dir="ltr"><span>%s</span></span>'
         links = ['<a href="%s">%s</a>' % (url, title) for url, title in breadcrumbs[:-1]]
         return breadcrumbSeparator.join(links + [lastFormat % breadcrumbs[-1][1]])
+
+    def serveFile(self, path):
+        from django.http import HttpResponse, Http404
+        if not path: raise Http404
+        name = path.pop(0)
+        if path: raise Http404
+        if name != "style.css":
+            raise Http404
+        template = style()
+        template.root = config.root
+        response = HttpResponse(content = str(template),
+                                mimetype = "text/css")
+        return response

Copied: cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/style.css (from rev 11747, cs/portal/trunk/seismo/SeismoWebPortal/static/css/style.css)
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/style.css	                        (rev 0)
+++ cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/style.css	2008-04-03 22:25:00 UTC (rev 11749)
@@ -0,0 +1,686 @@
+#compiler-settings
+directiveStartToken = @
+#end compiler-settings
+
+img {
+    border-width: 0;
+}
+
+#logo {
+    vertical-align: middle;
+}
+
+#portal-logo {
+    /* override plone */
+    background: url($root/pics/logo.gif) no-repeat;
+}
+
+.illustration {
+    margin-left: auto;
+    margin-right: auto;
+}
+
+.caption {
+    font-style: italic;
+}
+
+
+/* banner */
+
+.banner #logos {
+    float: left;
+}
+
+.banner img {
+    vertical-align: middle;
+}
+
+.banner #sflogo {
+    padding-top: 16px;
+}
+
+.banner h1 {
+    margin-top: 0;
+    margin-bottom: 0;
+    padding-top: 16px;
+}
+
+.banner #sf3dg {
+    color: navy;
+}
+
+.banner #webportal {
+    color: gray;
+}
+
+
+/* messages */
+
+.messages {
+    font-weight: bold;
+    padding: .2em .2em .2em .2em;
+    border: thin solid white;
+    clear: both;
+}
+
+.active {
+    background-color: yellow;
+    border: thin solid black;
+}
+
+
+/* help */
+
+.help {
+    border-style: double;
+    border-color: black;
+    background-color: #ffc;
+}
+
+div.help {
+    padding: 1em 1em 1em 1em;
+}
+
+span.help {
+    margin: 0em .2em 1em 1em;
+    padding: .2em .2em .2em .2em;
+    float: left;
+    width: 20em;
+}
+
+dl.help {
+    margin: 1em 1em 1em 1em;
+    padding: 1em 1em 1em 1em;
+    clear: both;
+}
+
+dl.help dt {
+    font-weight: bold;
+}
+
+.help div.illustration {
+    border: 1px solid black;
+    padding: 1em 1em 1em 1em;
+    background-color: white;
+}
+
+
+/* home, login */
+
+div.splash {
+    font-size: large;
+    text-align: center;
+}
+
+.splash hr {
+    width: 50%;
+    margin-left: auto;
+    margin-right: auto;
+    margin-top: 1em;
+    margin-bottom: 1em;
+}
+
+#powered, #presented, #sponsored {
+    color: gray;
+    font-style: italic;
+}
+
+.codes li {
+    list-style: none;
+    display: inline;
+    padding-left: .5em;
+    padding-right: .5em;
+}
+
+.producers li {
+    list-style: none;
+    display: inline;
+    padding-left: .5em;
+    padding-right: .5em;
+}
+
+.producers a {
+    text-decoration: none;
+}
+
+.nameplate {
+    width: 80%;
+    margin-top: 1em;
+    margin-left: auto;
+    margin-right: auto;
+    color: gray;
+}
+
+.splash a.button {
+    text-transform: capitalize;
+}
+
+.links li {
+    list-style: none;
+    display: inline;
+    padding-left: .5em;
+    padding-right: .5em;
+    border-right: 1px solid black;
+    font-size: small;
+}
+
+.links li.last {
+    border-right: 0;
+}
+
+ul.sponsors {
+    text-align: center;
+    background: white;
+}
+
+.sponsors li {
+    list-style: none;
+    display: inline;
+    margin-left: 1em;
+    margin-right: 1em;
+}
+
+.sponsors img {
+    vertical-align: middle;
+}
+
+
+/* registration */
+
+#usermap {
+    width: 500px;
+}
+
+
+/* login display */
+
+div.login {
+    float: right;
+    background-color: white;
+}
+
+.login li {
+    list-style: none;
+}
+
+.login li {
+    display: inline;
+    padding-left: .5em;
+    padding-right: .5em;
+}
+
+#greeting {
+    font-weight: bold;
+    font-style: italic;
+}
+
+
+/* taskbar */
+
+div.taskbar {
+    clear: both;
+}
+
+.taskbar ul {
+    list-style: none;
+    border-top: 1px solid black;
+    border-bottom: 1px solid black;
+    padding-top: 2px;
+    padding-bottom: 2px;
+    margin-left: 0;
+    background-color: #eee;
+    line-height: 200%;
+}
+
+.taskbar li {
+    display: inline;
+    border-style: outset;
+    font-size: large;
+    margin-left: .1em;
+    margin-right: .1em;
+}
+
+.taskbar a {
+    text-decoration: none;
+    color: black;
+    padding-left: 1em;
+    padding-right: 1em;
+}
+
+.taskbar li.selected {
+    border-style: inset;
+    font-weight: bold;
+    color: black;
+    background-color: orange;
+}
+
+
+/* tabs */
+
+div.tabs {
+    clear: both;
+}
+
+.tabs ul {
+    list-style: none;
+    margin-left: 0;
+    border-bottom: thick solid orange;
+}
+
+.tabs li {
+    display: inline;
+    border-top: 1px solid black;
+    border-right: 1px solid black;
+    font-size: large;
+}
+
+.tabs li.first {
+    border-left: 1px solid black;
+}
+
+.tabs a {
+    text-decoration: none;
+    color: black;
+    padding-left: 1em;
+    padding-right: 1em;
+}
+
+.tabs li.selected {
+    border-bottom: thin solid orange;
+    font-weight: bold;
+    color: black;
+    background-color: orange;
+}
+
+
+/* titlebars */
+
+.titlebar {
+/*
+    border: thin solid blue;
+    background-color: #ccf;
+*/
+    color: white;
+}
+
+h1.titlebar {
+    background-color: navy;
+}
+
+h2.titlebar {
+    background-color: blue;
+}
+
+.titlebar img {
+    vertical-align: middle;
+}
+
+
+/* toolbars */
+
+div.toolbar {
+    padding: .4em 1em .4em 1em;
+    margin: .6em 0em .6em 0em;
+    border-top: 1px solid black;
+    border-bottom: 1px solid black;
+    background-color: #eee;
+}
+
+.toolbar img {
+    vertical-align: middle;
+}
+
+.toolbar form {
+    display: inline;
+}
+
+
+/* infobars */
+
+.infobar {
+    border-bottom: medium double black;
+}
+
+
+/* tables */
+
+table.cool {
+    border: thin solid black;
+}
+
+table.cool caption {
+    font-size: large;
+    background-color: #ccf;
+}
+
+table.cool .even {
+    background-color: #eef;
+}
+
+table.cool tr.title {
+    color: white;
+    background-color: #88f;
+    border-top: 1px solid black;
+}
+
+table.cool th {
+    text-align: left;
+    padding-left: 1em;
+    padding-right: 1em;
+}
+
+table.cool th.colgroup {
+    text-align: center;
+    background-color: #ffd;
+    border-bottom: thin dotted purple;
+}
+
+table.cool td {
+    padding-left: 1em;
+    padding-right: 1em;
+}
+
+ul.output {
+    list-style: none;
+    font-family: monospace;
+    margin: 0 0 0 0;
+    padding: 0 0 0 0;
+}
+
+.output li {
+    display: inline;
+}
+
+.True {
+    text-transform: lowercase;
+}
+
+.False {
+    text-transform: lowercase;
+}
+
+span.True:before {
+    content: url($root/pics/icon-yes.gif) " ";
+}
+
+span.False:before {
+    content: url($root/pics/icon-no.gif) " ";
+}
+
+.float {
+    text-align: right;
+}
+
+.int {
+    text-align: right;
+}
+
+.notApplicable {
+    color: gray;
+    text-align: center;
+}
+
+.inlineInfo {
+    font-size: small;
+}
+
+.new {
+    background-color: yellow;
+}
+
+
+/* detail views */
+
+.properties dt {
+    width: 50%;
+    font-weight: bold;
+    float: left;
+    text-align: right;
+    margin-right: 1ex;
+    clear: both;
+    padding-top: .2em;
+    padding-bottom: .2em;
+}
+
+.properties dt:after {
+    content: ":";
+}
+
+.properties dd {
+    height: 1.3em;
+    padding-top: .2em;
+    padding-bottom: .2em;
+}
+
+.properties dd input {
+    display: inline;
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+/*** experimental floating properties
+div.box {
+    float: left;
+    padding: 1em;
+    margin: 1em;
+    border: 1px solid gray;
+}
+
+div.box h3 {
+    margin: 0;
+    text-align: center;
+}
+***/
+
+/* for experimental confirmation page */
+table.properties td {
+    border: 1px solid gray;
+}
+
+
+
+/* forms */
+
+fieldset {
+    margin: 1em;
+    padding: 1em;
+    clear: both;
+}
+
+form fieldset legend {
+    font-size: larger;
+}
+
+fieldset fieldset {
+    float: left;
+}
+
+fieldset fieldset legend {
+    font-size: normal;
+}
+
+form div {
+    padding-top: .2em;
+    padding-bottom: .2em;
+    clear: both;
+}
+
+form p {
+    clear: both;
+}
+
+.error {
+    font-weight: bold;
+    color: red;
+
+    /* override plone */
+    background-color: white;
+    border: none;
+    padding: 0;
+    margin: 0;
+}
+
+form span.error {
+    margin: 0em .2em 1em 1em;
+    padding: .2em .2em .2em .2em;
+}
+
+.computed {
+    font-weight: bold;
+    background-color: #fcc;
+    border: thin solid red;
+}
+
+label.before {
+    font-weight: bold;
+    float: left;
+    text-align: right;
+    margin-right: 1ex;
+}
+
+.tab30ex label.before {
+    width: 30ex;
+}
+
+.tab30ex fieldset label.before {
+    /* account for the fieldset margin & padding */
+    width: 26ex;
+}
+
+.tab30ex label.after {
+    /*float: left;*/
+}
+
+.tab30ex .checkbox { margin-left: 30ex; }
+.tab30ex .radio { margin-left: 30ex; }
+
+.tab30ex fieldset .checkbox {
+    /* account for the fieldset margin & padding */
+    margin-left: 26ex;
+}
+
+.tab30ex fieldset .radio {
+    /* account for the fieldset margin & padding */
+    margin-left: 26ex;
+}
+
+.tab30ex fieldset fieldset .checkbox { margin-left: 0; }
+.tab30ex fieldset fieldset .radio { margin-left: 0; }
+
+.radio ul {
+    list-style: none;
+}
+
+label.before:after {
+    content: ":";
+}
+
+.tab30ex input.vIntegerField {
+    float: left;
+}
+
+.tab30ex input.vFloatField {
+    float: left;
+}
+
+.tab30ex input.vCheckboxField {
+    float: left;
+}
+
+.tab30ex select.vSelectField {
+    float: left;
+    margin-bottom: 1em;
+}
+
+input.reset {
+    float: right;
+}
+
+input.submit {
+    margin-top: 2em;
+    margin-bottom: 2em;
+}
+
+.tab30ex input.submit {
+    margin-left: 30ex;
+}
+
+
+/* events */
+
+#cmtsolutionIllustration {
+    width: 700px;
+}
+
+#sourceBeachballMw {
+    font-size: larger;
+}
+
+.cmtsolution pre {
+    border: 1px solid black;
+    padding: 1em;
+    background-color: #eee;
+}
+
+
+/* stations */
+
+#stations {
+    width: 576px;
+}
+
+
+
+/* icons */
+
+#portal-globalnav img.icon {
+    width: 32px;
+    height: 32px;
+    vertical-align: bottom;
+}
+
+
+
+/* misc. */
+
+.greek {
+    text-transform: none;
+}
+
+
+
+/* plone extensions */
+
+ at media screen {
+
+        .contenttype-search,
+    .actionMenu .contenttype-search a:hover { 
+        background-image: url(http://www.geodynamics.org/cig/search_icon.gif); 
+        background-repeat: no-repeat; 
+        background-position: 0% 0%;
+    }
+    /* Holly hack to prevent items from shifting to the left in IE*/
+    * html .contenttype-search { 
+        height: 1%;
+    }
+    #portal-sitemap .contenttype-search a:hover,
+    #portlet-navigation-tree .contenttype-search a:hover,
+    #portlet-navigation-tree .contenttype-search a.navTreeCurrentItem {
+        background-image: url(http://www.geodynamics.org/cig/search_icon.gif);
+        background-repeat: no-repeat;
+        background-position: 0% 3px;
+    }
+    #portal-sitemap .contenttype-search,
+    #portlet-navigation-tree .contenttype-search {
+        background-position: 0% 4px;
+    }
+    * html #portal-sitemap .contenttype-search a:hover,
+    * html #portlet-navigation-tree .contenttype-search a:hover,
+    * html #portlet-navigation-tree .contenttype-search a.navTreeCurrentItem {
+        position: relative;
+    }
+    .listing .contenttype-search { 
+        display: block; 
+    }
+
+}

Added: cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/style.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/style.py	                        (rev 0)
+++ cs/portal/trunk/seismo/SeismoWebPortal/designs/plone/style.py	2008-04-03 22:25:00 UTC (rev 11749)
@@ -0,0 +1,822 @@
+#!/usr/bin/env python
+
+
+
+
+##################################################
+## DEPENDENCIES
+import sys
+import os
+import os.path
+from os.path import getmtime, exists
+import time
+import types
+import __builtin__
+from Cheetah.Version import MinCompatibleVersion as RequiredCheetahVersion
+from Cheetah.Version import MinCompatibleVersionTuple as RequiredCheetahVersionTuple
+from Cheetah.Template import Template
+from Cheetah.DummyTransaction import DummyTransaction
+from Cheetah.NameMapper import NotFound, valueForName, valueFromSearchList, valueFromFrameOrSearchList
+from Cheetah.CacheRegion import CacheRegion
+import Cheetah.Filters as Filters
+import Cheetah.ErrorCatchers as ErrorCatchers
+
+##################################################
+## MODULE CONSTANTS
+try:
+    True, False
+except NameError:
+    True, False = (1==1), (1==0)
+VFFSL=valueFromFrameOrSearchList
+VFSL=valueFromSearchList
+VFN=valueForName
+currentTime=time.time
+__CHEETAH_version__ = '2.0rc7'
+__CHEETAH_versionTuple__ = (2, 0, 0, 'candidate', 7)
+__CHEETAH_genTime__ = 1207258017.1388161
+__CHEETAH_genTimestamp__ = 'Thu Apr  3 14:26:57 2008'
+__CHEETAH_src__ = 'style.css'
+__CHEETAH_srcLastModified__ = 'Thu Apr  3 14:11:25 2008'
+__CHEETAH_docstring__ = 'Autogenerated by CHEETAH: The Python-Powered Template Engine'
+
+if __CHEETAH_versionTuple__ < RequiredCheetahVersionTuple:
+    raise AssertionError(
+      'This template was compiled with Cheetah version'
+      ' %s. Templates compiled before version %s must be recompiled.'%(
+         __CHEETAH_version__, RequiredCheetahVersion))
+
+##################################################
+## CLASSES
+
+class style(Template):
+
+    ##################################################
+    ## CHEETAH GENERATED METHODS
+
+
+    def __init__(self, *args, **KWs):
+
+        Template.__init__(self, *args, **KWs)
+        if not self._CHEETAH__instanceInitialized:
+            cheetahKWArgs = {}
+            allowedKWs = 'searchList namespaces filter filtersLib errorCatcher'.split()
+            for k,v in KWs.items():
+                if k in allowedKWs: cheetahKWArgs[k] = v
+            self._initCheetahInstance(**cheetahKWArgs)
+        
+
+    def respond(self, trans=None):
+
+
+
+        ## CHEETAH: main method generated for this template
+        if (not trans and not self._CHEETAH__isBuffering and not callable(self.transaction)):
+            trans = self.transaction # is None unless self.awake() was called
+        if not trans:
+            trans = DummyTransaction()
+            _dummyTrans = True
+        else: _dummyTrans = False
+        write = trans.response().write
+        SL = self._CHEETAH__searchList
+        _filter = self._CHEETAH__currentFilter
+        
+        ########################################
+        ## START - generated method body
+        
+        write('''
+img {
+    border-width: 0;
+}
+
+#logo {
+    vertical-align: middle;
+}
+
+#portal-logo {
+    /* override plone */
+    background: url(''')
+        _v = VFFSL(SL,"root",True) # '$root' on line 15, col 21
+        if _v is not None: write(_filter(_v, rawExpr='$root')) # from line 15, col 21.
+        write('''/pics/logo.gif) no-repeat;
+}
+
+.illustration {
+    margin-left: auto;
+    margin-right: auto;
+}
+
+.caption {
+    font-style: italic;
+}
+
+
+/* banner */
+
+.banner #logos {
+    float: left;
+}
+
+.banner img {
+    vertical-align: middle;
+}
+
+.banner #sflogo {
+    padding-top: 16px;
+}
+
+.banner h1 {
+    margin-top: 0;
+    margin-bottom: 0;
+    padding-top: 16px;
+}
+
+.banner #sf3dg {
+    color: navy;
+}
+
+.banner #webportal {
+    color: gray;
+}
+
+
+/* messages */
+
+.messages {
+    font-weight: bold;
+    padding: .2em .2em .2em .2em;
+    border: thin solid white;
+    clear: both;
+}
+
+.active {
+    background-color: yellow;
+    border: thin solid black;
+}
+
+
+/* help */
+
+.help {
+    border-style: double;
+    border-color: black;
+    background-color: #ffc;
+}
+
+div.help {
+    padding: 1em 1em 1em 1em;
+}
+
+span.help {
+    margin: 0em .2em 1em 1em;
+    padding: .2em .2em .2em .2em;
+    float: left;
+    width: 20em;
+}
+
+dl.help {
+    margin: 1em 1em 1em 1em;
+    padding: 1em 1em 1em 1em;
+    clear: both;
+}
+
+dl.help dt {
+    font-weight: bold;
+}
+
+.help div.illustration {
+    border: 1px solid black;
+    padding: 1em 1em 1em 1em;
+    background-color: white;
+}
+
+
+/* home, login */
+
+div.splash {
+    font-size: large;
+    text-align: center;
+}
+
+.splash hr {
+    width: 50%;
+    margin-left: auto;
+    margin-right: auto;
+    margin-top: 1em;
+    margin-bottom: 1em;
+}
+
+#powered, #presented, #sponsored {
+    color: gray;
+    font-style: italic;
+}
+
+.codes li {
+    list-style: none;
+    display: inline;
+    padding-left: .5em;
+    padding-right: .5em;
+}
+
+.producers li {
+    list-style: none;
+    display: inline;
+    padding-left: .5em;
+    padding-right: .5em;
+}
+
+.producers a {
+    text-decoration: none;
+}
+
+.nameplate {
+    width: 80%;
+    margin-top: 1em;
+    margin-left: auto;
+    margin-right: auto;
+    color: gray;
+}
+
+.splash a.button {
+    text-transform: capitalize;
+}
+
+.links li {
+    list-style: none;
+    display: inline;
+    padding-left: .5em;
+    padding-right: .5em;
+    border-right: 1px solid black;
+    font-size: small;
+}
+
+.links li.last {
+    border-right: 0;
+}
+
+ul.sponsors {
+    text-align: center;
+    background: white;
+}
+
+.sponsors li {
+    list-style: none;
+    display: inline;
+    margin-left: 1em;
+    margin-right: 1em;
+}
+
+.sponsors img {
+    vertical-align: middle;
+}
+
+
+/* registration */
+
+#usermap {
+    width: 500px;
+}
+
+
+/* login display */
+
+div.login {
+    float: right;
+    background-color: white;
+}
+
+.login li {
+    list-style: none;
+}
+
+.login li {
+    display: inline;
+    padding-left: .5em;
+    padding-right: .5em;
+}
+
+#greeting {
+    font-weight: bold;
+    font-style: italic;
+}
+
+
+/* taskbar */
+
+div.taskbar {
+    clear: both;
+}
+
+.taskbar ul {
+    list-style: none;
+    border-top: 1px solid black;
+    border-bottom: 1px solid black;
+    padding-top: 2px;
+    padding-bottom: 2px;
+    margin-left: 0;
+    background-color: #eee;
+    line-height: 200%;
+}
+
+.taskbar li {
+    display: inline;
+    border-style: outset;
+    font-size: large;
+    margin-left: .1em;
+    margin-right: .1em;
+}
+
+.taskbar a {
+    text-decoration: none;
+    color: black;
+    padding-left: 1em;
+    padding-right: 1em;
+}
+
+.taskbar li.selected {
+    border-style: inset;
+    font-weight: bold;
+    color: black;
+    background-color: orange;
+}
+
+
+/* tabs */
+
+div.tabs {
+    clear: both;
+}
+
+.tabs ul {
+    list-style: none;
+    margin-left: 0;
+    border-bottom: thick solid orange;
+}
+
+.tabs li {
+    display: inline;
+    border-top: 1px solid black;
+    border-right: 1px solid black;
+    font-size: large;
+}
+
+.tabs li.first {
+    border-left: 1px solid black;
+}
+
+.tabs a {
+    text-decoration: none;
+    color: black;
+    padding-left: 1em;
+    padding-right: 1em;
+}
+
+.tabs li.selected {
+    border-bottom: thin solid orange;
+    font-weight: bold;
+    color: black;
+    background-color: orange;
+}
+
+
+/* titlebars */
+
+.titlebar {
+/*
+    border: thin solid blue;
+    background-color: #ccf;
+*/
+    color: white;
+}
+
+h1.titlebar {
+    background-color: navy;
+}
+
+h2.titlebar {
+    background-color: blue;
+}
+
+.titlebar img {
+    vertical-align: middle;
+}
+
+
+/* toolbars */
+
+div.toolbar {
+    padding: .4em 1em .4em 1em;
+    margin: .6em 0em .6em 0em;
+    border-top: 1px solid black;
+    border-bottom: 1px solid black;
+    background-color: #eee;
+}
+
+.toolbar img {
+    vertical-align: middle;
+}
+
+.toolbar form {
+    display: inline;
+}
+
+
+/* infobars */
+
+.infobar {
+    border-bottom: medium double black;
+}
+
+
+/* tables */
+
+table.cool {
+    border: thin solid black;
+}
+
+table.cool caption {
+    font-size: large;
+    background-color: #ccf;
+}
+
+table.cool .even {
+    background-color: #eef;
+}
+
+table.cool tr.title {
+    color: white;
+    background-color: #88f;
+    border-top: 1px solid black;
+}
+
+table.cool th {
+    text-align: left;
+    padding-left: 1em;
+    padding-right: 1em;
+}
+
+table.cool th.colgroup {
+    text-align: center;
+    background-color: #ffd;
+    border-bottom: thin dotted purple;
+}
+
+table.cool td {
+    padding-left: 1em;
+    padding-right: 1em;
+}
+
+ul.output {
+    list-style: none;
+    font-family: monospace;
+    margin: 0 0 0 0;
+    padding: 0 0 0 0;
+}
+
+.output li {
+    display: inline;
+}
+
+.True {
+    text-transform: lowercase;
+}
+
+.False {
+    text-transform: lowercase;
+}
+
+span.True:before {
+    content: url(''')
+        _v = VFFSL(SL,"root",True) # '$root' on line 403, col 18
+        if _v is not None: write(_filter(_v, rawExpr='$root')) # from line 403, col 18.
+        write('''/pics/icon-yes.gif) " ";
+}
+
+span.False:before {
+    content: url(''')
+        _v = VFFSL(SL,"root",True) # '$root' on line 407, col 18
+        if _v is not None: write(_filter(_v, rawExpr='$root')) # from line 407, col 18.
+        write('''/pics/icon-no.gif) " ";
+}
+
+.float {
+    text-align: right;
+}
+
+.int {
+    text-align: right;
+}
+
+.notApplicable {
+    color: gray;
+    text-align: center;
+}
+
+.inlineInfo {
+    font-size: small;
+}
+
+.new {
+    background-color: yellow;
+}
+
+
+/* detail views */
+
+.properties dt {
+    width: 50%;
+    font-weight: bold;
+    float: left;
+    text-align: right;
+    margin-right: 1ex;
+    clear: both;
+    padding-top: .2em;
+    padding-bottom: .2em;
+}
+
+.properties dt:after {
+    content: ":";
+}
+
+.properties dd {
+    height: 1.3em;
+    padding-top: .2em;
+    padding-bottom: .2em;
+}
+
+.properties dd input {
+    display: inline;
+    margin-top: 0;
+    margin-bottom: 0;
+}
+
+/*** experimental floating properties
+div.box {
+    float: left;
+    padding: 1em;
+    margin: 1em;
+    border: 1px solid gray;
+}
+
+div.box h3 {
+    margin: 0;
+    text-align: center;
+}
+***/
+
+/* for experimental confirmation page */
+table.properties td {
+    border: 1px solid gray;
+}
+
+
+
+/* forms */
+
+fieldset {
+    margin: 1em;
+    padding: 1em;
+    clear: both;
+}
+
+form fieldset legend {
+    font-size: larger;
+}
+
+fieldset fieldset {
+    float: left;
+}
+
+fieldset fieldset legend {
+    font-size: normal;
+}
+
+form div {
+    padding-top: .2em;
+    padding-bottom: .2em;
+    clear: both;
+}
+
+form p {
+    clear: both;
+}
+
+.error {
+    font-weight: bold;
+    color: red;
+
+    /* override plone */
+    background-color: white;
+    border: none;
+    padding: 0;
+    margin: 0;
+}
+
+form span.error {
+    margin: 0em .2em 1em 1em;
+    padding: .2em .2em .2em .2em;
+}
+
+.computed {
+    font-weight: bold;
+    background-color: #fcc;
+    border: thin solid red;
+}
+
+label.before {
+    font-weight: bold;
+    float: left;
+    text-align: right;
+    margin-right: 1ex;
+}
+
+.tab30ex label.before {
+    width: 30ex;
+}
+
+.tab30ex fieldset label.before {
+    /* account for the fieldset margin & padding */
+    width: 26ex;
+}
+
+.tab30ex label.after {
+    /*float: left;*/
+}
+
+.tab30ex .checkbox { margin-left: 30ex; }
+.tab30ex .radio { margin-left: 30ex; }
+
+.tab30ex fieldset .checkbox {
+    /* account for the fieldset margin & padding */
+    margin-left: 26ex;
+}
+
+.tab30ex fieldset .radio {
+    /* account for the fieldset margin & padding */
+    margin-left: 26ex;
+}
+
+.tab30ex fieldset fieldset .checkbox { margin-left: 0; }
+.tab30ex fieldset fieldset .radio { margin-left: 0; }
+
+.radio ul {
+    list-style: none;
+}
+
+label.before:after {
+    content: ":";
+}
+
+.tab30ex input.vIntegerField {
+    float: left;
+}
+
+.tab30ex input.vFloatField {
+    float: left;
+}
+
+.tab30ex input.vCheckboxField {
+    float: left;
+}
+
+.tab30ex select.vSelectField {
+    float: left;
+    margin-bottom: 1em;
+}
+
+input.reset {
+    float: right;
+}
+
+input.submit {
+    margin-top: 2em;
+    margin-bottom: 2em;
+}
+
+.tab30ex input.submit {
+    margin-left: 30ex;
+}
+
+
+/* events */
+
+#cmtsolutionIllustration {
+    width: 700px;
+}
+
+#sourceBeachballMw {
+    font-size: larger;
+}
+
+.cmtsolution pre {
+    border: 1px solid black;
+    padding: 1em;
+    background-color: #eee;
+}
+
+
+/* stations */
+
+#stations {
+    width: 576px;
+}
+
+
+
+/* icons */
+
+#portal-globalnav img.icon {
+    width: 32px;
+    height: 32px;
+    vertical-align: bottom;
+}
+
+
+
+/* misc. */
+
+.greek {
+    text-transform: none;
+}
+
+
+
+/* plone extensions */
+
+ at media screen {
+
+        .contenttype-search,
+    .actionMenu .contenttype-search a:hover { 
+        background-image: url(http://www.geodynamics.org/cig/search_icon.gif); 
+        background-repeat: no-repeat; 
+        background-position: 0% 0%;
+    }
+    /* Holly hack to prevent items from shifting to the left in IE*/
+    * html .contenttype-search { 
+        height: 1%;
+    }
+    #portal-sitemap .contenttype-search a:hover,
+    #portlet-navigation-tree .contenttype-search a:hover,
+    #portlet-navigation-tree .contenttype-search a.navTreeCurrentItem {
+        background-image: url(http://www.geodynamics.org/cig/search_icon.gif);
+        background-repeat: no-repeat;
+        background-position: 0% 3px;
+    }
+    #portal-sitemap .contenttype-search,
+    #portlet-navigation-tree .contenttype-search {
+        background-position: 0% 4px;
+    }
+    * html #portal-sitemap .contenttype-search a:hover,
+    * html #portlet-navigation-tree .contenttype-search a:hover,
+    * html #portlet-navigation-tree .contenttype-search a.navTreeCurrentItem {
+        position: relative;
+    }
+    .listing .contenttype-search { 
+        display: block; 
+    }
+
+}
+''')
+        
+        ########################################
+        ## END - generated method body
+        
+        return _dummyTrans and trans.response().getvalue() or ""
+        
+    ##################################################
+    ## CHEETAH GENERATED ATTRIBUTES
+
+
+    _CHEETAH__instanceInitialized = False
+
+    _CHEETAH_version = __CHEETAH_version__
+
+    _CHEETAH_versionTuple = __CHEETAH_versionTuple__
+
+    _CHEETAH_genTime = __CHEETAH_genTime__
+
+    _CHEETAH_genTimestamp = __CHEETAH_genTimestamp__
+
+    _CHEETAH_src = __CHEETAH_src__
+
+    _CHEETAH_srcLastModified = __CHEETAH_srcLastModified__
+
+    _mainCheetahMethod_for_style= 'respond'
+
+## END CLASS DEFINITION
+
+if not hasattr(style, '_initCheetahAttributes'):
+    templateAPIClass = getattr(style, '_CHEETAH_templateClass', Template)
+    templateAPIClass._addCheetahPlumbingCodeToClass(style)
+
+
+# CHEETAH was developed by Tavis Rudd and Mike Orr
+# with code, advice and input from many other volunteers.
+# For more information visit http://www.CheetahTemplate.org/
+
+##################################################
+## if run from command line:
+if __name__ == '__main__':
+    from Cheetah.TemplateCmdLineIface import CmdLineIface
+    CmdLineIface(templateObj=style()).run()
+
+

Modified: cs/portal/trunk/seismo/SeismoWebPortal/forms.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/forms.py	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/forms.py	2008-04-03 22:25:00 UTC (rev 11749)
@@ -7,6 +7,7 @@
 from models import UserInfo, Invite, Folder
 from models import EventWorkspace, StationList
 from cmt import CMTSolution
+import config
 
 
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -219,7 +220,7 @@
             return
         raise validators.ValidationError(
 """Someone has already registered using this e-mail address. """
-"""(If you've forgotten your username and/or password, try <a href="/specfem3dglobe/pwreset/">resetting your password</a>.)"""
+"""(If you've forgotten your username and/or password, try <a href="%s/login/reset/">resetting your password</a>.)""" % config.root
     )
 
     

Modified: cs/portal/trunk/seismo/SeismoWebPortal/gui.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/gui.py	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/gui.py	2008-04-03 22:25:00 UTC (rev 11749)
@@ -1,5 +1,7 @@
 
+import config
 
+
 class WindowParent(object):
 
     def __init__(self):
@@ -209,11 +211,11 @@
 
 
 class FileBrowser(TreeBrowser):
-    iconURL = "/specfem3dglobe/icons/folder.gif"
+    iconURL = "%s/icons/folder.gif" % config.root
 
 
 class EventFinder(Navigator):
-    iconURL = "/specfem3dglobe/icons/eventfinder.gif"
+    iconURL = "%s/icons/eventfinder.gif" % config.root
 
 
 class EventViewer(Navigator):

Modified: cs/portal/trunk/seismo/SeismoWebPortal/list_detail.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/list_detail.py	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/list_detail.py	2008-04-03 22:25:00 UTC (rev 11749)
@@ -4,6 +4,7 @@
 from django.core.paginator import ObjectPaginator, InvalidPage
 from django.core.exceptions import ObjectDoesNotExist
 import gui
+import config
 
 def object_list(request, desktop, window, queryset, paginate_by=None, page=None,
         allow_empty=False, template_name=None, template_loader=loader,
@@ -121,6 +122,7 @@
             c[key] = value()
         else:
             c[key] = value
+    c['root'] = config.root
     window.content = gui.StaticContent(t.render(c))
     desktop.activeWindow.selectWindow(window)
     return desktop

Modified: cs/portal/trunk/seismo/SeismoWebPortal/models.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/models.py	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/models.py	2008-04-03 22:25:00 UTC (rev 11749)
@@ -8,7 +8,9 @@
 from managers import CurrentUser
 from middleware import get_current_user
 
+import config
 
+
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # pseudo filesystem
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -33,7 +35,7 @@
                   objectId = False)
 
     def url(self):
-        return "/specfem3dglobe/%d/" % self.id
+        return "%s/%d/" % (config.root, self.id)
 
     def icon(self):
         return self.contents.icon()
@@ -134,7 +136,7 @@
 
     def icon(self):
         ss = self.singleSource
-        return ss and ss.beachball() or '<img class="icon" src="/specfem3dglobe/icons/document.gif">'
+        return ss and ss.beachball() or '<img class="icon" src="%s/icons/document.gif">' % config.root
 
     def delete(self):
         self.source_set.all().delete()
@@ -197,7 +199,7 @@
         return 2.0 * (log10(self.scalarSeismicMoment()) - 16.1)/3.0
 
     def beachball(self):
-        src = "/specfem3dglobe/beachballs/%d.gif" % self.id
+        src = "%s/beachballs/%d.gif" % (config.root, self.id)
         return '<img class="icon" src="%s">' % src
 
     def cmtSolution(self):
@@ -273,7 +275,7 @@
     def __str__(self): return self.fsNode.name
 
     def icon(self):
-        return '<img src="/specfem3dglobe/icons/stationlist.gif">'
+        return '<img src="%s/icons/stationlist.gif">' % config.root
 
     def save(self):
         super(StationList, self).save()
@@ -291,7 +293,7 @@
     @classmethod
     def favorite(self):
         # NYI
-        return StationList.objects.get()
+        return StationList.objects.all()[0]
 
 
 class Station(models.Model):
@@ -376,7 +378,7 @@
     def __str__(self): return self.fsNode.name
 
     def icon(self):
-        return '<img src="/specfem3dglobe/icons/mesh.gif">'
+        return '<img src="%s/icons/mesh.gif">' % config.root
 
     def save(self):
         super(Specfem3DGlobeMesh, self).save()
@@ -407,7 +409,7 @@
     def __str__(self): return self.fsNode.name
 
     def icon(self):
-        return '<img src="/specfem3dglobe/icons/model.gif">'
+        return '<img src="%s/icons/model.gif">' % config.root
 
     def save(self):
         super(Specfem3DGlobeModel, self).save()
@@ -470,7 +472,7 @@
     def __str__(self): return self.fsNode.name
     
     def icon(self):
-        return '<img src="/specfem3dglobe/icons/parameters.gif">'
+        return '<img src="%s/icons/parameters.gif">' % config.root
 
     def nodes(self):
         """Return the number of processors required for this simulation."""
@@ -558,7 +560,7 @@
     def __str__(self): return self.fsNode.name
     
     def icon(self):
-        return '<img src="/specfem3dglobe/icons/modecat.gif">'
+        return '<img src="%s/icons/modecat.gif">' % config.root
 
     def save(self):
         super(MineosModeCatalog, self).save()
@@ -580,7 +582,7 @@
     def __str__(self): return self.fsNode.name
 
     def icon(self):
-        return '<img src="/specfem3dglobe/icons/model.gif">'
+        return '<img src="%s/icons/model.gif">' % config.root
 
     def save(self):
         super(MineosModel, self).save()
@@ -621,7 +623,7 @@
     def __str__(self): return self.fsNode.name
     
     def icon(self):
-        return '<img src="/specfem3dglobe/icons/parameters.gif">'
+        return '<img src="%s/icons/parameters.gif">' % config.root
 
     def save(self):
         super(MineosParameters, self).save()

Modified: cs/portal/trunk/seismo/SeismoWebPortal/site/urls.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/site/urls.py	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/site/urls.py	2008-04-03 22:25:00 UTC (rev 11749)
@@ -9,6 +9,6 @@
 
     #(r'^accounts/login/$', 'django.contrib.auth.views.login'),
 
-    (r'^specfem3dglobe/', include('SeismoWebPortal.urls')),
+    (r'^portals/seismo/', include('SeismoWebPortal.urls')),
 
 )

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/404.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/404.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/404.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -1,4 +1,2 @@
 
-<p><a href="/specfem3dglobe/"><img id=logo src="/specfem3dglobe/pics/specfem3dg_logo.jpg" width=99 height=94>Home</a>
-
 <h1>Not Found</h1>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/500.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/500.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/500.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -1,4 +1,2 @@
 
-<p><a href="/specfem3dglobe/"><img id=logo src="/specfem3dglobe/pics/specfem3dg_logo.jpg" width=99 height=94>Home</a>
-
 <h1>Internal Server Error</h1>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/desktop.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/desktop.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/desktop.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -5,11 +5,11 @@
 
     <tr>
 
-    <td align=center><table><tr><td align=center><a href="/specfem3dglobe/home/"><img src="/specfem3dglobe/icons/folder.gif"></a></td></tr><tr><td align=center><a href="/specfem3dglobe/home/">Home</a></td></tr></table></td>
+    <td align=center><table><tr><td align=center><a href="{{root}}/home/"><img src="{{root}}/icons/folder.gif"></a></td></tr><tr><td align=center><a href="{{root}}/home/">Home</a></td></tr></table></td>
 
-    <td align=center><table><tr><td align=center><a href="/specfem3dglobe/trash/"><img src="/specfem3dglobe/icons/folder.gif"></a></td></tr><tr><td align=center><a href="/specfem3dglobe/trash/">Trash</a></td></tr></table></td>
+    <td align=center><table><tr><td align=center><a href="{{root}}/trash/"><img src="{{root}}/icons/folder.gif"></a></td></tr><tr><td align=center><a href="{{root}}/trash/">Trash</a></td></tr></table></td>
 
-    <td align=center><table><tr><td align=center><a href="/specfem3dglobe/events/"><img src="/specfem3dglobe/icons/eventfinder.gif"></a></td></tr><tr><td align=center><a href="/specfem3dglobe/events/">Event Finder</a></td></tr></table></td>
+    <td align=center><table><tr><td align=center><a href="{{root}}/events/"><img src="{{root}}/icons/eventfinder.gif"></a></td></tr><tr><td align=center><a href="{{root}}/events/">Event Finder</a></td></tr></table></td>
 
     </tr>
 

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_detail.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -2,7 +2,7 @@
 <h2>{{ object }}</h2>
 
 <div class=toolbar>
-    <a href="gearth.kml"><img src="/specfem3dglobe/pics/kml.icon.gif" title="View in Google Earth" alt="View in Google Earth"></a>
+    <a href="gearth.kml"><img src="{{root}}/pics/kml.icon.gif" title="View in Google Earth" alt="View in Google Earth"></a>
     [<a href="CMTSOLUTION.txt">download as text</a>]
 </div>
 

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_search_results.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_search_results.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_search_results.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -22,7 +22,7 @@
         <tr>
             <td>
                 <!-- an inline events/add form, already filled-out -->
-	        <form method="post" action="/specfem3dglobe/config/events/new/">
+	        <form method="post" action="{{root}}/config/events/new/">
 		    <input type="hidden" name="name"             value="{{ event.eventName }}"/>
 		    <input type="hidden" name="dataSource"       value="{{ event.dataSource }}"/>
 		    <input type="hidden" name="when_date"        value="{{ event.year }}-{{ event.month }}-{{ event.day }}"/>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_upload.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_upload.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/event_upload.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -1,7 +1,7 @@
 
 <h2>upload event</h2>
 
-<form action="/specfem3dglobe/config/events/upload/" method="post" enctype="multipart/form-data">
+<form action="{{action}}" method="post" enctype="multipart/form-data">
 
     {% if form.has_errors %}
     <p><span class=error>Please correct the following error{{ form.error_dict|pluralize }}.</span>
@@ -35,7 +35,7 @@
 known as the Harvard CMT catalog).  It looks like this:</p>
 
 <div class=illustration id=cmtsolutionIllustration>
-    <img src="/specfem3dglobe/pics/cmtsolution.gif" width=700 height=310>
+    <img src="{{root}}/pics/cmtsolution.gif" width=700 height=310>
     <p class=caption><code>CMTSOLUTION</code> file obtained from the
     Harvard CMT catalog.  The top line is the initial estimate of the
     source, which is used as a starting point for the CMT

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineosmodel_upload.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineosmodel_upload.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/mineosmodel_upload.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -1,7 +1,7 @@
 
 <h2>upload mineos model</h2>
 
-<form action="/specfem3dglobe/config/mineos/models/upload/" method="POST" enctype="multipart/form-data">
+<form action="{{action}}" method="POST" enctype="multipart/form-data">
 
     {% if form.has_errors %}
     <p><span class=error>Please correct the following error{{ form.error_dict|pluralize }}.</span>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/password_change_form.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/password_change_form.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/password_change_form.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -5,7 +5,7 @@
 <p><span class=error>Please correct the following error{{ form.error_dict|pluralize }}.</span>
 {% endif %}
 
-<form action="/specfem3dglobe/profile/password/" method="post">
+<form action="{{root}}/profile/password/" method="post">
     <div class=tab30ex>
 
     <div>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/readme.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/readme.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/readme.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -23,9 +23,9 @@
 <code>seismograms.tar.gz</code> in the "output" column of the
 simulation's information page. Click this link to download the output of
 the simulation: seismograms in ASCII and <a href="http://www.llnl.gov/sac/">SAC</a> format.
-Then, <a href="/specfem3dglobe/samples/UTILS.tar.gz">download the
+Then, <a href="{{root}}/samples/UTILS.tar.gz">download the
 post-processing utilities</a> to process the data.  See
-<a href="/specfem3dglobe/doc/manual_SPECFEM3D_GLOBE.pdf">the manual</a>
+<a href="{{root}}/doc/manual_SPECFEM3D_GLOBE.pdf">the manual</a>
 for further details.
 
 <p>As you become familiar with the code, feel free to explore this
@@ -33,7 +33,7 @@
 
 <h3>tips</h3>
 
-<p><img src="/specfem3dglobe/pics/kml.icon.gif"> If you have
+<p><img src="{{root}}/pics/kml.icon.gif"> If you have
 <a href="http://earth.google.com/">Google Earth</a> installed on your
 computer, you can use it to map events and stations.  Just look for
 the KML icon and click it!</p>
@@ -45,5 +45,5 @@
 
 <h3>additional documentation</h3>
 
-<p><a href="/specfem3dglobe/doc/manual_SPECFEM3D_GLOBE.pdf">
-   <img src="/specfem3dglobe/pics/adobe-pdf.icon.gif">SPECFEM 3D GLOBE User Manual</a>
+<p><a href="{{root}}/doc/manual_SPECFEM3D_GLOBE.pdf">
+   <img src="{{root}}/pics/adobe-pdf.icon.gif">SPECFEM 3D GLOBE User Manual</a>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/registration_form.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/registration_form.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/registration_form.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -3,14 +3,14 @@
 
 <p>To create a new account, simply fill-out the form below.
 
-<p>If you've registered before, but have simply forgotten your username and/or password, try <a href="/specfem3dglobe/pwreset/">resetting your password</a>.
+<p>If you've registered before, but have simply forgotten your username and/or password, try <a href="{{root}}/login/reset/">resetting your password</a>.
    If you need help, <a href="mailto:portal at geodynamics.org">contact us</a>.
 
 {% if form.has_errors %}
 <p><span class=error>Please correct the following error{{ form.error_dict|pluralize }}.</span>
 {% endif %}
 
-<form method="post" action="/specfem3dglobe/registration/">
+<form method="post" action="{{root}}/registration/">
     <div class=tab30ex>
 
     <fieldset><legend>username and password</legend>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dgloberequest_form.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dgloberequest_form.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/specfem3dgloberequest_form.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -6,5 +6,5 @@
     </div>
 
     {% if help_visible %}
-    <dl class=help><dt>zero half duration</dt><dd>For point-source simulations, we recommend setting the source half-duration parameter <code>half duration</code> equal to zero, which corresponds to simulating a step source-time function, i.e., a moment-rate function that is a delta function. If <code>half duration</code> is not set to zero, the code will use a Gaussian (i.e., a signal with a shape similar to a 'smoothed triangle', as explained in Komatitsch and Tromp [2002a]) source-time function with half-width <code>half duration</code>. We prefer to run the solver with <code>half duration</code> set to zero and convolve the resulting synthetic seismograms in post-processing after the run, because this way it is easy to use a variety of source-time functions. Komatitsch and Tromp [2002a] determined that the noise generated in the simulation by using a step source time function may be safely filtered out afterward based upon a convolution with the desired source time function and/or low-pass filtering. Use the script <code>process_syn.pl</code> for this purpose by specifying the <code>-h</code> option (the <code>process_syn.pl</code> script can be found in the <a href="/specfem3dglobe/samples/UTILS.tar.gz">utilities package</a>). Alternatively, use signal-processing software packages such as <a href="http://www.llnl.gov/sac/">SAC</a>.<p>For finite fault simulations, it is usually not advisable to use a zero half duration and convolve afterwards, since the half duration is generally fixed by the finite fault model.</dd></dl>
+    <dl class=help><dt>zero half duration</dt><dd>For point-source simulations, we recommend setting the source half-duration parameter <code>half duration</code> equal to zero, which corresponds to simulating a step source-time function, i.e., a moment-rate function that is a delta function. If <code>half duration</code> is not set to zero, the code will use a Gaussian (i.e., a signal with a shape similar to a 'smoothed triangle', as explained in Komatitsch and Tromp [2002a]) source-time function with half-width <code>half duration</code>. We prefer to run the solver with <code>half duration</code> set to zero and convolve the resulting synthetic seismograms in post-processing after the run, because this way it is easy to use a variety of source-time functions. Komatitsch and Tromp [2002a] determined that the noise generated in the simulation by using a step source time function may be safely filtered out afterward based upon a convolution with the desired source time function and/or low-pass filtering. Use the script <code>process_syn.pl</code> for this purpose by specifying the <code>-h</code> option (the <code>process_syn.pl</code> script can be found in the <a href="{{root}}/samples/UTILS.tar.gz">utilities package</a>). Alternatively, use signal-processing software packages such as <a href="http://www.llnl.gov/sac/">SAC</a>.<p>For finite fault simulations, it is usually not advisable to use a zero half duration and convolve afterwards, since the half duration is generally fixed by the finite fault model.</dd></dl>
     {% endif %}

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/splash.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/splash.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/splash.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -17,8 +17,8 @@
 
     <p id=powered>Powered by:</p>
     <ul class=codes>
-        <li><img src="/specfem3dglobe/pics/specfem3dg_logo.jpg" width=99 height=94>Specfem 3D Globe v4.0
-        <li><img src="/specfem3dglobe/pics/mineos_logo.gif" width=75 height=75>Mineos v1.0
+        <li><img src="{{root}}/pics/specfem3dg_logo.jpg" width=99 height=94>Specfem 3D Globe v4.0
+        <li><img src="{{root}}/pics/mineos_logo.gif" width=75 height=75>Mineos v1.0
     </ul>
 
     <hr>
@@ -34,11 +34,11 @@
 
     <p id=sponsored>Sponsored by:</p>
     <ul class=sponsors>
-        <li><a href="http://www.geodynamics.org/"><img src="/specfem3dglobe/pics/cig-logo_small-initials.gif"></a>
-        <li><a href="http://www.caltech.edu/"><img src="/specfem3dglobe/pics/citlogo.gif"></a>
-        <li><a href="http://www.seismolab.caltech.edu/"><img src="/specfem3dglobe/pics/seismolab_logo.gif"></a>
-        <li><a href="http://www.nsf.gov/"><img src="/specfem3dglobe/pics/nsf_logo.jpg"></a>
-        <li><a href="http://www.teragrid.org/"><img src="/specfem3dglobe/pics/tg_logo.gif"></a>
+        <li><a href="http://www.geodynamics.org/"><img src="{{root}}/pics/cig-logo_small-initials.gif"></a>
+        <li><a href="http://www.caltech.edu/"><img src="{{root}}/pics/citlogo.gif"></a>
+        <li><a href="http://www.seismolab.caltech.edu/"><img src="{{root}}/pics/seismolab_logo.gif"></a>
+        <li><a href="http://www.nsf.gov/"><img src="{{root}}/pics/nsf_logo.jpg"></a>
+        <li><a href="http://www.teragrid.org/"><img src="{{root}}/pics/tg_logo.gif"></a>
     </ul>
 
 </div> <!-- splash -->

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_detail.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_detail.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_detail.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -2,7 +2,7 @@
 <h2>{{ object }}</h2>
 
 <div class=toolbar>
-    <a href="gearth.kml"><img src="/specfem3dglobe/pics/kml.icon.gif" title="View in Google Earth" alt="View in Google Earth"></a>
+    <a href="gearth.kml"><img src="{{root}}/pics/kml.icon.gif" title="View in Google Earth" alt="View in Google Earth"></a>
     [<a href="stations.txt">download as text</a>]
 </div>
 

Deleted: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_form.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_form.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_form.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -1,24 +0,0 @@
-
-<h2>edit station list</h2>
-
-{% if form.has_errors %}
-<p><span class=error>Please correct the following error{{ form.error_dict|pluralize }}.</span>
-{% endif %}
-
-<form method="post" action="/specfem3dglobe/config/stations/{{ object.id }}/edit/">
-
-    <div class=tab30ex>
-
-    <div>
-        <label for="id_name" class=before>name</label>
-        {{ form.name }}
-        {% if form.name.errors %}<span class=error>{{ form.name.errors|join:", " }}</span>{% endif %}
-    </div>
-
-    <div>
-        <input class=submit type="submit" value="Save">
-    </div>
-
-    </div> <!-- tab30ex -->
-
-</form>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_upload.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_upload.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/stationlist_upload.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -1,7 +1,7 @@
 
 <h2>upload station list</h2>
 
-<form action="/specfem3dglobe/config/stations/upload/" method="POST" enctype="multipart/form-data">
+<form action="{{action}}" method="POST" enctype="multipart/form-data">
 
     {% if form.has_errors %}
     <p><span class=error>Please correct the following error{{ form.error_dict|pluralize }}.</span>
@@ -37,7 +37,7 @@
 <code>STATIONS</code> file, which looks like this:</p>
 
 <div class=illustration id=stations>
-    <img src="/specfem3dglobe/pics/stations.gif" width=576 height=322>
+    <img src="{{root}}/pics/stations.gif" width=576 height=322>
     <p class=caption>Sample <code>STATIONS</code> file.</p>
 </div>
 
@@ -61,7 +61,7 @@
 <code>STATIONS</code> file.  Instead, station elevation is computed
 based upon topography data.</p>
 
-<p><a href="/specfem3dglobe/samples/STATIONS.txt">Click here</a> to
+<p><a href="{{root}}/samples/STATIONS.txt">Click here</a> to
 download a sample <code>STATIONS</code> file.</p>
 
 </div>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/user_map.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/user_map.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/user_map.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -1,5 +1,5 @@
 
 <div class=illustration id=usermap>
-    <img src="/specfem3dglobe/pics/specfem_users_map.gif" width=461 height=230>
+    <img src="{{root}}/pics/specfem_users_map.gif" width=461 height=230>
     <p class=caption>SPECFEM User Map</p>
 </div>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/userinfo_form.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/userinfo_form.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/SeismoWebPortal/userinfo_form.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -5,7 +5,7 @@
 <p><span class=error>Please correct the following error{{ form.error_dict|pluralize }}.</span>
 {% endif %}
 
-<form method="post" action="/specfem3dglobe/profile/">
+<form method="post" action="{{root}}/profile/">
 
     <div class=tab30ex>
 

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/login.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/login.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/login.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -16,7 +16,7 @@
 </dl>
 {% endif %}
 
-<form method="post" action="/specfem3dglobe/login/">
+<form method="post" action="{{root}}/login/">
 
     <div class=tab30ex>
 
@@ -35,15 +35,15 @@
     {% if next %}
     <input type="hidden" name="next" value="{{ next }}" />
     {% else %}
-    <input type="hidden" name="next" value="/specfem3dglobe/" />
+    <input type="hidden" name="next" value="{{root}}/" />
     {% endif %}
 
     </div> <!-- tab30ex -->
 
 </form>
 
-<p>Are you a new user? If so, please <a href="/specfem3dglobe/registration/">register</a>.
+<p>Are you a new user? If so, please <a href="{{root}}/registration/">register</a>.
 
-<p>If you've forgotten your username and/or password, try <a href="/specfem3dglobe/login/reset/">resetting your password</a>.
+<p>If you've forgotten your username and/or password, try <a href="{{root}}/login/reset/">resetting your password</a>.
 
 <p>If you need help, <a href="mailto:portal at geodynamics.org">contact us</a>.

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -3,7 +3,7 @@
 
 <p>Forgotten your password? Enter your e-mail address below, and we'll reset your password and e-mail the new one to you.</p>
 
-<form action="/specfem3dglobe/login/reset/" method="post">
+<form action="{{root}}/login/reset/" method="post">
 
     {% if form.has_errors %}
     <p><span class=error>Please correct the following error{{ form.error_dict|pluralize }}.</span>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset_done.html
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset_done.html	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset_done.html	2008-04-03 22:25:00 UTC (rev 11749)
@@ -3,4 +3,4 @@
 
 <p><b>Success!</b> We've e-mailed a new password to the e-mail address you submitted. You should be receiving it shortly.</p>
 
-<p><a href="/specfem3dglobe/login/">Login</a></p>
+<p><a href="{{root}}/login/">Login</a></p>

Modified: cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset_email.txt
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset_email.txt	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/templates/registration/pwreset_email.txt	2008-04-03 22:25:00 UTC (rev 11749)
@@ -1,13 +1,13 @@
 You're receiving this e-mail because you requested a password reset
-for your user account at the SPECFEM 3D GLOBE Web Portal:
+for your user account at the CIG Seismo Web Portal:
 
-http://crust.geodynamics.org/specfem3dglobe/
+http://crust.geodynamics.org{{root}}/
 
 Your new password is: {{ new_password }}
 
 Feel free to change this password by going to this page:
 
-https://crust.geodynamics.org/specfem3dglobe/registration/password/
+https://crust.geodynamics.org{{root}}/profile/password/
 
 Your username, in case you've forgotten: {{ user.username }}
 

Modified: cs/portal/trunk/seismo/SeismoWebPortal/views.py
===================================================================
--- cs/portal/trunk/seismo/SeismoWebPortal/views.py	2008-04-03 18:48:51 UTC (rev 11748)
+++ cs/portal/trunk/seismo/SeismoWebPortal/views.py	2008-04-03 22:25:00 UTC (rev 11749)
@@ -18,6 +18,7 @@
 from models import FSNode, Folder
 from models import EventWorkspace
 from cmt import CMTSolution
+import config
 import gui
 
 import os, os.path
@@ -56,7 +57,14 @@
 def root(request, pathname):
     from django.views.static import serve as staticServe
 
-    desktop = gui.Desktop("/specfem3dglobe", "CIG Seismology Web Portal")
+    if config.root is None:
+        if pathname:
+            x = request.path.find("/" + pathname)
+            config.root = request.path[0:x]
+        else:
+            config.root = request.path[0:-1]
+
+    desktop = gui.Desktop(config.root, "CIG Seismology Web Portal")
     if not request.user.is_anonymous():
         desktop.user = request.user
 
@@ -81,7 +89,7 @@
         "jobs": jobs, # accessed by daemon
         "output": output, # accessed by daemon
         "beachballs": beachballs,
-        "css": static,
+        "designs": designs,
         "doc": static,
         "pics": static,
         "icons": static,
@@ -96,7 +104,7 @@
     if request.user.is_anonymous():
         from opal.contrib.auth import REDIRECT_FIELD_NAME
         from urllib import quote
-        return HttpResponseRedirect('/specfem3dglobe/login?%s=%s' %
+        return HttpResponseRedirect(config.root + '/login?%s=%s' %
                                     (REDIRECT_FIELD_NAME, quote(request.get_full_path())))
 
     openFileBrowser(desktop)
@@ -105,7 +113,7 @@
         "home": homeFolder,
         "shared": sharedFolder,
         "trash": trashFolder,
-        "config": config,
+        "config": configFactory,
         "events": event_search,
         "profile": profile,
         "logout": logout,
@@ -123,8 +131,8 @@
     appWindow, _, _ = openPublicApps(desktop)
     desktop.selectWindow(appWindow)
     
-    splash = gui.ChildWindow("/specfem3dglobe/", "About")
-    html = loader.render_to_string('SeismoWebPortal/splash.html')
+    splash = gui.ChildWindow(config.root + "/", "About")
+    html = loader.render_to_string('SeismoWebPortal/splash.html', { 'root': config.root })
     splash.content = gui.StaticContent(html)
     
     appWindow.insertWindow(splash)
@@ -134,13 +142,13 @@
 
 
 def openPublicApps(desktop):
-    about = gui.AppWindow("/specfem3dglobe/", "About")
+    about = gui.AppWindow(config.root + "/", "About")
     desktop.insertWindow(about)
 
-    login = gui.AppWindow("/specfem3dglobe/login/", "Login")
+    login = gui.AppWindow(config.root + "/login/", "Login")
     desktop.insertWindow(login)
 
-    register = gui.AppWindow("/specfem3dglobe/registration/", "Register")
+    register = gui.AppWindow(config.root + "/registration/", "Register")
     desktop.insertWindow(register)
 
     return about, login, register
@@ -151,9 +159,9 @@
         gui.Directory("home", "Home", []),
         gui.Directory("shared", "Shared", []),
         gui.Directory("trash", "Trash", []),
-        gui.Search("events", "Event Finder", url = "/specfem3dglobe/events/"),
+        gui.Search("events", "Event Finder", url = config.root + "/events/"),
         ])
-    fileBrowser = gui.FileBrowser("/specfem3dglobe/", "File Browser", navtree)
+    fileBrowser = gui.FileBrowser(config.root + "/", "File Browser", navtree)
     desktop.insertWindow(fileBrowser)
     desktop.selectWindow(fileBrowser)
 
@@ -171,7 +179,17 @@
     return response
 
 
+def designs(request, path, desktop):
+    if not path: raise Http404
+    name = path.pop(0)
+    if name != "plone":
+        raise Http404
 
+    import designs.plone
+    design = designs.plone.PloneDesign()
+    return design.serveFile(path)
+
+
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # Specfem 3D Globe
 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -181,18 +199,18 @@
 
 
 def desktopFolder(request, desktop):
-    child = gui.ChildWindow("/specfem3dglobe/", "View")
-    child.content = gui.StaticContent(loader.render_to_string('SeismoWebPortal/desktop.html'))
+    child = gui.ChildWindow(config.root + "/", "View")
+    child.content = gui.StaticContent(loader.render_to_string('SeismoWebPortal/desktop.html', {'root': config.root}))
     desktop.activeWindow.selectWindow(child)
     return desktop
 
 
 def trashFolder(request, path, desktop):
-    return folderView(Folder.trashFolder(request.user), "trash", "/specfem3dglobe/trash/", request, path, desktop)
+    return folderView(Folder.trashFolder(request.user), "trash", config.root + "/trash/", request, path, desktop)
 
 
 def sharedFolder(request, path, desktop):
-    return folderView(Folder.sharedFolder(), "shared", "/specfem3dglobe/shared/", request, path, desktop)
+    return folderView(Folder.sharedFolder(), "shared", config.root + "/shared/", request, path, desktop)
 
 
 def folderView(folder, slug, url, request, path, desktop):
@@ -232,13 +250,13 @@
 
 def readme(request, path, desktop):
     if path: raise Http404
-    child = gui.ChildWindow("/specfem3dglobe/readme/", "View")
-    child.content = gui.StaticContent(loader.render_to_string('SeismoWebPortal/readme.html'))
+    child = gui.ChildWindow(config.root + "/readme/", "View")
+    child.content = gui.StaticContent(loader.render_to_string('SeismoWebPortal/readme.html', { 'root': config.root }))
     desktop.activeWindow.selectWindow(child)
     return desktop
 
 
-def config(request, path, desktop):
+def configFactory(request, path, desktop):
 
     if not path: raise Http404
     
@@ -248,7 +266,7 @@
     if name == "stations":
         return uploadOnly(request, path, desktop,
                           UploadStationListManipulator(),
-                          "/specfem3dglobe/config/stations/upload/",
+                          config.root + "/config/stations/upload/",
                           "SeismoWebPortal/stationlist_upload.html")
 
     index = Index({
@@ -271,7 +289,7 @@
     name = path.pop(0)
     if name == "new":
         if path: raise Http404
-        url = "/specfem3dglobe/config/%s/new/" % url
+        url = config.root + "/config/%s/new/" % url
         window = gui.ChildWindow(url, "New")
         window.buttons.append(helpButton(request))
         return create(request, desktop, window, ModelClass)
@@ -290,7 +308,7 @@
 
 def configObject(name, request, path, desktop):
     objId = intOr404(name)
-    url = "/specfem3dglobe/%d/" % objId
+    url = config.root + "/%d/" % objId
     
     fsNode = get_object_or_404(FSNode, id=objId)
     
@@ -355,7 +373,7 @@
                              )
     if name == "delete":
         obj = get_object_or_404(ModelClass, id=objId)
-        return moveObjectToTrash(obj, request, "/specfem3dglobe/home/")
+        return moveObjectToTrash(obj, request, config.root + "/home/")
     raise Http404
 
 
@@ -368,25 +386,25 @@
     
     home = Folder.homeFolder(request.user)
     
-    child = gui.ChildWindow("/specfem3dglobe/home/", "View")
-    config = "/specfem3dglobe/config/"
+    child = gui.ChildWindow(config.root + "/home/", "View")
+    url = config.root + "/config/"
     child.menuBar = [
         gui.Menu("newMenu", "new", "New",
-                 [gui.MenuItem(config + "events/new/", "Event"),
-                  gui.MenuItem(config + "specfem3dglobe/models/new/", "Specfem 3D Globe Model"),
-                  gui.MenuItem(config + "specfem3dglobe/meshes/new/1/", "Specfem 3D Globe 1-chunk Regional Mesh"),
-                  gui.MenuItem(config + "specfem3dglobe/meshes/new/2/", "Specfem 3D Globe 2-chunk Regional Mesh"),
-                  gui.MenuItem(config + "specfem3dglobe/meshes/new/3/", "Specfem 3D Globe 3-chunk Regional Mesh"),
-                  gui.MenuItem(config + "specfem3dglobe/meshes/new/6/", "Specfem 3D Globe Global Mesh"),
-                  gui.MenuItem(config + "specfem3dglobe/parameters/new/", "Specfem 3D Globe Parameter Set"),
-                  gui.MenuItem(config + "mineos/modes/new/", "Mineos Mode Catalog"),
-                  gui.MenuItem(config + "mineos/parameters/new/", "Mineos Parameter Set"),
+                 [gui.MenuItem(url + "events/new/", "Event"),
+                  gui.MenuItem(url + "specfem3dglobe/models/new/", "Specfem 3D Globe Model"),
+                  gui.MenuItem(url + "specfem3dglobe/meshes/new/1/", "Specfem 3D Globe 1-chunk Regional Mesh"),
+                  gui.MenuItem(url + "specfem3dglobe/meshes/new/2/", "Specfem 3D Globe 2-chunk Regional Mesh"),
+                  gui.MenuItem(url + "specfem3dglobe/meshes/new/3/", "Specfem 3D Globe 3-chunk Regional Mesh"),
+                  gui.MenuItem(url + "specfem3dglobe/meshes/new/6/", "Specfem 3D Globe Global Mesh"),
+                  gui.MenuItem(url + "specfem3dglobe/parameters/new/", "Specfem 3D Globe Parameter Set"),
+                  gui.MenuItem(url + "mineos/modes/new/", "Mineos Mode Catalog"),
+                  gui.MenuItem(url + "mineos/parameters/new/", "Mineos Parameter Set"),
                   ]
                  ),
         gui.Menu("uploadMenu", "upload", "Upload",
-                 [gui.MenuItem(config + "events/upload/", "Event"),
-                  gui.MenuItem(config + "stations/upload/", "Station List"),
-                  gui.MenuItem(config + "mineos/models/upload/", "Mineos Model"),
+                 [gui.MenuItem(url + "events/upload/", "Event"),
+                  gui.MenuItem(url + "stations/upload/", "Station List"),
+                  gui.MenuItem(url + "mineos/models/upload/", "Mineos Model"),
                  ]
                  )
         ]
@@ -400,13 +418,13 @@
 def config_specfem3dglobe_parameters(request, path, desktop):
     name = path.pop(0)
     if name == "new":
-        window = gui.ChildWindow("/specfem3dglobe/config/specfem3dglobe/parameters/new/", "New")
+        window = gui.ChildWindow(config.root + "/config/specfem3dglobe/parameters/new/", "New")
         window.buttons.append(helpButton(request))
         return create_object(request,
                              desktop,
                              window,
                              Specfem3DGlobeParameters,
-                             post_save_redirect = '/specfem3dglobe/home/',
+                             post_save_redirect = config.root + '/home/',
                              follow = { 'fsNode': False },
                              )
     raise Http404
@@ -470,7 +488,7 @@
                              )
     if name == "delete":
         obj = get_object_or_404(Specfem3DGlobeParameters, id=objId)
-        return moveObjectToTrash(obj, request, "/specfem3dglobe/home/")
+        return moveObjectToTrash(obj, request, config.root + "/home/")
     
     index = Index({
         "par_file.txt": par_file,
@@ -522,8 +540,8 @@
     _, appWindow, _ = openPublicApps(desktop)
     desktop.selectWindow(appWindow)
     
-    login = gui.ChildWindow("/specfem3dglobe/login/", "Login")
-    reset = gui.ChildWindow("/specfem3dglobe/login/reset/", "Reset Password")
+    login = gui.ChildWindow(config.root + "/login/", "Login")
+    reset = gui.ChildWindow(config.root + "/login/reset/", "Reset Password")
     appWindow.insertWindow(login)
     appWindow.insertWindow(reset)
 
@@ -556,6 +574,7 @@
         'form': forms.FormWrapper(manipulator, request.POST, errors),
         REDIRECT_FIELD_NAME: redirect_to,
         'site_name': Site.objects.get_current().name,
+        'root': config.root,
     })
 
     login.content = gui.StaticContent(html)
@@ -568,7 +587,7 @@
     if path: raise Http404
     
     logoutUser(request)
-    return HttpResponseRedirect('/specfem3dglobe/login/')
+    return HttpResponseRedirect(config.root + '/login/')
 
 def pwreset(request, path, reset, desktop):
     from django.views.generic.simple import direct_to_template
@@ -578,8 +597,8 @@
         name = path.pop(0)
         if path: raise Http404
         if name == "done":
-            resetDone = gui.ChildWindow("/specfem3dglobe/login/reset/done/", "Password Reset")
-            html = loader.render_to_string("registration/pwreset_done.html")
+            resetDone = gui.ChildWindow(config.root + "/login/reset/done/", "Password Reset")
+            html = loader.render_to_string("registration/pwreset_done.html", { 'root': config.root })
             resetDone.content = gui.StaticContent(html)
             desktop.activeWindow.insertWindow(resetDone)
             desktop.activeWindow.selectWindow(resetDone)
@@ -756,7 +775,7 @@
                "",
                "To download the output, visit the following web page:",
                "",
-               "https://crust.geodynamics.org/specfem3dglobe/simulations/%d/" % sim.id,
+               "https://crust.geodynamics.org%s/simulations/%d/" % (config.root, sim.id),
                "",
                "Sincerely,",
                "The SPECFEM 3D GLOBE Web Portal",
@@ -813,8 +832,8 @@
     _, _, appWindow = openPublicApps(desktop)
     desktop.selectWindow(appWindow)
 
-    register = gui.ChildWindow("/specfem3dglobe/registration/", "Register")
-    map = gui.ChildWindow("/specfem3dglobe/registration/map/", "Map")
+    register = gui.ChildWindow(config.root + "/registration/", "Register")
+    map = gui.ChildWindow(config.root + "/registration/map/", "Map")
     appWindow.insertWindow(register)
     appWindow.insertWindow(map)
 
@@ -822,7 +841,7 @@
         name = path.pop(0)
         if path: raise Http404
         if name == "map":
-            html = loader.render_to_string('SeismoWebPortal/user_map.html')
+            html = loader.render_to_string('SeismoWebPortal/user_map.html', { 'root': config.root })
             map.content = gui.StaticContent(html)
             desktop.activeWindow.selectWindow(map)
             return desktop
@@ -842,7 +861,7 @@
                 help_login_hook(request, user)
                 notify_managers_of_new_user(request, user)
                 user.message_set.create(message="Welcome to the SPECFEM 3D GLOBE web portal!")
-                return HttpResponseRedirect('/specfem3dglobe/')
+                return HttpResponseRedirect(config.root + '/')
     else:
         # Populate new_data with a 'flattened' version of the current data.
         new_data = manipulator.flatten_data()
@@ -853,19 +872,19 @@
     # Populate the FormWrapper.
     form = forms.FormWrapper(manipulator, new_data, errors, edit_inline = True)
     
-    html = loader.render_to_string(template, { 'form': form, 'desktop': desktop })
+    html = loader.render_to_string(template, { 'form': form, 'desktop': desktop, 'root': config.root })
     register.content = gui.StaticContent(html)
     desktop.activeWindow.selectWindow(register)
     return desktop
 
 
 def profile(request, path, desktop):
-    appWindow = gui.AppWindow("/specfem3dglobe/profile/", "Profile")
+    appWindow = gui.AppWindow(config.root + "/profile/", "Profile")
     desktop.insertWindow(appWindow)
     desktop.selectWindow(appWindow)
     
-    contact = gui.ChildWindow("/specfem3dglobe/profile/", "Contact")
-    password = gui.ChildWindow("/specfem3dglobe/profile/password/", "Password")
+    contact = gui.ChildWindow(config.root + "/profile/", "Contact")
+    password = gui.ChildWindow(config.root + "/profile/password/", "Password")
     appWindow.insertWindow(contact)
     appWindow.insertWindow(password)
 
@@ -887,7 +906,7 @@
             user, errors = manipulator.save(new_data)
             if not errors:
                 user.message_set.create(message="Your contact information has been saved.")
-                return HttpResponseRedirect('/specfem3dglobe/')
+                return HttpResponseRedirect(config.root + '/')
     else:
         # Populate new_data with a 'flattened' version of the current data.
         new_data = manipulator.flatten_data()
@@ -896,7 +915,7 @@
     # Populate the FormWrapper.
     form = forms.FormWrapper(manipulator, new_data, errors, edit_inline = True)
     
-    html = loader.render_to_string(template, { 'form': form, 'desktop': desktop })
+    html = loader.render_to_string(template, { 'form': form, 'desktop': desktop, 'root': config.root })
     contact.content = gui.StaticContent(html)
     desktop.activeWindow.selectWindow(contact)
     return desktop
@@ -949,9 +968,10 @@
         if not errors:
             form.save(new_data)
             request.user.message_set.create(message="Your password has been changed.")
-            return HttpResponseRedirect('/specfem3dglobe/')
+            return HttpResponseRedirect(config.root + '/')
         
-    html = loader.render_to_string(template_name, { 'form': forms.FormWrapper(form, new_data, errors) })
+    html = loader.render_to_string(template_name, { 'form': forms.FormWrapper(form, new_data, errors),
+                                                    'root': config.root })
     password.content = gui.StaticContent(html)
     desktop.activeWindow.selectWindow(password)
     return desktop
@@ -968,7 +988,7 @@
         name = path.pop(0)
         nchunks = intOr404(name)
         if path: raise Http404
-        window = gui.ChildWindow("/specfem3dglobe/config/specfem3dglobe/meshes/new/%d/" % nchunks, "New")
+        window = gui.ChildWindow(config.root + "/config/specfem3dglobe/meshes/new/%d/" % nchunks, "New")
         return manipulate_mesh(request, desktop, window, nchunks = nchunks, action='new')
     
     raise Http404
@@ -1004,12 +1024,12 @@
                              properties,
                              FSNode,
                              objId,
-                             post_save_redirect = '/specfem3dglobe/home/',
+                             post_save_redirect = config.root + '/home/',
                              follow = FSNode.follow,
                              )
     if name == "delete":
         if path: raise Http404
-        return moveObjectToTrash(mesh, request, "/specfem3dglobe/home/")
+        return moveObjectToTrash(mesh, request, config.root + "/home/")
 
     raise Http404
 
@@ -1059,7 +1079,7 @@
                 manipulator.do_html2python(new_data)
                 manipulator.save(new_data)
                 if not errors:
-                    return HttpResponseRedirect('/specfem3dglobe/home/')
+                    return HttpResponseRedirect(config.root + '/home/')
     else:
         # Populate new_data with a 'flattened' version of the current data.
         new_data = manipulator.flatten_data()
@@ -1091,7 +1111,7 @@
                          desktop,
                          window,
                          ModelClass,
-                         post_save_redirect = '/specfem3dglobe/home/',
+                         post_save_redirect = config.root + '/home/',
                          follow = { 'fsNode': False },
                          )
 
@@ -1102,7 +1122,7 @@
                          window,
                          ModelClass,
                          object_id,
-                         post_save_redirect = '/specfem3dglobe/home/',
+                         post_save_redirect = config.root + '/home/',
                          follow = { 'fsNode': False },
                          )
 
@@ -1206,11 +1226,11 @@
                              properties,
                              FSNode,
                              workspace.fsNode.id, # Ouch!
-                             post_save_redirect = '/specfem3dglobe/home/',
+                             post_save_redirect = config.root + '/home/',
                              follow = FSNode.follow,
                              )
     if name == "delete":
-        return moveObjectToTrash(workspace, request, "/specfem3dglobe/home/")
+        return moveObjectToTrash(workspace, request, config.root + "/home/")
 
     response = eventFiles(name, event, request)
     if response:
@@ -1262,7 +1282,7 @@
         print >>html, '<tbody class=%s>' % (i % 2 and 'even' or 'odd')
         for meshGroup in modelGroup.itervalues():
             for ps in meshGroup:
-                atDepth = img("/specfem3dglobe/pics/icon-%s.gif" % (ps.receivers_can_be_buried and "yes" or "no"))
+                atDepth = img(config.root + "/pics/icon-%s.gif" % (ps.receivers_can_be_buried and "yes" or "no"))
                 print >>html, ('<tr><td>%s</td><td>%s</td><td>%.0f</td><td>%s</td><td>%s</td><td>unavailable</td></tr>' %
                                (ps.model, ps.mesh, ps.mesh.shortestPeriod(), atDepth, ps)
                                )
@@ -1386,11 +1406,11 @@
 
     if path: raise Http404
 
-    search = gui.Search("search", "Search", url = "/specfem3dglobe/events/")
+    search = gui.Search("search", "Search", url = config.root + "/events/")
     navtree = gui.Directory("events", "Events", [
         search,
         ])
-    appWindow = gui.EventFinder("/specfem3dglobe/events/", "Event Finder", navtree)
+    appWindow = gui.EventFinder(config.root + "/events/", "Event Finder", navtree)
     desktop.insertWindow(appWindow)
     desktop.selectWindow(appWindow)
     
@@ -1400,7 +1420,7 @@
 
     if not request.GET:
         appWindow.path.append(search)
-        search = gui.ChildWindow("/specfem3dglobe/events/", "Search")
+        search = gui.ChildWindow(config.root + "/events/", "Search")
         desktop.activeWindow.insertWindow(search)
         html = loader.render_to_string('SeismoWebPortal/event_search.html')
         search.content = gui.StaticContent(html)
@@ -1443,7 +1463,8 @@
     
     results = gui.ChildWindow(resultsURL, "Results")
     html = loader.render_to_string('SeismoWebPortal/event_search_results.html',
-                                   {'event_list': parser.cmtList })
+                                   {'event_list': parser.cmtList,
+                                    'root': config.root})
     results.content = gui.StaticContent(html)
     desktop.activeWindow.selectWindow(results)
     return desktop
@@ -1457,7 +1478,7 @@
     if action == "new":
         manipulator = SingleSourceEventAddManipulator()
         event = None
-        window = gui.ChildWindow("/specfem3dglobe/config/events/new/", "New")
+        window = gui.ChildWindow(config.root + "/config/events/new/", "New")
         desktop.activeWindow.insertWindow(window)
     elif action == "edit":
         event = workspace.event
@@ -1478,7 +1499,7 @@
             if name:
                 obj.fsNode.name = name
                 obj.fsNode.save()
-            url = "/specfem3dglobe/%i/" % obj.fsNode.id
+            url = config.root + "/%i/" % obj.fsNode.id
             return HttpResponseRedirect(url)
     else:
         new_data = manipulator.flatten_data()
@@ -1501,7 +1522,7 @@
                       path,
                       desktop,
                       UploadEventManipulator(),
-                      "/specfem3dglobe/config/events/upload/",
+                      config.root + "/config/events/upload/",
                       "SeismoWebPortal/event_upload.html")
 
 
@@ -1525,7 +1546,7 @@
             if not errors:
                 manipulator.do_html2python(new_data)
                 newObject = manipulator.save(new_data, request.user)
-                return HttpResponseRedirect("/specfem3dglobe/%i/" % newObject.fsNode.id)
+                return HttpResponseRedirect(config.root + "/%i/" % newObject.fsNode.id)
     else:
         errors = new_data = {}
 
@@ -1533,7 +1554,10 @@
     child.buttons.append(helpButton(request))
     form = forms.FormWrapper(manipulator, new_data, errors)
     html = loader.render_to_string(templateName,
-                                   {'form': form, 'help_visible': help_visible}
+                                   {'form': form,
+                                    'help_visible': help_visible,
+                                    'root': config.root,
+                                    'action': url}
                                    )
     child.content = gui.StaticContent(html)
     desktop.activeWindow.selectWindow(child)
@@ -1678,7 +1702,7 @@
 
     if name == "delete":
         obj = get_object_or_404(StationList, id=objId)
-        return moveObjectToTrash(obj, request, "/specfem3dglobe/home/")
+        return moveObjectToTrash(obj, request, config.root + "/home/")
 
     if name == "map.jpg":
         return stations_map_jpg(stationList)
@@ -1694,7 +1718,7 @@
 def stationlist_detail_gearth(request, object_id):
     stationList = get_object_or_404(StationList, id=object_id)
     kwds = dict(queryset = stationList.station_set.all(),
-                extra_context = {'name': stationList.name})
+                extra_context = {'name': stationList.fsNode.name})
     return station_list_gearth(request, **kwds)
 
 
@@ -1844,7 +1868,7 @@
     else:
         showHide = "show_help=1"
         title = "Show Help"
-    return gui.WindowButton("/specfem3dglobe/help/toggle/?" + showHide + "&post_toggle_redirect=" + quote(request.path), title)
+    return gui.WindowButton(config.root + "/help/toggle/?" + showHide + "&post_toggle_redirect=" + quote(request.path), title)
 
 def help_login_hook(request, user):
     try:
@@ -1960,7 +1984,7 @@
 def config_mineos_models(request, path, desktop):
     return uploadOnly(request, path, desktop,
                       UploadMineosModelManipulator(),
-                      "/specfem3dglobe/config/mineos/models/upload/",
+                      config.root + "/config/mineos/models/upload/",
                       "SeismoWebPortal/mineosmodel_upload.html")
 
 



More information about the cig-commits mailing list