Some neat and useful bits on top of FeinCMS
Python JavaScript CSS
Pull request Compare This branch is 88 commits ahead, 5 commits behind glamkit:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
feincmstools
.gitignore
AUTHORS.txt
CHANGES.txt
LICENSE.txt
README.rst
setup.cfg
setup.py

README.rst

GLAMkit-feincmstools

Wrapper around FeinCMS with many extra features.

Principally, feincmstools allows you to create FeinCMS content types, and register them to your Document models more intuitively and DRYly.

GLAMkit-feincmstools is a part of the GLAMkit framework.

A demo app is available here.

To make a FeinCMS Document:

  1. In models.py Define your model as a subclass of feincmstools.base.FeinCMSDocument (or feincmstools.base.HierarchicalFeinCMSDocument for documents you want to arrange in a tree).

If you are using HierarchicalFeinCMSDocument, you may want to mix in HierarchicalSlugField, which generates a slug value based on concatenations of the slugs of the document's parents.

from feincmstools.fields import HierarchicalSlugField
from feincmstools.base import HierarchicalFeinCMSDocument
from django.db import models

class Article(HierarchicalFeinCMSDocument, HierarchicalSlugField):
        title = models.CharField(max_length=255)
        slug = models.SlugField('slug', max_length=255, unique=True, db_index=True)

Create an admin for the model, in admin.py:

from django.contrib import admin
from feincmstools.admin import HierarchicalFeinCMSDocumentAdmin
from .models import Article

class ArticleAdmin(HierarchicalFeinCMSDocumentAdmin):
        prepopulated_fields = {"slug": ("title", )}

admin.site.register(Article, ArticleAdmin)

2) Define feincms_regions OR feincms_templates as an attribute of your model. feincms_regions is a list of region name/title tuples. feincms_templates allows different regions to be used and different templates rendered depending on user selection.

class Article(HierarchicalFeinCMSDocument, HierarchicalSlugField):
        ...

        feincms_regions = (
                ('main', 'Main'),
                ('left', 'Left sidebar'),
        )

        OR

        feincms_templates = [
                {
                        'key': 'base',
                        'title': 'Standard template',
                        'path': 'magazine/article.html',
                        'regions': (
                                ('main', 'Main content area'),
                                ('related', 'Related articles', 'inherited'),
                        ),
                }, {
                        'key': '2col',
                        'title': 'Template with two columns',
                        'path': 'magazine/article_2col.html',
                        'regions': (
                                ('col1', 'Column one'),
                                ('col2', 'Column two'),
                                ('related', 'Related articles', 'inherited'),
                        ),
                }
        ]

3) Define the classmethod content_types_by_region(region). This should return a list of which content types are allowed in which region, grouped into menu sections that appear in the admin UI. To define content types, see the next section.

class Article(HierarchicalFeinCMSDocument, HierarchicalSlugField):
        ...

        @classmethod
        def content_types_by_region(cls, region):
                standard_content_types = [
                        (None, (Text, HorizontalRule)),
                        ('Media', (OEmbedContent)), #The string 'Media' is shown in the admin menu.
                        ('Advanced', (RawHTMLContent,)),
                ]

                other_content_types = {
                        'related': [
                                (None, (RelatedArticle,)),
                        ],
                        'col2': [
                                (None, (Text,)),
                                ('Advanced', (RawHTMLContent,)),
                        ]
                }

                return other_content_types.get(region, standard_content_types)
  1. To render the FeinCMS content in the template, use something like:

    {% load feincms_tags %}
    {% feincms_render_region article "main" request %}
    

To make a FeinCMS Content Type:

FeinCMStools also provides a Content abstract model that you can use for creating FeinCMS content types. If you use feincmstools.base.Content, it looks through hierarchy of template paths, allowing you to finely control the appearance of content types in different regions and/or apps. To create a content type:

  1. In content_types.py (the filename doesn't matter, but this is a good convention), define an abstract model that subclasses Content:

    from django.db import models
    from feincmstools.base import Content
    
    class Text(Content):
                    text = models.TextField(blank=True)
    
                    class Meta:
                                    abstract=True
    
  2. Create a template to render the content at content_types/<your_app>/text/render.html in your templates folder. The template is provided with a context variable content, which is your Content model instance. You can treat it as any other Django model, e.g.:

    {{ content.text|linebreaks }}
    

render.html is the 'last-resort' template name. You can provide other templates for more specific contexts, such as for specific regions, or used by specific models. Templates are searched in this order:

content_types/[content_type_defining_app]/[content_model]/[content_type_using_app]_[content_type_using_model]_[region_name].html
content_types/[content_type_defining_app]/[content_model]/[content_type_using_model]_[region_name].html
content_types/[content_type_defining_app]/[content_model]/[region_name].html
content_types/[content_type_defining_app]/[content_model]/render.html

And for admin:

content_types/[content_type_defining_app]/[content_model]/admin_init.html

Content searches up through the model hierarchy until it finds a suitable template, so templates named after superclasses will also work.

  1. Add Text to the content_types_by_region lists, where you want it to be available.
  2. Create a schema migration for EVERY app that uses Text in its content_types_by_region. If you are confident there are no other schema changes in these apps, use manage.py feincms_models_migration, which creates automatic migrations for every feincms app.