Replace HomeSettings with Presence Model class. Replace SiteSettings with
authorTodd Larsen <tlarsen@google.com>
Fri, 21 Nov 2008 10:46:15 +0000
changeset 534 c31cfbf1a20f
parent 533 ba3309b2fd30
child 535 9045b8888772
Replace HomeSettings with Presence Model class. Replace SiteSettings with Site Model class. Derive Group Model class from Presence, adding the "home page settings" properties in a Melange site presence to every Group. Patch by: Todd Larsen
app/soc/logic/models/base.py
app/soc/logic/models/home_settings.py
app/soc/logic/models/presence.py
app/soc/logic/models/site.py
app/soc/logic/models/site_settings.py
app/soc/models/group.py
app/soc/models/home_settings.py
app/soc/models/presence.py
app/soc/models/site.py
app/soc/models/site_settings.py
app/soc/templates/soc/base.html
app/soc/templates/soc/home_settings/error.html
app/soc/templates/soc/home_settings/list/home_heading.html
app/soc/templates/soc/home_settings/list/home_row.html
app/soc/templates/soc/home_settings/public.html
app/soc/templates/soc/presence/error.html
app/soc/templates/soc/presence/list/home_heading.html
app/soc/templates/soc/presence/list/home_row.html
app/soc/templates/soc/presence/public.html
app/soc/templates/soc/site/edit.html
app/soc/templates/soc/site/ga.html
app/soc/templates/soc/site/list/site_heading.html
app/soc/templates/soc/site/list/site_row.html
app/soc/templates/soc/site_settings/edit.html
app/soc/templates/soc/site_settings/ga.html
app/soc/templates/soc/site_settings/list/site_heading.html
app/soc/templates/soc/site_settings/list/site_row.html
app/soc/views/helper/responses.py
app/soc/views/models/home_settings.py
app/soc/views/models/presence.py
app/soc/views/models/site.py
app/soc/views/models/site_settings.py
app/soc/views/models/sponsor.py
app/soc/views/sitemap/build.py
--- a/app/soc/logic/models/base.py	Fri Nov 21 08:41:23 2008 +0000
+++ b/app/soc/logic/models/base.py	Fri Nov 21 10:46:15 2008 +0000
@@ -468,10 +468,6 @@
       supplied key_name and properties.
     """
 
-    import logging
-    logging.info(key_name)
-    logging.info(properties)
-
     entity = self.getFromKeyName(key_name)
 
     if not entity:
--- a/app/soc/logic/models/home_settings.py	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""HomeSettings (Model) query functions.
-"""
-
-__authors__ = [
-  '"Sverre Rabbelier" <sverre@rabbelier.nl>',
-  '"Lennard de Rijk" <ljvderijk@gmail.com>'
-  ]
-
-
-from soc.logic.models import base
-
-import soc.models.home_settings
-
-
-class Logic(base.Logic):
-  """Logic methods for the HomeSettings model.
-  """
-
-  def __init__(self):
-    """Defines the name, key_name and model for this entity.
-    """
-    base.Logic.__init__(self, soc.models.home_settings.HomeSettings)
-  
-  def getKeyValues(self, entity):
-    """See base.Logic.getKeyNameValues.
-    """
-
-    return [entity.scope_path, entity.link_id]
-
-  def getKeyValuesFromFields(self, fields):
-    """See base.Logic.getKeyValuesFromFields.
-    """
-
-    return [fields['scope_path'], fields['link_id']]
-
-  def getKeyFieldNames(self):
-    """See base.Logic.getKeyFieldNames.
-    """
-
-    return ['scope_path', 'link_id']
-
-logic = Logic()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/logic/models/presence.py	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,58 @@
+#!/usr/bin/python2.5
+#
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Presence (Model) query functions.
+"""
+
+__authors__ = [
+  '"Sverre Rabbelier" <sverre@rabbelier.nl>',
+  '"Lennard de Rijk" <ljvderijk@gmail.com>'
+  ]
+
+
+from soc.logic.models import base
+
+import soc.models.presence
+
+
+class Logic(base.Logic):
+  """Logic methods for the Presence model.
+  """
+
+  def __init__(self):
+    """Defines the name, key_name and model for this entity.
+    """
+    base.Logic.__init__(self, soc.models.presence.Presence)
+  
+  def getKeyValues(self, entity):
+    """See base.Logic.getKeyNameValues.
+    """
+
+    return [entity.scope_path, entity.link_id]
+
+  def getKeyValuesFromFields(self, fields):
+    """See base.Logic.getKeyValuesFromFields.
+    """
+
+    return [fields['scope_path'], fields['link_id']]
+
+  def getKeyFieldNames(self):
+    """See base.Logic.getKeyFieldNames.
+    """
+
+    return ['scope_path', 'link_id']
+
+logic = Logic()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/logic/models/site.py	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,54 @@
+#!/usr/bin/python2.5
+#
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Site (Model) query functions.
+"""
+
+__authors__ = [
+  '"Sverre Rabbelier" <sverre@rabbelier.nl>',
+  ]
+
+
+from soc.logic.models import base
+from soc.logic.models import presence
+
+import soc.models.presence
+import soc.models.site
+
+
+class Logic(presence.Logic):
+  """Logic methods for the Site model.
+  """
+
+  DEF_SITE_SCOPE_PATH = 'site'
+  DEF_SITE_LINK_ID = 'home'
+  DEF_SITE_HOME_DOC_LINK_ID = 'home'
+
+  def __init__(self):
+    """Defines the name, key_name and model for this entity.
+    """
+    base.Logic.__init__(self, soc.models.site.Site,
+                        base_model=soc.models.presence.Presence)
+
+  def getMainKeyValues(self):
+    """Returns the default key values for the site settings.
+    """
+
+    return [self.DEF_SITE_SCOPE_PATH, 
+            self.DEF_SITE_LINK_ID]
+
+
+logic = Logic()
--- a/app/soc/logic/models/site_settings.py	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""SiteSettings (Model) query functions.
-"""
-
-__authors__ = [
-  '"Sverre Rabbelier" <sverre@rabbelier.nl>',
-  ]
-
-
-from soc.logic.models import base
-from soc.logic.models import home_settings
-
-import soc.models.home_settings
-import soc.models.site_settings
-
-
-class Logic(home_settings.Logic):
-  """Logic methods for the SiteSettings model.
-  """
-
-  DEF_SITE_SETTINGS_SCOPE_PATH = 'site'
-  DEF_SITE_SETTINGS_LINK_ID = 'home'
-  DEF_SITE_HOME_DOC_LINK_ID = 'home'
-
-  def __init__(self):
-    """Defines the name, key_name and model for this entity.
-    """
-    base.Logic.__init__(self, soc.models.site_settings.SiteSettings,
-                        base_model=soc.models.home_settings.HomeSettings)
-
-  def getMainKeyValues(self):
-    """Returns the default key values for the site settings.
-    """
-
-    return [self.DEF_SITE_SETTINGS_SCOPE_PATH, 
-            self.DEF_SITE_SETTINGS_LINK_ID]
-
-
-logic = Logic()
--- a/app/soc/models/group.py	Fri Nov 21 08:41:23 2008 +0000
+++ b/app/soc/models/group.py	Fri Nov 21 10:46:15 2008 +0000
@@ -28,11 +28,11 @@
 
 from soc.models import countries
 
-import soc.models.linkable
+import soc.models.presence
 import soc.models.user
 
 
-class Group(soc.models.linkable.Linkable):
+class Group(soc.models.presence.Presence):
   """Common data fields for all groups.
   """
 
--- a/app/soc/models/home_settings.py	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#   http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""This module contains the HomeSettings Model."""
-
-__authors__ = [
-  '"Pawel Solyga" <pawel.solyga@gmail.com>',
-  '"Todd Larsen" <tlarsen@google.com>',
-]
-
-
-from google.appengine.ext import db
-
-from django.utils.translation import ugettext_lazy
-
-import soc.models.document
-import soc.models.linkable
-
-
-class HomeSettings(soc.models.linkable.Linkable):
-  """Model that stores settings for various Home pages.
-
-  This Model is the basis for more specific "/home" view settings, such as
-  SiteSettings, ProgramSettings, etc.
-  """
-
-  #: Reference to Document containing the contents of the "/home" page
-  home = db.ReferenceProperty(
-    reference_class=soc.models.document.Document,
-    collection_name='home')
-  home.help_text = ugettext_lazy(
-      'Document to be used as the "/home" page static contents.')
-
-  #: Valid ATOM or RSS feed url or None if unused. Feed entries are shown 
-  #: on the site page using Google's JavaScript blog widget  
-  feed_url = db.LinkProperty(verbose_name=ugettext_lazy('Feed URL'))
-  feed_url.help_text = ugettext_lazy(
-      'The URL should be a valid ATOM or RSS feed. '
-      'Feed entries are shown on the home page.')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/models/presence.py	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,58 @@
+#!/usr/bin/python2.5
+#
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""This module contains the Presence Model."""
+
+__authors__ = [
+  '"Pawel Solyga" <pawel.solyga@gmail.com>',
+  '"Todd Larsen" <tlarsen@google.com>',
+]
+
+
+from google.appengine.ext import db
+
+from django.utils.translation import ugettext_lazy
+
+import soc.models.document
+import soc.models.linkable
+
+
+class Presence(soc.models.linkable.Linkable):
+  """Model for anything that has a "presence" on a Melange site.
+
+  A "presence" is (currently) defined as:
+  * having a "home" page with contents set by selecting a Document
+  * displaying an (optional) ATOM or RSS feed
+
+  Models that have a "presence" on a Melange web site are (currently):
+  * any Group (Organization, Club, etc.)
+  * any Program
+  * the site itself, which is a singleton Presence
+  """
+
+  #: Reference to Document containing the contents of the "/home" page
+  home = db.ReferenceProperty(
+    reference_class=soc.models.document.Document,
+    collection_name='home')
+  home.help_text = ugettext_lazy(
+      'Document to be used as the "/home" page static contents.')
+
+  #: Valid ATOM or RSS feed url or None if unused. Feed entries are shown 
+  #: on the site page using Google's JavaScript blog widget  
+  feed_url = db.LinkProperty(verbose_name=ugettext_lazy('Feed URL'))
+  feed_url.help_text = ugettext_lazy(
+      'The URL should be a valid ATOM or RSS feed. '
+      'Feed entries are shown on the home page.')
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/models/site.py	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,54 @@
+#!/usr/bin/python2.5
+#
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""This module contains the Site Model."""
+
+__authors__ = [
+  '"Pawel Solyga" <pawel.solyga@gmail.com>',
+  '"Lennard de Rijk" <ljvderijk@gmail.com>',
+]
+
+
+from google.appengine.ext import db
+
+from django.utils.translation import ugettext_lazy
+
+import soc.models.presence
+
+
+class Site(soc.models.presence.Presence):
+  """Model of a Site, which stores per site configuration.
+
+  The Site Model stores configuration information unique to the Melange
+  web site as a whole (in addition to any configuration that is common to
+  any "presence" on the site, such as a Group or Program).
+  """
+
+  #: Valid Google Analytics tracking number, if entered every page
+  #: is going to have Google Analytics JS initialization code in 
+  #: the footer with the given tracking number.
+  ga_tracking_num = db.StringProperty(
+      verbose_name=ugettext_lazy('Google Analytics'))
+  ga_tracking_num.help_text = ugettext_lazy(
+      'Valid Google Analytics tracking number. If the number is '
+      'entered every page is going to have Google Analytics '
+      'initialization code in footer.')
+
+  #: Valid Google Maps API Key. Used to embed Google Maps.
+  gmaps_api_key = db.StringProperty(verbose_name=ugettext_lazy('Google Maps'))
+  gmaps_api_key.help_text = ugettext_lazy(
+      'Valid Google Maps API Key. This key is used for '
+      'embedding Google Maps into the website.')
--- a/app/soc/models/site_settings.py	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#   http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""This module contains the SiteSettings Model."""
-
-__authors__ = [
-  '"Pawel Solyga" <pawel.solyga@gmail.com>',
-  '"Lennard de Rijk" <ljvderijk@gmail.com>',
-]
-
-
-from google.appengine.ext import db
-
-from django.utils.translation import ugettext_lazy
-
-import soc.models.home_settings
-
-
-class SiteSettings(soc.models.home_settings.HomeSettings):
-  """Model of a SiteSettings, which stores per site configuration."""
-
-  #: Valid Google Analytics tracking number, if entered every page
-  #: is going to have Google Analytics JS initialization code in 
-  #: the footer with the given tracking number.
-  ga_tracking_num = db.StringProperty(verbose_name=ugettext_lazy('Google Analytics'))
-  ga_tracking_num.help_text = ugettext_lazy(
-      'Valid Google Analytics tracking number. If the number is '
-      'entered every page is going to have Google Analytics '
-      'initialization code in footer.')
-
-  #: Valid Google Maps API Key. Used to embed Google Maps.
-  gmaps_api_key = db.StringProperty(verbose_name=ugettext_lazy('Google Maps'))
-  gmaps_api_key.help_text = ugettext_lazy(
-      'Valid Google Maps API Key. This key is used for '
-      'embedding Google Maps into the website.')
--- a/app/soc/templates/soc/base.html	Fri Nov 21 08:41:23 2008 +0000
+++ b/app/soc/templates/soc/base.html	Fri Nov 21 10:46:15 2008 +0000
@@ -152,7 +152,7 @@
    </div>
    <div id="footer" dir="ltr">
     {% if ga_tracking_num %}
-    {% include 'soc/site_settings/ga.html' %}
+    {% include 'soc/site/ga.html' %}
     {% endif %}
     <div class="text">
 	{% block footer %}
--- a/app/soc/templates/soc/home_settings/error.html	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-{% extends "soc/base.html" %}
-{% comment %}
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-{% endcomment %}
-
-{% block page_title %}
-Default Home page
-{% endblock %}
-
-{% block header_title %}
-Default Home page
-{% endblock %}
-
-{% block body %}
-This is the default home page, which can be edited via the <a href="/home/settings/create">Home Settings</a>.<br />
-{% endblock %}
--- a/app/soc/templates/soc/home_settings/list/home_heading.html	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<tr align="left">
-  <th class="first" align="right">Path</th>
-  <th>Home Document</th>
-</tr>
--- a/app/soc/templates/soc/home_settings/list/home_row.html	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'" 
-onclick="document.location.href='/home/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}'" name="name">
-  <td align="right">
-   <div class="title">
-    <a class="noul"
-     href="/home/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}">{{ data_element.scope_path}}/{{ data_element.link_id }}</a>
-   </div>
-  </td>
-  <td><div class="link_id">{{ data_element.home.title }}</div></td>
-</tr>
--- a/app/soc/templates/soc/home_settings/public.html	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-{% extends "soc/home/public.html" %}
-{% comment %}
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-{% endcomment %}
-
-{% block missing_doc %}
-The contents of this default Site home page can be changed by
-<a href="/document/edit">creating a new Document</a> or
-<a href="/document/list">editing an existing Document</a> and then selecting
-that Document in the
-<a href="/site/settings/edit">Site Settings</a> interface.
-Other elements of this page, such as a feed to be displayed below this
-content, can also be set using the
-<a href="/site/settings/edit">Site Settings</a> interface.
-You need to sign in as site Developer in order to change
-<a href="/site/settings/edit">Site Settings</a>.
-{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/presence/error.html	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,26 @@
+{% extends "soc/base.html" %}
+{% comment %}
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+
+{% block page_title %}
+Default Home page
+{% endblock %}
+
+{% block header_title %}
+Default Home page
+{% endblock %}
+
+{% block body %}
+This is the default home page, which can be edited via the <a href="/home/settings/create">Home Settings</a>.<br />
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/presence/list/home_heading.html	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,4 @@
+<tr align="left">
+  <th class="first" align="right">Path</th>
+  <th>Home Document</th>
+</tr>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/presence/list/home_row.html	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,10 @@
+<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'" 
+onclick="document.location.href='/home/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}'" name="name">
+  <td align="right">
+   <div class="title">
+    <a class="noul"
+     href="/home/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}">{{ data_element.scope_path}}/{{ data_element.link_id }}</a>
+   </div>
+  </td>
+  <td><div class="link_id">{{ data_element.home.title }}</div></td>
+</tr>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/presence/public.html	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,27 @@
+{% extends "soc/home/public.html" %}
+{% comment %}
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+
+{% block missing_doc %}
+The contents of this default Site home page can be changed by
+<a href="/document/edit">creating a new Document</a> or
+<a href="/document/list">editing an existing Document</a> and then selecting
+that Document in the
+<a href="/site/settings/edit">Site Settings</a> interface.
+Other elements of this page, such as a feed to be displayed below this
+content, can also be set using the
+<a href="/site/settings/edit">Site Settings</a> interface.
+You need to sign in as site Developer in order to change
+<a href="/site/settings/edit">Site Settings</a>.
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/site/edit.html	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,111 @@
+{% extends "soc/base.html" %}
+{% comment %}
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+
+{% block body %}
+<p>
+<p>
+{% block instructions %}
+Please use this form to set basic home page settings.
+{% endblock %}
+</p>
+<p>
+</p>
+<form method="POST">
+ <table>
+	{{ settings_form.as_table }}
+{% if home_doc %}
+  <tr>
+   <td colspan="4">&nbsp;</td>
+  </tr>
+{% comment %}
+TODO(tlarsen): OK, this is pretty lame as well.  I think we need some sort
+  of "Document preview" that can be appended to the end of the page. Also,
+  There is way too much text on this page.  Can a UI wizard please fix this
+  UI?
+{% endcomment %}
+  <tr>
+   <td colspan="4">
+An existing Document is currently selected to provide the body contents of the home page:
+   </td>
+  </tr>
+  <tr>
+   <td>&nbsp;</td>
+   <td colspan="3">
+    {{ home_doc.title }}
+   </td> 
+  </tr>
+  <tr>
+   <th>Path:</th>
+   <td colspan="2">
+    {{ home_doc.scope_path }}/{{ home_doc.link_id }}
+   </td>
+  </tr>
+  <tr>
+   <th>Created By:</th>
+   <td colspan="2">
+    {{ home_doc.author.link_id }}
+   </td>
+  </tr>
+  <tr>
+   <th>Created On:</th>
+   <td colspan="2">
+    {{ home_doc.created }}
+   </td>
+  </tr>
+  <tr>
+   <th>Modified:</th>
+   <td colspan="2">
+    {{ home_doc.modified }}
+   </td>
+  </tr>
+{% endif %}
+  <tr>
+   <td colspan="4">
+ <p>
+ Any existing Document (to which access is permitted) can be used as the body contents of the home page.
+ <ul>
+  <li>
+<a href="/document/edit">Create a new Document to use for the home page content here.</a>
+  </li>
+  <li>
+<a href="/document/list">Edit an existing Document to use for the home page content here.</a>
+  </li>
+ </ul>
+Then, specify the Document to use below:
+</p>
+   </td>
+  </tr>
+  <tr>
+   <td colspan="4">&nbsp;</td>
+  </tr>
+	{{ doc_select_form.as_table }}
+  <tr>
+   <td colspan="4">&nbsp;</td>
+  </tr>
+   <table>
+   <tr>
+     {% block submit_buttons %}
+    <td> 
+     <input style="font-weight: bold" type="submit" value="Save Changes"/></span>
+    </td>
+    <td>
+     <input type="button" onclick="location.href='/'" value="Cancel"/>
+    </td>
+    {% endblock %}
+   </tr>
+  </table>
+</form>
+</p>
+{% endblock %}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/site/ga.html	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,21 @@
+{% comment %}
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+{% endcomment %}
+<script type="text/javascript">
+var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+</script>
+<script type="text/javascript">
+var pageTracker = _gat._getTracker("{{ ga_tracking_num }}");
+pageTracker._trackPageview();
+</script>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/site/list/site_heading.html	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,4 @@
+<tr align="left">
+  <th class="first" align="right">Path</th>
+  <th>Home Document</th>
+</tr>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/templates/soc/site/list/site_row.html	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,10 @@
+<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'" 
+onclick="document.location.href='/site/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}'" name="name">
+  <td align="right">
+   <div class="title">
+    <a class="noul"
+     href="/site/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}">{{ data_element.scope_path}}/{{ data_element.link_id }}</a>
+   </div>
+  </td>
+  <td><div class="link_id">{{ data_element.home.title }}</div></td>
+</tr>
--- a/app/soc/templates/soc/site_settings/edit.html	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-{% extends "soc/base.html" %}
-{% comment %}
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-{% endcomment %}
-
-{% block body %}
-<p>
-<p>
-{% block instructions %}
-Please use this form to set basic home page settings.
-{% endblock %}
-</p>
-<p>
-</p>
-<form method="POST">
- <table>
-	{{ settings_form.as_table }}
-{% if home_doc %}
-  <tr>
-   <td colspan="4">&nbsp;</td>
-  </tr>
-{% comment %}
-TODO(tlarsen): OK, this is pretty lame as well.  I think we need some sort
-  of "Document preview" that can be appended to the end of the page. Also,
-  There is way too much text on this page.  Can a UI wizard please fix this
-  UI?
-{% endcomment %}
-  <tr>
-   <td colspan="4">
-An existing Document is currently selected to provide the body contents of the home page:
-   </td>
-  </tr>
-  <tr>
-   <td>&nbsp;</td>
-   <td colspan="3">
-    {{ home_doc.title }}
-   </td> 
-  </tr>
-  <tr>
-   <th>Path:</th>
-   <td colspan="2">
-    {{ home_doc.scope_path }}/{{ home_doc.link_id }}
-   </td>
-  </tr>
-  <tr>
-   <th>Created By:</th>
-   <td colspan="2">
-    {{ home_doc.author.link_id }}
-   </td>
-  </tr>
-  <tr>
-   <th>Created On:</th>
-   <td colspan="2">
-    {{ home_doc.created }}
-   </td>
-  </tr>
-  <tr>
-   <th>Modified:</th>
-   <td colspan="2">
-    {{ home_doc.modified }}
-   </td>
-  </tr>
-{% endif %}
-  <tr>
-   <td colspan="4">
- <p>
- Any existing Document (to which access is permitted) can be used as the body contents of the home page.
- <ul>
-  <li>
-<a href="/document/edit">Create a new Document to use for the home page content here.</a>
-  </li>
-  <li>
-<a href="/document/list">Edit an existing Document to use for the home page content here.</a>
-  </li>
- </ul>
-Then, specify the Document to use below:
-</p>
-   </td>
-  </tr>
-  <tr>
-   <td colspan="4">&nbsp;</td>
-  </tr>
-	{{ doc_select_form.as_table }}
-  <tr>
-   <td colspan="4">&nbsp;</td>
-  </tr>
-   <table>
-   <tr>
-     {% block submit_buttons %}
-    <td> 
-     <input style="font-weight: bold" type="submit" value="Save Changes"/></span>
-    </td>
-    <td>
-     <input type="button" onclick="location.href='/'" value="Cancel"/>
-    </td>
-    {% endblock %}
-   </tr>
-  </table>
-</form>
-</p>
-{% endblock %}
--- a/app/soc/templates/soc/site_settings/ga.html	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-{% comment %}
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-  http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-{% endcomment %}
-<script type="text/javascript">
-var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
-document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
-</script>
-<script type="text/javascript">
-var pageTracker = _gat._getTracker("{{ ga_tracking_num }}");
-pageTracker._trackPageview();
-</script>
--- a/app/soc/templates/soc/site_settings/list/site_heading.html	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<tr align="left">
-  <th class="first" align="right">Path</th>
-  <th>Home Document</th>
-</tr>
--- a/app/soc/templates/soc/site_settings/list/site_row.html	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-<tr class="off" onmouseover="this.className='on'" onmouseout="this.className='off'" 
-onclick="document.location.href='/site/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}'" name="name">
-  <td align="right">
-   <div class="title">
-    <a class="noul"
-     href="/site/settings/edit/{{ data_element.scope_path }}/{{ data_element.link_id }}">{{ data_element.scope_path}}/{{ data_element.link_id }}</a>
-   </div>
-  </td>
-  <td><div class="link_id">{{ data_element.home.title }}</div></td>
-</tr>
--- a/app/soc/views/helper/responses.py	Fri Nov 21 08:41:23 2008 +0000
+++ b/app/soc/views/helper/responses.py	Fri Nov 21 10:46:15 2008 +0000
@@ -30,7 +30,7 @@
 
 from soc.logic import accounts
 from soc.logic import system
-from soc.logic.models import site_settings
+from soc.logic.models import site
 from soc.views import helper
 from soc.views.sitemap import sidebar
 
@@ -107,9 +107,9 @@
   context['sign_out'] = users.create_logout_url(request.path)
   context['sidebar_menu_items'] = sidebar.SIDEBAR
 
-  settings = site_settings.logic.getFromFields(
-      scope_path=site_settings.logic.DEF_SITE_SETTINGS_SCOPE_PATH,
-      link_id=site_settings.logic.DEF_SITE_SETTINGS_LINK_ID)
+  settings = site.logic.getFromFields(
+      scope_path=site.logic.DEF_SITE_SCOPE_PATH,
+      link_id=site.logic.DEF_SITE_LINK_ID)
   
   if settings:
     context['ga_tracking_num'] = settings.ga_tracking_num
--- a/app/soc/views/models/home_settings.py	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Views for Home Settings.
-"""
-
-__authors__ = [
-    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
-  ]
-
-
-from google.appengine.ext import db
-from google.appengine.api import users
-
-from django import forms
-from django.utils.translation import ugettext_lazy
-
-from soc.logic import dicts
-from soc.logic import validate
-from soc.logic.models import document as document_logic
-from soc.views import helper
-from soc.views.helper import widgets
-from soc.views.models import base
-
-import soc.models.home_settings
-import soc.logic.models.home_settings
-import soc.logic.dicts
-import soc.views.helper
-import soc.views.helper.widgets
-
-
-class SettingsValidationForm(helper.forms.BaseForm):
-  """Django form displayed when creating or editing Settings.
-  
-  This form includes validation functions for Settings fields.
-  """
-
-    # TODO(tlarsen): scope_path will be a hard-coded read-only
-    #   field for some (most?) User Roles
-  doc_scope_path = forms.CharField(required=False,
-      label=ugettext_lazy('Document scope path'),
-      help_text=soc.models.work.Work.scope_path.help_text)
-
-  # TODO(tlarsen): actually, using these two text fields to specify
-  #   the Document is pretty cheesy; this needs to be some much better
-  #   Role-scoped Document selector that we don't have yet
-  doc_link_id = forms.CharField(required=False,
-      label=ugettext_lazy('Document link ID'),
-      help_text=soc.models.work.Work.link_id.help_text)
-
-  def clean_feed_url(self):
-    feed_url = self.cleaned_data.get('feed_url')
-
-    if feed_url == '':
-      # feed url not supplied (which is OK), so do not try to validate it
-      return None
-    
-    if not validate.isFeedURLValid(feed_url):
-      raise forms.ValidationError('This URL is not a valid ATOM or RSS feed.')
-
-    return feed_url
-
-
-class CreateForm(SettingsValidationForm):
-  """Django form displayed when creating or editing Settings.
-  """
-
-  class Meta:
-    """Inner Meta class that defines some behavior for the form.
-    """
-    #: db.Model subclass for which the form will gather information
-    model = soc.models.home_settings.HomeSettings
-
-    #: list of model fields which will *not* be gathered by the form
-    exclude = ['inheritance_line', 'home']
-
-
-class EditForm(CreateForm):
-  """Django form displayed a Document is edited.
-  """
-
-  pass
-
-
-class View(base.View):
-  """View methods for the Document model.
-  """
-
-  def __init__(self, original_params=None):
-    """Defines the fields and methods required for the base View class
-    to provide the user with list, public, create, edit and delete views.
-
-    Params:
-      original_params: a dict with params for this View
-    """
-
-    params = {}
-
-    params['name'] = "Home Settings"
-    params['name_short'] = "Home Settings"
-    params['name_plural'] = "Home Settings"
-    params['url_name'] = "home/settings"
-    params['module_name'] = "home_settings"
-
-    params['edit_form'] = EditForm
-    params['create_form'] = CreateForm
-
-    # TODO(tlarsen) Add support for Django style template lookup
-    params['edit_template'] = 'soc/models/edit.html'
-    params['public_template'] = 'soc/home_settings/public.html'
-    params['list_template'] = 'soc/models/list.html'
-
-    params['lists_template'] = {
-      'list_main': 'soc/list/list_main.html',
-      'list_pagination': 'soc/list/list_pagination.html',
-      'list_row': 'soc/home_settings/list/home_row.html',
-      'list_heading': 'soc/home_settings/list/home_heading.html',
-    }
-
-    params['delete_redirect'] = '/' + params['url_name'] + '/list'
-
-    params = dicts.merge(original_params, params)
-
-    base.View.__init__(self, params=params)
-
-    self._logic = soc.logic.models.home_settings.logic
-
-  def _public(self, request, entity, context):
-    """
-    """
-
-    if not entity:
-      return
-
-    try:
-      home_doc = entity.home
-    except db.Error:
-      home_doc = None
-
-    if home_doc:
-      home_doc.content = helper.templates.unescape(home_doc.content)
-      context['home_document'] = home_doc
-
-  def _editGet(self, request, entity, form):
-    """See base.View._editGet().
-    """
-
-    try:
-      if entity.home:
-        form.fields['doc_scope_path'].initial = entity.home.scope_path
-        form.fields['doc_link_id'].initial = entity.home.link_id
-    except db.Error:
-      pass
-
-  def _editPost(self, request, entity, fields):
-    """See base.View._editPost().
-    """
-
-    doc_scope_path = fields['doc_scope_path']
-    doc_link_id = fields['doc_link_id']
-
-    # TODO notify the user if home_doc is not found
-    home_doc = document_logic.logic.getFromFields(
-    scope_path=doc_scope_path, link_id=doc_link_id)
-
-    fields['home'] = home_doc
-
-
-view = View()
-
-create = view.create
-edit = view.edit
-delete = view.delete
-list = view.list
-public = view.public
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/views/models/presence.py	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,188 @@
+#!/usr/bin/python2.5
+#
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Views for Models with a "presence" on a Melange site.
+"""
+
+__authors__ = [
+    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
+  ]
+
+
+from google.appengine.ext import db
+from google.appengine.api import users
+
+from django import forms
+from django.utils.translation import ugettext_lazy
+
+from soc.logic import dicts
+from soc.logic import validate
+from soc.logic.models import document as document_logic
+from soc.views import helper
+from soc.views.helper import widgets
+from soc.views.models import base
+
+import soc.models.presence
+import soc.logic.models.presence
+import soc.logic.dicts
+import soc.views.helper
+import soc.views.helper.widgets
+
+
+class SettingsValidationForm(helper.forms.BaseForm):
+  """Django form displayed when creating or editing Settings.
+  
+  This form includes validation functions for Settings fields.
+  """
+
+    # TODO(tlarsen): scope_path will be a hard-coded read-only
+    #   field for some (most?) User Roles
+  doc_scope_path = forms.CharField(required=False,
+      label=ugettext_lazy('Document scope path'),
+      help_text=soc.models.work.Work.scope_path.help_text)
+
+  # TODO(tlarsen): actually, using these two text fields to specify
+  #   the Document is pretty cheesy; this needs to be some much better
+  #   Role-scoped Document selector that we don't have yet
+  doc_link_id = forms.CharField(required=False,
+      label=ugettext_lazy('Document link ID'),
+      help_text=soc.models.work.Work.link_id.help_text)
+
+  def clean_feed_url(self):
+    feed_url = self.cleaned_data.get('feed_url')
+
+    if feed_url == '':
+      # feed url not supplied (which is OK), so do not try to validate it
+      return None
+    
+    if not validate.isFeedURLValid(feed_url):
+      raise forms.ValidationError('This URL is not a valid ATOM or RSS feed.')
+
+    return feed_url
+
+
+class CreateForm(SettingsValidationForm):
+  """Django form displayed when creating or editing Settings.
+  """
+
+  class Meta:
+    """Inner Meta class that defines some behavior for the form.
+    """
+    #: db.Model subclass for which the form will gather information
+    model = soc.models.presence.Presence
+
+    #: list of model fields which will *not* be gathered by the form
+    exclude = ['inheritance_line', 'home']
+
+
+class EditForm(CreateForm):
+  """Django form displayed a Document is edited.
+  """
+
+  pass
+
+
+class View(base.View):
+  """View methods for the Document model.
+  """
+
+  def __init__(self, original_params=None):
+    """Defines the fields and methods required for the base View class
+    to provide the user with list, public, create, edit and delete views.
+
+    Params:
+      original_params: a dict with params for this View
+    """
+
+    params = {}
+
+    params['name'] = "Home Settings"
+    params['name_short'] = "Home Settings"
+    params['name_plural'] = "Home Settings"
+    params['url_name'] = "home/settings"
+    params['module_name'] = "presence"
+
+    params['edit_form'] = EditForm
+    params['create_form'] = CreateForm
+
+    # TODO(tlarsen) Add support for Django style template lookup
+    params['edit_template'] = 'soc/models/edit.html'
+    params['public_template'] = 'soc/presence/public.html'
+    params['list_template'] = 'soc/models/list.html'
+
+    params['lists_template'] = {
+      'list_main': 'soc/list/list_main.html',
+      'list_pagination': 'soc/list/list_pagination.html',
+      'list_row': 'soc/presence/list/home_row.html',
+      'list_heading': 'soc/presence/list/home_heading.html',
+    }
+
+    params['delete_redirect'] = '/' + params['url_name'] + '/list'
+
+    params = dicts.merge(original_params, params)
+
+    base.View.__init__(self, params=params)
+
+    self._logic = soc.logic.models.presence.logic
+
+  def _public(self, request, entity, context):
+    """
+    """
+
+    if not entity:
+      return
+
+    try:
+      home_doc = entity.home
+    except db.Error:
+      home_doc = None
+
+    if home_doc:
+      home_doc.content = helper.templates.unescape(home_doc.content)
+      context['home_document'] = home_doc
+
+  def _editGet(self, request, entity, form):
+    """See base.View._editGet().
+    """
+
+    try:
+      if entity.home:
+        form.fields['doc_scope_path'].initial = entity.home.scope_path
+        form.fields['doc_link_id'].initial = entity.home.link_id
+    except db.Error:
+      pass
+
+  def _editPost(self, request, entity, fields):
+    """See base.View._editPost().
+    """
+
+    doc_scope_path = fields['doc_scope_path']
+    doc_link_id = fields['doc_link_id']
+
+    # TODO notify the user if home_doc is not found
+    home_doc = document_logic.logic.getFromFields(
+    scope_path=doc_scope_path, link_id=doc_link_id)
+
+    fields['home'] = home_doc
+
+
+view = View()
+
+create = view.create
+edit = view.edit
+delete = view.delete
+list = view.list
+public = view.public
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/soc/views/models/site.py	Fri Nov 21 10:46:15 2008 +0000
@@ -0,0 +1,160 @@
+#!/usr/bin/python2.5
+#
+# Copyright 2008 the Melange authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Views for Site Settings.
+"""
+
+__authors__ = [
+    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
+  ]
+
+
+from google.appengine.ext import db
+from google.appengine.api import users
+
+from django import forms
+from django.utils.translation import ugettext_lazy
+
+from soc.logic import dicts
+from soc.logic import validate
+from soc.views import helper
+from soc.views.helper import widgets
+from soc.views.models import presence
+
+import soc.models.site
+import soc.logic.models.site
+import soc.logic.dicts
+import soc.views.helper
+import soc.views.helper.widgets
+
+
+class CreateForm(presence.SettingsValidationForm):
+  """Django form displayed when creating or editing Site Settings.
+  """
+
+  class Meta:
+    """Inner Meta class that defines some behavior for the form.
+    """
+    #: db.Model subclass for which the form will gather information
+    model = soc.models.site.Site
+
+    #: list of model fields which will *not* be gathered by the form
+    exclude = ['inheritance_line', 'home', 'scope_path', 'link_id']
+
+  scope_path = forms.CharField(widget=forms.HiddenInput)
+
+  link_id = forms.CharField(widget=forms.HiddenInput)
+
+
+class EditForm(CreateForm):
+  """Django form displayed a Document is edited.
+  """
+
+  pass
+
+
+class View(presence.View):
+  """View methods for the Document model.
+  """
+
+  def __init__(self, original_params=None):
+    """Defines the fields and methods required for the base View class
+    to provide the user with list, public, create, edit and delete views.
+
+    Params:
+      original_params: a dict with params for this View
+    """
+
+    params = {}
+
+    # add ugettext_lazy ?
+    params['name'] = "Site Settings"
+    params['name_short'] = "Site Settings"
+    params['name_plural'] = "Site Settings"
+    # lower name and replace " " with "/"
+    # for module name lower name and replace " " with "_"
+    params['url_name'] = "site/settings"
+    params['module_name'] = "site"
+
+    params['edit_form'] = EditForm
+    params['create_form'] = CreateForm
+
+    params['lists_template'] = {
+      'list_main': 'soc/list/list_main.html',
+      'list_pagination': 'soc/list/list_pagination.html',
+      'list_row': 'soc/site/list/site_row.html',
+      'list_heading': 'soc/site/list/site_heading.html',
+    }
+
+    params['delete_redirect'] = '/' + params['url_name'] + '/list'
+
+    params['sidebar_additional'] = [ ( '/' + params['url_name'] + '/edit', 'Edit Main Site Settings')]
+
+    params = dicts.merge(original_params, params)
+
+    presence.View.__init__(self, original_params=params)
+
+    self._logic = soc.logic.models.site.logic
+
+  def main_public(self, request, page_name=None, **kwargs):
+    """Displays the main site settings page.
+
+    Args:
+      request: the standard Django HTTP request object
+      page_name: the page name displayed in templates as page and header title
+      kwargs: not used
+    """
+
+    keys = self._logic.getKeyFieldNames()
+    values = self._logic.getMainKeyValues()
+    key_values = dicts.zip(keys, values)
+
+    return self.public(request, page_name, **key_values)
+
+  def main_edit(self, request, page_name=None, **kwargs):
+    """Displays the edit page for the main site settings page.
+
+    Args:
+      request: the standard Django HTTP request object
+      page_name: the page name displayed in templates as page and header title
+      kwargs: not used
+    """
+
+    keys = self._logic.getKeyFieldNames()
+    values = self._logic.getMainKeyValues()
+    key_values = dicts.zip(keys, values)
+
+    return self.edit(request, page_name, seed=key_values, **key_values)
+
+  def getDjangoURLPatterns(self):
+    """See base.View.getDjangoURLPatterns().
+    """
+
+    patterns = super(View, self).getDjangoURLPatterns()
+    patterns += [(r'^$','soc.views.models.site.main_public')]
+    patterns += [(r'^' + self._params['url_name'] + '/edit$',
+                  'soc.views.models.site.main_edit')]
+    return patterns
+
+view = View()
+
+create = view.create
+edit = view.edit
+delete = view.delete
+list = view.list
+public = view.public
+main_public = view.main_public
+main_edit = view.main_edit
--- a/app/soc/views/models/site_settings.py	Fri Nov 21 08:41:23 2008 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-#!/usr/bin/python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Views for Site Settings.
-"""
-
-__authors__ = [
-    '"Sverre Rabbelier" <sverre@rabbelier.nl>',
-  ]
-
-
-from google.appengine.ext import db
-from google.appengine.api import users
-
-from django import forms
-from django.utils.translation import ugettext_lazy
-
-from soc.logic import dicts
-from soc.logic import validate
-from soc.views import helper
-from soc.views.helper import widgets
-from soc.views.models import home_settings
-
-import soc.models.site_settings
-import soc.logic.models.site_settings
-import soc.logic.dicts
-import soc.views.helper
-import soc.views.helper.widgets
-
-
-class CreateForm(home_settings.SettingsValidationForm):
-  """Django form displayed when creating or editing Site Settings.
-  """
-
-  class Meta:
-    """Inner Meta class that defines some behavior for the form.
-    """
-    #: db.Model subclass for which the form will gather information
-    model = soc.models.site_settings.SiteSettings
-
-    #: list of model fields which will *not* be gathered by the form
-    exclude = ['inheritance_line', 'home', 'scope_path', 'link_id']
-
-  scope_path = forms.CharField(widget=forms.HiddenInput)
-
-  link_id = forms.CharField(widget=forms.HiddenInput)
-
-
-class EditForm(CreateForm):
-  """Django form displayed a Document is edited.
-  """
-
-  pass
-
-
-class View(home_settings.View):
-  """View methods for the Document model.
-  """
-
-  def __init__(self, original_params=None):
-    """Defines the fields and methods required for the base View class
-    to provide the user with list, public, create, edit and delete views.
-
-    Params:
-      original_params: a dict with params for this View
-    """
-
-    params = {}
-
-    # add ugettext_lazy ?
-    params['name'] = "Site Settings"
-    params['name_short'] = "Site Settings"
-    params['name_plural'] = "Site Settings"
-    # lower name and replace " " with "/"
-    # for module name lower name and replace " " with "_"
-    params['url_name'] = "site/settings"
-    params['module_name'] = "site_settings"
-
-    params['edit_form'] = EditForm
-    params['create_form'] = CreateForm
-
-    params['lists_template'] = {
-      'list_main': 'soc/list/list_main.html',
-      'list_pagination': 'soc/list/list_pagination.html',
-      'list_row': 'soc/site_settings/list/site_row.html',
-      'list_heading': 'soc/site_settings/list/site_heading.html',
-    }
-
-    params['delete_redirect'] = '/' + params['url_name'] + '/list'
-
-    params['sidebar_additional'] = [ ( '/' + params['url_name'] + '/edit', 'Edit Main Site Settings')]
-
-    params = dicts.merge(original_params, params)
-
-    home_settings.View.__init__(self, original_params=params)
-
-    self._logic = soc.logic.models.site_settings.logic
-
-  def main_public(self, request, page_name=None, **kwargs):
-    """Displays the main site settings page.
-
-    Args:
-      request: the standard Django HTTP request object
-      page_name: the page name displayed in templates as page and header title
-      kwargs: not used
-    """
-
-    keys = self._logic.getKeyFieldNames()
-    values = self._logic.getMainKeyValues()
-    key_values = dicts.zip(keys, values)
-
-    return self.public(request, page_name, **key_values)
-
-  def main_edit(self, request, page_name=None, **kwargs):
-    """Displays the edit page for the main site settings page.
-
-    Args:
-      request: the standard Django HTTP request object
-      page_name: the page name displayed in templates as page and header title
-      kwargs: not used
-    """
-
-    keys = self._logic.getKeyFieldNames()
-    values = self._logic.getMainKeyValues()
-    key_values = dicts.zip(keys, values)
-
-    return self.edit(request, page_name, seed=key_values, **key_values)
-
-  def getDjangoURLPatterns(self):
-    """See base.View.getDjangoURLPatterns().
-    """
-
-    patterns = super(View, self).getDjangoURLPatterns()
-    patterns += [(r'^$','soc.views.models.site_settings.main_public')]
-    patterns += [(r'^' + self._params['url_name'] + '/edit$', 'soc.views.models.site_settings.main_edit')]
-    return patterns
-
-view = View()
-
-create = view.create
-edit = view.edit
-delete = view.delete
-list = view.list
-public = view.public
-main_public = view.main_public
-main_edit = view.main_edit
--- a/app/soc/views/models/sponsor.py	Fri Nov 21 08:41:23 2008 +0000
+++ b/app/soc/views/models/sponsor.py	Fri Nov 21 10:46:15 2008 +0000
@@ -63,6 +63,18 @@
       raise forms.ValidationError("This link ID is already in use.")
     return link_id
 
+  def clean_feed_url(self):
+    feed_url = self.cleaned_data.get('feed_url')
+
+    if feed_url == '':
+      # feed url not supplied (which is OK), so do not try to validate it
+      return None
+    
+    if not validate.isFeedURLValid(feed_url):
+      raise forms.ValidationError('This URL is not a valid ATOM or RSS feed.')
+
+    return feed_url
+
 
 class EditForm(CreateForm):
   """Django form displayed when editing a Sponsor.
--- a/app/soc/views/sitemap/build.py	Fri Nov 21 08:41:23 2008 +0000
+++ b/app/soc/views/sitemap/build.py	Fri Nov 21 10:46:15 2008 +0000
@@ -25,11 +25,11 @@
 from django.conf.urls import defaults
 
 from soc.views.models import document
-from soc.views.models import home_settings
+from soc.views.models import presence
 from soc.views.models import host
 from soc.views.models import request
 from soc.views.models import user
-from soc.views.models import site_settings
+from soc.views.models import site
 from soc.views.models import sponsor
 
 from soc.views.sitemap import sidebar
@@ -38,11 +38,11 @@
 
 sidebar.SIDEBAR.append(user.view.getUserSidebar())
 
-sidebar.SIDEBAR.append(home_settings.view.getSidebarLinks())
-sitemap.addPages(home_settings.view.getDjangoURLPatterns())
+sidebar.SIDEBAR.append(presence.view.getSidebarLinks())
+sitemap.addPages(presence.view.getDjangoURLPatterns())
 
-sidebar.SIDEBAR.append(site_settings.view.getSidebarLinks())
-sitemap.addPages(site_settings.view.getDjangoURLPatterns())
+sidebar.SIDEBAR.append(site.view.getSidebarLinks())
+sitemap.addPages(site.view.getDjangoURLPatterns())
 
 sidebar.SIDEBAR.append(user.view.getSidebarLinks())
 sitemap.addPages(user.view.getDjangoURLPatterns())