Package: django-fluent-pages
This project has reached the end of its development as CMS framework.It only receives low maintenance to continue running existing websites.Feel free to browse the code, but please use other Django-based CMS frameworks such asWagtail CMSwhen you start a new project.django-fluent-pagesThis is a stand-alone module, which provides a flexible,
scalable CMS with custom node types, and flexible block content.Features:A fully customizable page hierarchy.Support for multilingual websites.Support for multiple websites in a single database.Fast SEO-friendly page URLs.SEO optimized (meta keywords, description, title, 301-redirects, sitemaps integration).Plugin support for custom page types, which:Integrate application logic in page trees.Integrate advanced block editing (via asdjango-fluent-contents).For more details, see thedocumentationat Read The Docs.Page tree customizationThis module provides a page tree, where each node type can be a different model.
This allows developers like yourself to structure your site tree as you see fit. For example:Build a tree structure of RST pages, by defining aRstPagetype.Build a tree with widget-based pages, by integratingdjango-fluent-contents.Build a “product page”, which exposes all products as sub nodes.Build a tree of ahomepage,subsection, andarticlenode, each with custom fields like professional CMSes have.Each node type can have it’s own custom fields, attributes and rendering.In case you’re building a custom CMS, this module might just be suited for you,
since it provides the tree for you, without bothering with anything else.
The actual page contents is defined via page type plugins.InstallationFirst install the module, preferably in a virtual environment:pipinstalldjango-fluent-pagesAll dependencies will be automatically installed.ConfigurationYou can also use the ready-made template:mkdirmy-website.comcdmy-website.comdjango-admin.pystartprojectmywebsite.-epy,rst,example,gitignore--template=https://github.com/edoburu/django-project-template/archive/django-fluent.zipOr create a new project:cd..django-admin.pystartprojectfluentdemoTo have a standard setup withdjango-fluent-contentsintegrated, use:INSTALLED_APPS+=(# The CMS apps'fluent_pages',# Required dependencies'mptt','parler','polymorphic','polymorphic_tree','slug_preview',# Optional widget pages via django-fluent-contents'fluent_pages.pagetypes.fluentpage','fluent_contents','fluent_contents.plugins.text','django_wysiwyg',# Optional other CMS page types'fluent_pages.pagetypes.redirectnode',# enable the admin'django.contrib.admin',)DJANGO_WYSIWYG_FLAVOR="yui_advanced"Note each CMS application is optional. Onlyfluent_pagesandmpttare required.
The remaining apps add additional functionality to the system.Inurls.py:urlpatterns+=patterns('',url(r'',include('fluent_pages.urls')))The database can be created afterwards:./manage.pymigrate./manage.pyrunserverCustom page typesThe key feature of this module is the support for custom node types.
Take a look in the existing types atfluent_pages.pagetypesto see how it’s being done.It boils down to creating a package with 2 files:Themodels.pyfile should define the custom node type, and any fields it has:fromdjango.dbimportmodelsfromdjango.utils.translationimportugettext_lazyas_fromfluent_pages.modelsimportHtmlPagefrommysite.settingsimportRST_TEMPLATE_CHOICESclassRstPage(HtmlPage):"""
    A page that renders RST code.
    """rst_content=models.TextField(_("RST contents"))template=models.CharField(_("Template"),max_length=200,choices=RST_TEMPLATE_CHOICES)classMeta:verbose_name=_("RST page")verbose_name_plural=_("RST pages")Apage_type_plugins.pyfile that defines the metadata, and rendering:fromfluent_pages.extensionsimportPageTypePlugin,page_type_poolfrom.modelsimportRstPage@page_type_pool.registerclassRstPagePlugin(PageTypePlugin):model=RstPagesort_priority=10defget_render_template(self,request,rstpage,**kwargs):returnrstpage.templateA template could look like:{%extends"base.html"%}{%loadmarkup%}{%blockheadtitle%}{{page.title}}{%endblock%}{%blockmain%}<h1>{{page.title}}</h1><divid="content">{{page.rst_content|restructuredtext}}</div>{%endblock%}Et, voila: with very little code a custom CMS was just created.Optionally, amodel_admincan also be defined, to have custom field layouts or extra functionality in theeditordeletepage.Plugin configurationThe plugin can define the following attributes:model- the model for the page typemodel_admin- the custom admin to use (must inherit fromPageAdmin)render_template- the template to use for renderingresponse_class- the response class (by defaultTemplateResponse)is_file- whether the node represents a file, and shouldn’t end with a slash.can_have_children- whether the node type is allowed to have child nodes.urls- a custom set of URL patterns for sub pages (either a module name, orpatterns()result).sort_priority- a sorting order in the “add page” dialog.It can also override the following functions:get_response(self, request, page, **kwargs)- completely redefine the response, instead of usingresponse_class,render_template, etc..get_render_template(self, request, page, **kwargs)- return the template to render, by default this isrender_template.get_context(self, request, page, **kwargs)- return the template context for the node.Details about these attributes is explained in thedocumentation.Application nodesAs briefly mentioned above, a page type can have it’s own set of URL patterns, via theurlsattribute.
This allows implementing page types such as a “product page” in the tree,
which automatically has all products from the database as sub pages.
The providesexamplemodule demonstrates this concept.The URL patterns start at the full path of the page, so it works similar to a regularinclude()in the URLconf.
However, a page type may be added multiple times to the tree.
To resolve the URLs, there are 2 functions available:fluent_pages.urlresolvers.app_reverse()- thisreverse()like function locates a view attached to a page.fluent_pages.urlresolvers.mixed_reverse()- this resolver triesapp_reverse()first, and falls back to the standardreverse().Themixed_reverse()is useful for third party applications which
can operate either stand-alone (mounted in the normal URLconf),
or operate as page type node in combination withdjango-fluent-pages.
These features are also used bydjango-fluent-blogsto provide a “Blog” page type
that can be added to a random point of the tree.Adding pages to the sitemapOptionally, the pages can be included in the sitemap.
Add the following inurls.py:fromfluent_pages.sitemapsimportPageSitemapsitemaps={'pages':PageSitemap,}urlpatterns+=patterns('',url(r'^sitemap.xml$','django.contrib.sitemaps.views.sitemap',{'sitemaps':sitemaps}),)ContributingThis module is designed to be generic. In case there is anything you didn’t like about it,
or think it’s not flexible enough, please let us know. We’d love to improve it!If you have any other valuable contribution, suggestion or idea,
please let us know as well because we will look into it.
Pull requests are welcome too. :-)