Integrating Fluent Contents  into Mezzanine

Stuart Dines
Team Leader / Senior Software Engineer @ The Interaction Consortium  http://interaction.net.au/

Senior Software Engineer @ Stockspot http://stockspot.com.au

@sjdines

 http://stuartdines.com

28th of January 2016

Background

  • Mezzanine
    • A content management platform that provides a simple yet highly extensible architecture.
    • The Page model in Mezzanine is the foundation of a site.
    • Most customisations will inherit from the Page model.
    • http://mezzanine.jupo.org/
  • Fluent Contents
    • Fluent Contents offers a widget engine to display various content on a page built in Django.
    • https://github.com/edoburu/django-fluent-contents

Combining Mezzanine and Fluent Contents

  • Why the need?
    • Allows specific content / data validation without requiring all fields set up on the model type
    • Allows different templates to be used with varying content requirements
    • Allows reusable content systems (built on content plugins)
    • Allows all the benefits of Mezzanine!
    • Speak to me after for more reasons why I like this combination

Combining Mezzanine and Fluent Contents

  • Yeah but how do I actually integrate the two?
    • I had the need and have made the solution available at :
      • https://github.com/sjdines/mezzanine-fluent-pages
    • Follow these steps:
# To install mezzanine_fluent_pages (after Mezzanine has been installed) run:

$ pip install -e git+ssh://git@github.com/sjdines/mezzanine-fluent-pages#egg=mezzanine-fluent-pages

# Then add the page type(s) you wish to INSTALLED_APPS:

INSTALLED_APPS += (
    'mezzanine_fluent_pages.mezzanine_page',
    'mezzanine_fluent_pages.mezzanine_layout_page',
    'django_wysiwyg',
    'fluent_contents',
    'fluent_contents.plugins.text',
)

# Define the location of MEZZANINE_PAGES_TEMPLATE_DIR.

MEZZANINE_PAGES_TEMPLATE_DIR = os.path.join(PROJECT_ROOT, "<project name>", "templates")

# Create a folder named `templates` in your project folder. If you choose to use the layout system all your
# layouts will need to go in this folder.

$ mkdir <project name>/templates

# Run migrations:

$ python manage.py migrate

Constructing `mezzanine_page`

  • `mezzanine_page` was an initial attempt at integrating the two systems
  • The initial step was to subclass the Mezzanine default `Page` type and add the `PlaceholderField` descriptor
  • The Mezzanine `Page` type requires  the `get_template_name` method defining where the template is (which is also created)
from fluent_contents.models import PlaceholderField
from mezzanine.pages.models import Page


class FluentContentsPage(Page):
    """
    A mezzanine `Page` type with fluent contents.
    """
    content = PlaceholderField('mezzanine_page_content')

    def get_template_name(self):
        """
        Obtain the template to use for front end rendering.
        :return: String of template location.
        """
        return 'fluent_mezzanine/fluent_contents_page.html'

Constructing `mezzanine_page`

  • Mezzanine requires functionality from the `PageAdmin` administration definition and Fluent Contents requires `PlaceholderFieldAdmin` functions to allow the descriptor to work correctly
  • Fieldsets also need to be redefined to add the `content` field (which correlates to the descriptor name on the model) as they are previously set on the `PageAdmin` class
from django.contrib import admin
from fluent_contents.admin import PlaceholderFieldAdmin
from mezzanine.pages.admin import PageAdmin

from . import models


class FluentContentsPageAdmin(PlaceholderFieldAdmin, PageAdmin):
    """
    Admin definition for `FluentContentsPage`.
    """
    fieldsets = PageAdmin.fieldsets + (
        (
            None,
            {
                'fields': ['content', ]
            }
        ),
    )

admin.site.register(models.FluentContentsPage, FluentContentsPageAdmin)

Constructing `mezzanine_page`

  • In the template we can either extend another template or create a new one
  • We need to load `fluent_contents_tags` and use the `render_placeholder` template tag to render our specified content
  • We need to ensure the field passed to `render_placeholder` is the descriptor
    • As Mezzanine uses polymorphism we need to get the actual model instance (`page.get_content_model`) before we refer to the descriptor

{% extends 'base.html' %}

{% load fluent_contents_tags %}

{% block main %}
	{% render_placeholder page.get_content_model.content %}
{% endblock %}

Constructing `mezzanine_layout_page`

  • `mezzanine_layout_page` incorporates a layout system which lets you define multiple templates to use
  • Most of the structure was taken from Fluent Pages where a layout system was already created and  tweaked for use with Mezzanine
  • Fluent Pages was not sub-classed for use as it adds several dependencies which are not required for this implementation
  • If you want more information regarding specifics please speak to me after

The Future of `mezzanine_fluent_pages`

  • PyPI releases!
    • I have not got to this yet....
  • Better documentation
    • The usual eternal state of documentation
    • There is not enough of it and the quality could be better
  • Cartridge page implementations
  • Working with Fluent Pages and abstracting out common code
  • Welcome for any other ideas, contribution or comments!

Let's do it!

Demonstrate setting up a project

Massive Thanks

Massive thanks have to go to:

  •  Mezzanine core team
    • Stephen McDonald
    • Josh Cartmell
    • Ken Bolton
    • Alex Hill
    • Eduardo RivasMathias Ettinger
  • Edborou
    • Diederik van der Boor
  • Contributors to each project

Questions?

Stuart Dines
Team Leader / Senior Software Engineer @ The Interaction Consortium  http://interaction.net.au/

Senior Software Engineer @ Stockspot http://stockspot.com.au

@sjdines

 http://stuartdines.com

Integrating Fluent Contents (https://github.com/edoburu/django-fluent-contents) into Mezzanine (http://mezzanine.jupo.org)

By Stu Dines

Integrating Fluent Contents (https://github.com/edoburu/django-fluent-contents) into Mezzanine (http://mezzanine.jupo.org)

  • 1,196