Monday, October 6, 2014

A Mezzanine Tutorial

{% endif %} {% endblock %}
Be sure to create a blog post to test.
The changeset for all that template hacking.

Part 4: Creating New Page Types

Design Plan

Next is one of the most powerful ways to customize Mezzanine: a new content page type. The new page will be for my documentation section, which is a tree of articles and how-tos on various subjects. I plan to have a top level "Docs" page, with a few subject area pages underneath it, say "Mezzanine", "Django", "Python", etc. Underneath these pages, I'll have "leaf node" articles of content. I want the Docs and subject pages to have a clickable table of contents, after the page content.
Note: I got the hang of extending page schemas by looking at the Mezzanine Gallery model and interface. Good reading.

Creating the Model

Start by creating a new model for the page. I'm going to use the rodmtech app created previously. (You could also create and use a new app, withpython manage.py createapp newapp; if you do, be sure to add it to INSTALLED_APPS in settings.py.)
Create rodmtech/models.py and fill it with
from django.db import models
from django.utils.translation import ugettext_lazy as _
from mezzanine.pages.models import Page, RichText

class DocPage(Page, RichText):
    """
    A doc tree page
    """
    add_toc = models.BooleanField(_("Add TOC"), default=False,
                                  help_text=_("Include a list of child links"))

    class Meta:
        verbose_name = _("Doc Page")
        verbose_name_plural = _("Doc Pages")

Migrating the Database

As soon as this file is saved, the Django ORM will be out of sync with our database. The site should work, but the admin won't, at least not the Pages section of the admin, until we get things back in sync. Would could use python manage.py syncdb, but instead get used to using South.
I highly recommend mastering South if you plan any Django projects that will evolve over time. Or, figure out a better way to do what South does. I'm not being facetious here, there are other apps, including some home grown solutions that work quite well. Here's a good article on schema change management.
The django-south incantation is
python manage.py schemamigration rodmtech --initial
python manage.py migrate rodmtech

Extend the Admin Site

Now the admin doesn't know about our new DocToc page type. Create rodmtech/admin.py and fill with
from django.contrib import admin
from mezzanine.pages.admin import PageAdmin
from .models import DocPage

admin.site.register(DocPage, PageAdmin)
For a good example of extending the admin for a richer page type, see the galleries app in Mezzanine, i.e.,site-packages/mezzanine/galleries/admin.py.
After adding a new admin.py, you'll need to exit the dev server, ^C out of manage.py runserver, and python manage.py runserver again. (Now why does the new rodmtech/admin.py require a restart? Afaict, Django looks for app/admin.py files at startup, to build it's admin site dynamically. If you change one that was already there, ok, "runserver" sees that and reloads. But a whole new admin.py file? Django doesn't catch that.)
Go back to the Pages section of the admin, refresh it if you're already there, and you should see "Doc Page" in the Add dropdown.

A Custom Template for DocPages

Time for the DocPage template. Remember the Mezzanine template finding rules for models inherited from Page: http://mezzanine.jupo.org/docs/content-architecture.html#page-templates. We'll want a templates/pages/docpage.html. I'm going to use a hierarchical list template already in Mezzanine for my markup, namely templates/pages/menus/footer_tree.html. My docpage.html looks like
{% extends "pages/page.html" %}

{% load pages_tags mezzanine_tags %}

{% block main %}{{ block.super }}

{% editable page.docpage.content %}
{{ page.docpage.content|richtext_filters|safe }}
{% endeditable %}


{% if page.docpage.add_toc %}

class="container"> {% page_menu "pages/menus/footer_tree.html" page %}
{% endif %} {% endblock %}
Now, the only thing missing are some DocPage pages. In the admin, create a new top level DocPage with the "Add TOC" checkbox checked. Add some additional pages underneath, and test your work.
And, the final changeset for this tutorial.

That's a Wrap

It this point, you should have built a site awfully close to the one you're browsing...at least as it was when this was written. All of the work described here is also in a Bitbucket Mercurial repo, rmorison/rodmtech_net.
Thanks for following along. Questions, comments, complaints are welcome.

No comments:

Post a Comment