Added a 'getting started' tutorial and a short intro to philo page to the docs. Impro...
authorStephen Burrows <stephen.r.burrows@gmail.com>
Tue, 31 May 2011 16:02:29 +0000 (12:02 -0400)
committerStephen Burrows <stephen.r.burrows@gmail.com>
Tue, 31 May 2011 16:02:29 +0000 (12:02 -0400)
docs/index.rst
docs/intro.rst [deleted file]
docs/tutorials/getting-started.rst [new file with mode: 0644]
docs/tutorials/intro.rst [new file with mode: 0644]
docs/what.rst [new file with mode: 0644]
philo/models/base.py

index 666e3ee..079185d 100644 (file)
@@ -8,12 +8,27 @@
 Welcome to Philo's documentation!
 =================================
 
-Contents:
+Philo is a foundation for developing web content management systems.
+
+Prerequisites:
+
+* `Python 2.5.4+ <http://www.python.org>`_
+* `Django 1.2+ <http://www.djangoproject.com/>`_
+* `django-mptt e734079+ <https://github.com/django-mptt/django-mptt/>`_
+* (Optional) `django-grappelli 2.0+ <http://code.google.com/p/django-grappelli/>`_
+* (Optional) `south 0.7.2+ <http://south.aeracode.org/>`_
+* (Optional) `recaptcha-django r6 <http://code.google.com/p/recaptcha-django/>`_
+
+To contribute, please visit the `project website <http://philocms.org/>`_ or make a fork of the git repository on `GitHub <http://github.com/ithinksw/philo>`_ or `Gitorious <http://gitorious.org/ithinksw/philo>`_. Feel free to join us on IRC at `irc://irc.oftc.net/#philo <irc://irc.oftc.net/#philo>`_.
+
+Contents
+++++++++
 
 .. toctree::
-       :maxdepth: 2
+       :maxdepth: 1
        
-       intro
+       what
+       tutorials/intro
        models/intro
        exceptions
        handling_requests
@@ -26,24 +41,8 @@ Contents:
        contrib/intro
 
 Indices and tables
-==================
+++++++++++++++++++
 
 * :ref:`genindex`
 * :ref:`modindex`
 * :ref:`search`
-
-What is Philo?
-==============
-
-Philo is a foundation for developing web content management systems.
-
-Prerequisites:
-
-* `Python 2.5.4+ <http://www.python.org>`_
-* `Django 1.2+ <http://www.djangoproject.com/>`_
-* `django-mptt e734079+ <https://github.com/django-mptt/django-mptt/>`_
-* (Optional) `django-grappelli 2.0+ <http://code.google.com/p/django-grappelli/>`_
-* (Optional) `south 0.7.2+ <http://south.aeracode.org/>`_
-* (Optional) `recaptcha-django r6 <http://code.google.com/p/recaptcha-django/>`_
-
-To contribute, please visit the `project website <http://philocms.org/>`_ or make a fork of the git repository on `GitHub <http://github.com/ithinksw/philo>`_ or `Gitorious <http://gitorious.org/ithinksw/philo>`_. Feel free to join us on IRC at `irc://irc.oftc.net/#philo <irc://irc.oftc.net/#philo>`_.
diff --git a/docs/intro.rst b/docs/intro.rst
deleted file mode 100644 (file)
index 2b253db..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-How to get started with philo
-=============================
-
-After installing `philo`_ and `mptt`_ on your python path, make sure to complete the following steps:
-
-1. add :mod:`philo` and :mod:`mptt` to :setting:`settings.INSTALLED_APPS`::
-       
-       INSTALLED_APPS = (
-               ...
-               'philo',
-               'mptt',
-               ...
-       )
-       
-2. add :class:`philo.middleware.RequestNodeMiddleware` to :setting:`settings.MIDDLEWARE_CLASSES`::
-       
-       MIDDLEWARE_CLASSES = (
-               ...
-               'philo.middleware.RequestNodeMiddleware',
-               ...
-       )
-       
-3. include :mod:`philo.urls` somewhere in your urls.py file. For example::
-       
-       from django.conf.urls.defaults import patterns, include, url
-       urlpatterns = patterns('',
-               url(r'^', include('philo.urls')),
-       )
-       
-4. Optionally add a root :class:`node <philo.models.Node>` to your current :class:`Site` in the admin interface.
-
-Philo should be ready to go!
-
-.. _philo: http://philocms.org/
-.. _mptt: http://github.com/django-mptt/django-mptt
diff --git a/docs/tutorials/getting-started.rst b/docs/tutorials/getting-started.rst
new file mode 100644 (file)
index 0000000..eeb9ce8
--- /dev/null
@@ -0,0 +1,87 @@
+Getting started with philo
+==========================
+
+.. note:: This guide assumes that you have worked with Django's built-in administrative interface.
+
+Once you've installed `philo`_ and `mptt`_ to your python path, there are only a few things that you need to do to get :mod:`philo` working.
+
+1. Add :mod:`philo` and :mod:`mptt` to :setting:`settings.INSTALLED_APPS`::
+               
+       INSTALLED_APPS = (
+               ...
+               'philo',
+               'mptt',
+               ...
+       )
+
+2. Syncdb or run migrations to set up your database.
+       
+3. Add :class:`philo.middleware.RequestNodeMiddleware` to :setting:`settings.MIDDLEWARE_CLASSES`::
+       
+       MIDDLEWARE_CLASSES = (
+               ...
+               'philo.middleware.RequestNodeMiddleware',
+               ...
+       )
+       
+4. Include :mod:`philo.urls` somewhere in your urls.py file. For example::
+       
+       from django.conf.urls.defaults import patterns, include, url
+       urlpatterns = patterns('',
+               url(r'^', include('philo.urls')),
+       )
+
+Philo should be ready to go! (Almost.)
+
+.. _philo: http://philocms.org/
+.. _mptt: http://github.com/django-mptt/django-mptt
+
+Hello world
++++++++++++
+
+Now that you've got everything configured, it's time to set up your first page! Easy peasy. Open up the admin and add a new :class:`.Template`. Call it "Hello World Template". The code can be something like this::
+       
+       <html>
+               <head>
+                       <title>Hello world!</title>
+               </head>
+               <body>
+                       <p>Hello world!</p>
+                       <p>The time is {% now %}.</p>
+               </body>
+       </html>
+
+Next, add a philo :class:`.Page` - let's call it "Hello World Page" and use the template you just made.
+
+Now make a philo :class:`.Node`. Give it the slug ``hello-world``. Set the view content type to "Page" and use the page that you just made. If you navigate to ``/hello-world``, you will see the results of rendering the page!
+
+Setting the root node
++++++++++++++++++++++
+
+So what's at ``/``? If you try to load it, you'll get a 404 error. This is because there's no :class:`.Node` located there - and since :attr:`.Node.slug` is a required field, getting a node there is not as simple as leaving the :attr:`.~Node.slug` blank.
+
+In :mod:`philo`, the node that is displayed at ``/`` is called the "root node" of the current :class:`Site`. To represent this idea cleanly in the database, :mod:`philo` adds a :class:`ForeignKey` to :class:`.Node` to the :class:`django.contrib.sites.models.Site` model.
+
+Since there's only one :class:`.Node` in your :class:`Site`, we probably want ``hello-world`` to be the root node. All you have to do is edit the current :class:`Site` and set its root node to ``hello-world``. Now you can see the page rendered at ``/``!
+
+Editing page contents
++++++++++++++++++++++
+
+Great! We've got a page that says "Hello World". But what if we want it to say something else? Should we really have to edit the :class:`.Template` to change the content of the :class:`.Page`? And what if we want to share the :class:`.Template` but have different content? Adjust the :class:`.Template` to look like this::
+       
+       <html>
+               <head>
+                       <title>{% container page_title %}</title>
+               </head>
+               <body>
+                       {% container page_body as content %}
+                       {% if content %}
+                               <p>{{ content }}</p>
+                       {% endif %}
+                       <p>The time is {% now %}.</p>
+               </body>
+       </html>
+
+Now go edit your :class:`.Page`. Two new fields called "Page title" and "Page body" have shown up! You can put anything you like in here and have it show up in the appropriate places when the page is rendered.
+
+.. seealso:: :ttag:`philo.templatetags.containers.container`
diff --git a/docs/tutorials/intro.rst b/docs/tutorials/intro.rst
new file mode 100644 (file)
index 0000000..903dfea
--- /dev/null
@@ -0,0 +1,7 @@
+Tutorials
+=========
+
+.. toctree::
+       :maxdepth: 1
+       
+       getting-started
diff --git a/docs/what.rst b/docs/what.rst
new file mode 100644 (file)
index 0000000..ac44619
--- /dev/null
@@ -0,0 +1,11 @@
+What is Philo, anyway?
+======================
+
+Philo allows the creation of site structures using Django's built-in admin interface. Like Django, Philo separates URL structure from backend code from display:
+
+* :class:`.Node`\ s represent the URL hierarchy of the website.
+* :class:`.View`\ s contain the logic for each :class:`.Node`, as simple as a :class:`.Redirect` or as complex as a :class:`.Blog`.
+* :class:`.Page`\ s (the most commonly used :class:`.View`) render whatever context they are passed using database-driven :class:`.Template`\ s written with Django's template language.
+* :class:`.Attribute`\ s are arbitrary key/value pairs which can be attached to most of the models that Philo provides. Attributes of a :class:`.Node` will be inherited by all of the :class:`.Node`'s descendants and will be available in the template's context.
+
+The :ttag:`~philo.templatetags.containers.container` template tag that Philo provides makes it easy to mark areas in a template which need to be editable page-by-page; every :class:`.Page` will have an additional field in the admin for each :ttag:`~philo.templatetags.containers.container` in the template it uses.
index 02d8456..9ba1ff6 100644 (file)
@@ -100,7 +100,7 @@ class AttributeValue(models.Model):
                abstract = True
 
 
-#: An instance of :class:`ContentTypeSubclassLimiter` which is used to track the content types which are considered valid value models for an :class:`Attribute`.
+#: An instance of :class:`.ContentTypeSubclassLimiter` which is used to track the content types which are considered valid value models for an :class:`Attribute`.
 attribute_value_limiter = ContentTypeSubclassLimiter(AttributeValue)
 
 
@@ -246,7 +246,12 @@ class ManyToManyValue(AttributeValue):
 
 
 class Attribute(models.Model):
-       """Represents an arbitrary key/value pair on an arbitrary :class:`Model` where the key consists of word characters and the value is a subclass of :class:`AttributeValue`."""
+       """
+       :class:`Attribute`\ s exist primarily to let arbitrary data be attached to arbitrary model instances without altering the database schema and without guaranteeing that the data will be available on every instance of that model.
+       
+       Generally, :class:`Attribute`\ s will not be accessed as models; instead, they will be accessed through the :attr:`Entity.attributes` property, which allows direct dictionary getting and setting of the value of an :class:`Attribute` with its key.
+       
+       """
        entity_content_type = models.ForeignKey(ContentType, related_name='attribute_entity_set', verbose_name='Entity type')
        entity_object_id = models.PositiveIntegerField(verbose_name='Entity ID', db_index=True)