Thomas
Thomas

Reputation: 63

How to implement django-fluent-contents to Mezzanine existing project

I have existing Mezzanine project with existing pages. It is possible to implement to AdminPage fluent-contents feature without fluent-pages feature? Just want to Mezzanine Page creation as it is but with fluent-contents in it. Is this possible to implement? Can anybody show some example how to implement it to Mezzanine AdminPage.

Upvotes: 3

Views: 437

Answers (1)

Thomas
Thomas

Reputation: 63

Since nobody had this problem and I already figure it out and successfully implement Fluent-contents to existing Mezzanine project. It is very simple but investigation takes edit core sources of mezzanine cms. After all output solution was simple app that extending Mezzanine Pages as in Admin or Client side.

(DIFFICULTY: medium/expert)

SOLUTION:

(for this example I had used app with name "cms_coremodul") PS: It was made with ver. Python 3.4 with virtual environment.

MEZZANINE SETUP AND INSTALLS:

-version of Mezzanine 4.0.1

-install fluent-contents with desired plugins what you need (follow fluent-contents docs).

pip install django-fluent-contents

-also you can optionally install powerfull wysiwyg CKEditor.

pip install django-ckeditor

-after you have all installed lets go to setup settings.py and migrate everything up.

settings.py :

-fluent-contents have to be above of your app and below of Mezzanine apps.

INSTALLED_APPS = (
    ...
    "fluent_contents",
    "django_wysiwyg",
    "ckeditor",
    # all working fluent-contents plugins
    'fluent_contents.plugins.text',                # requires django-wysiwyg
    'fluent_contents.plugins.code',                # requires pygments
    'fluent_contents.plugins.gist',
    'fluent_contents.plugins.iframe',
    'fluent_contents.plugins.markup',
    'fluent_contents.plugins.rawhtml',
    'fluent_contents.plugins.picture',
    'fluent_contents.plugins.oembeditem',
    'fluent_contents.plugins.sharedcontent',
    'fluent_contents.plugins.googledocsviewer',
    ...
    'here_will_be_your_app',
)

-settings for django-ckeditor:

settings.py :

# CORE MODUL DEFAULT WYSIWYG EDITOR SETUP
RICHTEXT_WIDGET_CLASS = "ckeditor.widgets.CKEditorWidget"
RICHTEXT_FILTER_LEVEL = 3
DJANGO_WYSIWYG_FLAVOR = "ckeditor"

# CKEditor config
CKEDITOR_CONFIGS = {
    'awesome_ckeditor': {
        'toolbar': 'Full',
    },
    'default': {
        'toolbar': 'Standard',
        'width': '100%',
    },         
}

-after setup of settings.py of fluent-contents is complete lets migrate everything up:

python manage.py migrate

-if there will be any error/fault about dependencies of fluent-contents, install that dependency and migrate again.

CREATE NEW APP FOR FLUENT-CONTENTS:

  • Create an new app in Mezzanine project (same as in Django):

    python manage.py startapp nameofyourapp

models.py :

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
from mezzanine.pages.models import Page
from django.utils.translation import ugettext_lazy as _
from fluent_contents.models import PlaceholderRelation, ContentItemRelation
from mezzanine.core.fields import FileField
from . import appconfig

class CoreModulPage(Page):

    template_name = models.CharField("Template choice", max_length=255, choices=appconfig.TEMPLATE_CHOICES, default=appconfig.COREMODUL_DEFAULT_TEMPLATE)

    # Accessing the data of django-fluent-contents
    placeholder_set = PlaceholderRelation()
    contentitem_set = ContentItemRelation()

    class Meta:
        verbose_name = _("Core page")
        verbose_name_plural = _("Core pages")

admin.py :

from django.contrib import admin
from django.http.response import HttpResponse
from mezzanine.pages.admin import PageAdmin

import json

# CORE MODUL IMPORT
from fluent_contents.admin import PlaceholderEditorAdmin
from fluent_contents.analyzer import get_template_placeholder_data
from django.template.loader import get_template
from .models import CoreModulPage
from . import appconfig
from fluent_contents.admin.placeholdereditor import PlaceholderEditorInline

class CoreModulAdmin(PlaceholderEditorAdmin, PageAdmin):

    #################################
    #CORE MODUL - PAGE LOGIC
    #################################
    corepage = CoreModulPage.objects.all()
    # CORE FLUENT-CONTENTS
    # This is where the magic happens.
    # Tell the base class which tabs to create
    def get_placeholder_data(self, request, obj):
        # Tell the base class which tabs to create
        template = self.get_page_template(obj)
        return get_template_placeholder_data(template)

    def get_page_template(self, obj):
        # Simple example that uses the template selected for the page.
        if not obj:
            return get_template(appconfig.COREMODUL_DEFAULT_TEMPLATE)
        else:
            return get_template(obj.template_name or appconfig.COREMODUL_DEFAULT_TEMPLATE)

    # Allow template layout changes in the client,
    # showing more power of the JavaScript engine.

    # THIS LINES ARE OPTIONAL
    # It sets your own path to admin templates and static of fluent-contents
    #
    # START OPTIONAL LINES
    # this "PlaceholderEditorInline.template" is in templates folder of your app
    PlaceholderEditorInline.template = "cms_plugins/cms_coremodul/admin/placeholder/inline_tabs.html"
    # this "PlaceholderEditorInline.Media.js"
    # and "PlaceholderEditorInline.Media.css" is in static folder of your app
    PlaceholderEditorInline.Media.js = (
            'cms_plugins/cms_coremodul/admin/js/jquery.cookie.js',
            'cms_plugins/cms_coremodul/admin/js/cp_admin.js',
            'cms_plugins/cms_coremodul/admin/js/cp_data.js',
            'cms_plugins/cms_coremodul/admin/js/cp_tabs.js',
            'cms_plugins/cms_coremodul/admin/js/cp_plugins.js',
            'cms_plugins/cms_coremodul/admin/js/cp_widgets.js',
            'cms_plugins/cms_coremodul/admin/js/fluent_contents.js',
        )

    PlaceholderEditorInline.Media.css = {
            'screen': (
                'cms_plugins/cms_coremodul/admin/css/cp_admin.css',
            ),
        }

    PlaceholderEditorInline.extend = False   # No need for the standard 'admin/js/inlines.min.js' here.
    #
    # END OPTIONAL LINES

    # template to change rendering template for contents (combobox in page to choose desired template to render)
    change_form_template = "cms_plugins/cms_coremodul/admin/page/change_form.html"

    class Media:
        js = (
            'cms_plugins/cms_coremodul/admin/js/coremodul_layouts.js',
        )



    def get_layout_view(self, request):
        """
        Return the metadata about a layout
        """
        template_name = request.GET['name']

        # Check if template is allowed, avoid parsing random templates
        templates = dict(appconfig.TEMPLATE_CHOICES)
        if not templates.has_key(template_name):
            jsondata = {'success': False, 'error': 'Template was not found!'}
            status = 404
        else:
            # Extract placeholders from the template, and pass to the client.
            template = get_template(template_name)
            placeholders = get_template_placeholder_data(template)

            jsondata = {
                'placeholders': [p.as_dict() for p in placeholders],
            }
            status = 200

        jsonstr = json.dumps(jsondata)
        return HttpResponse(jsonstr, content_type='application/json', status=status)


admin.site.register(CoreModulPage, CoreModulAdmin)

appconfig.py :

-you have to create new appconfig.py file in your app.

from django.conf import settings
from django.core.exceptions import ImproperlyConfigured


TEMPLATE_CHOICES = getattr(settings, "TEMPLATE_CHOICES", ())
COREMODUL_DEFAULT_TEMPLATE = getattr(settings, "COREMODUL_DEFAULT_TEMPLATE", TEMPLATE_CHOICES[0][0] if TEMPLATE_CHOICES else None)


if not TEMPLATE_CHOICES:
    raise ImproperlyConfigured("Value of variable 'TEMPLATE_CHOICES' is not set!")

if not COREMODUL_DEFAULT_TEMPLATE:
    raise ImproperlyConfigured("Value of variable 'COREMODUL_DEFAULT_TEMPLATE' is not set!")

settings.py : -this lines add to settings.py of your Mezzanine project.

# CORE MODUL TEMPLATE LIST
TEMPLATE_CHOICES = (
    ("pages/coremodulpage.html", "CoreModulPage"),
    ("pages/coremodulpagetwo.html", "CoreModulPage2"),
)

# CORE MODUL default template setup (if drop-down not exist in admin interface)
COREMODUL_DEFAULT_TEMPLATE = TEMPLATE_CHOICES[0][0]

-append your app to INSTALLED_APPS (add your app to INSTALLED_APPS).

INSTALLED_APPS = (
    ...
    "yourappname_with_fluentcontents",
)

create templates for your contents of your app:

-template with one placeholder:

coremodulpage.html:

{% extends "pages/page.html" %}
{% load mezzanine_tags fluent_contents_tags %}

{% block main %}{{ block.super }}
{% page_placeholder page.coremodulpage "main" role='m' %}
{% endblock %}

-template with two placeholders (one aside):

{% extends "pages/page.html" %}
{% load mezzanine_tags fluent_contents_tags %}

{% block main %}{{ block.super }}
{% page_placeholder page.coremodulpage "main" role='m' %}
<aside>
    {% page_placeholder page.coremodulpage "sidepanel" role='s' %}
</aside>
{% endblock %}

-after your app is setup lets make migrations:

-1.Make migration of your app:

python manage.py makemigrations yourappname

-2.Make migration of your app to database:

python manage.py migrate

FINALLY COMPLETE! - try your new type of Admin Page with Fluent-contents plugin installed. - In dropdown with Page type in Admin select Core Page. If you had create template for render of fluent-contents tab with placeholders shows with dropdown in it. Now you can select desired plugin and create your modular content of your page.

Upvotes: 2

Related Questions