Merge pull request #300 from fsbraun/feature/by-plugin-template

Feature-add: allow by-plugin definition of template folder (Issue #295)
This commit is contained in:
Iacopo Spalletti 2016-07-08 07:56:26 +02:00 committed by GitHub
commit d72270d87d
7 changed files with 95 additions and 12 deletions

View file

@ -18,9 +18,13 @@ class BlogPlugin(CMSPluginBase):
def get_render_template(self, context, instance, placeholder): def get_render_template(self, context, instance, placeholder):
if instance.app_config and instance.app_config.template_prefix: if instance.app_config and instance.app_config.template_prefix:
return os.path.join(instance.app_config.template_prefix, self.base_render_template) return os.path.join(instance.app_config.template_prefix,
instance.template_folder,
self.base_render_template)
else: else:
return os.path.join('djangocms_blog', self.base_render_template) return os.path.join('djangocms_blog',
instance.template_folder,
self.base_render_template)
class BlogLatestEntriesPlugin(BlogPlugin): class BlogLatestEntriesPlugin(BlogPlugin):
@ -32,9 +36,10 @@ class BlogLatestEntriesPlugin(BlogPlugin):
model = LatestPostsPlugin model = LatestPostsPlugin
form = LatestEntriesForm form = LatestEntriesForm
filter_horizontal = ('categories',) filter_horizontal = ('categories',)
fields = ('app_config', 'latest_posts', 'tags', 'categories') fields = ['app_config', 'latest_posts', 'tags', 'categories'] + \
['template_folder'] if len(get_setting('PLUGIN_TEMPLATE_FOLDERS')) > 1 else []
cache = False cache = False
base_render_template = 'plugins/latest_entries.html' base_render_template = 'latest_entries.html'
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogLatestEntriesPlugin, self).render(context, instance, placeholder) context = super(BlogLatestEntriesPlugin, self).render(context, instance, placeholder)
@ -51,8 +56,9 @@ class BlogLatestEntriesPluginCached(BlogPlugin):
model = LatestPostsPlugin model = LatestPostsPlugin
form = LatestEntriesForm form = LatestEntriesForm
filter_horizontal = ('categories',) filter_horizontal = ('categories',)
fields = ('app_config', 'latest_posts', 'tags', 'categories') fields = ['app_config', 'latest_posts', 'tags', 'categories'] + \
base_render_template = 'plugins/latest_entries.html' ['template_folder'] if len(get_setting('PLUGIN_TEMPLATE_FOLDERS')) > 1 else []
base_render_template = 'latest_entries.html'
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogLatestEntriesPluginCached, self).render(context, instance, placeholder) context = super(BlogLatestEntriesPluginCached, self).render(context, instance, placeholder)
@ -65,8 +71,9 @@ class BlogAuthorPostsPlugin(BlogPlugin):
module = get_setting('PLUGIN_MODULE_NAME') module = get_setting('PLUGIN_MODULE_NAME')
name = get_setting('AUTHOR_POSTS_PLUGIN_NAME') name = get_setting('AUTHOR_POSTS_PLUGIN_NAME')
model = AuthorEntriesPlugin model = AuthorEntriesPlugin
base_render_template = 'plugins/authors.html' base_render_template = 'authors.html'
filter_horizontal = ['authors'] filter_horizontal = ['authors']
exclude = ['template_folder'] if len(get_setting('PLUGIN_TEMPLATE_FOLDERS')) >= 1 else []
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogAuthorPostsPlugin, self).render(context, instance, placeholder) context = super(BlogAuthorPostsPlugin, self).render(context, instance, placeholder)
@ -78,7 +85,8 @@ class BlogTagsPlugin(BlogPlugin):
module = get_setting('PLUGIN_MODULE_NAME') module = get_setting('PLUGIN_MODULE_NAME')
name = get_setting('TAGS_PLUGIN_NAME') name = get_setting('TAGS_PLUGIN_NAME')
model = GenericBlogPlugin model = GenericBlogPlugin
base_render_template = 'plugins/tags.html' base_render_template = 'tags.html'
exclude = ['template_folder'] if len(get_setting('PLUGIN_TEMPLATE_FOLDERS')) >= 1 else []
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogTagsPlugin, self).render(context, instance, placeholder) context = super(BlogTagsPlugin, self).render(context, instance, placeholder)
@ -91,7 +99,8 @@ class BlogCategoryPlugin(BlogPlugin):
module = get_setting('PLUGIN_MODULE_NAME') module = get_setting('PLUGIN_MODULE_NAME')
name = get_setting('CATEGORY_PLUGIN_NAME') name = get_setting('CATEGORY_PLUGIN_NAME')
model = GenericBlogPlugin model = GenericBlogPlugin
base_render_template = 'plugins/categories.html' base_render_template = 'categories.html'
exclude = ['template_folder'] if len(get_setting('PLUGIN_TEMPLATE_FOLDERS')) >= 1 else []
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogCategoryPlugin, self).render(context, instance, placeholder) context = super(BlogCategoryPlugin, self).render(context, instance, placeholder)
@ -111,7 +120,8 @@ class BlogArchivePlugin(BlogPlugin):
module = get_setting('PLUGIN_MODULE_NAME') module = get_setting('PLUGIN_MODULE_NAME')
name = get_setting('ARCHIVE_PLUGIN_NAME') name = get_setting('ARCHIVE_PLUGIN_NAME')
model = GenericBlogPlugin model = GenericBlogPlugin
base_render_template = 'plugins/archive.html' base_render_template = 'archive.html'
exclude = ['template_folder'] if len(get_setting('PLUGIN_TEMPLATE_FOLDERS')) >= 1 else []
def render(self, context, instance, placeholder): def render(self, context, instance, placeholder):
context = super(BlogArchivePlugin, self).render(context, instance, placeholder) context = super(BlogArchivePlugin, self).render(context, instance, placeholder)

View file

@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('djangocms_blog', '0023_auto_20160626_1539'),
]
operations = [
migrations.AddField(
model_name='authorentriesplugin',
name='template_folder',
field=models.CharField(default='Default template', verbose_name='Plugin template', max_length=200, help_text='Select plugin template to load for this instance', choices=[('plugins', 'Default template')]),
),
migrations.AddField(
model_name='genericblogplugin',
name='template_folder',
field=models.CharField(default='Default template', verbose_name='Plugin template', max_length=200, help_text='Select plugin template to load for this instance', choices=[('plugins', 'Default template')]),
),
migrations.AddField(
model_name='latestpostsplugin',
name='template_folder',
field=models.CharField(default='Default template', verbose_name='Plugin template', max_length=200, help_text='Select plugin template to load for this instance', choices=[('plugins', 'Default template')]),
),
]

View file

@ -33,6 +33,7 @@ from .settings import get_setting
BLOG_CURRENT_POST_IDENTIFIER = get_setting('CURRENT_POST_IDENTIFIER') BLOG_CURRENT_POST_IDENTIFIER = get_setting('CURRENT_POST_IDENTIFIER')
BLOG_CURRENT_NAMESPACE = get_setting('CURRENT_NAMESPACE') BLOG_CURRENT_NAMESPACE = get_setting('CURRENT_NAMESPACE')
BLOG_PLUGIN_TEMPLATE_FOLDERS = get_setting('PLUGIN_TEMPLATE_FOLDERS')
try: # pragma: no cover try: # pragma: no cover
from cmsplugin_filer_image.models import ThumbnailOption # NOQA from cmsplugin_filer_image.models import ThumbnailOption # NOQA
@ -378,6 +379,13 @@ class BasePostPlugin(CMSPlugin):
current_site = models.BooleanField( current_site = models.BooleanField(
_('current site'), default=True, help_text=_('Select items from the current site only') _('current site'), default=True, help_text=_('Select items from the current site only')
) )
template_folder = models.CharField(
max_length=200,
verbose_name=_('Plugin template'),
help_text=_('Select plugin template to load for this instance'),
default=BLOG_PLUGIN_TEMPLATE_FOLDERS[0][0],
choices=BLOG_PLUGIN_TEMPLATE_FOLDERS
)
class Meta: class Meta:
abstract = True abstract = True

View file

@ -135,5 +135,8 @@ def get_setting(name):
'BLOG_LIVEBLOG_PLUGINS': getattr( 'BLOG_LIVEBLOG_PLUGINS': getattr(
settings, 'BLOG_LIVEBLOG_PLUGINS', ('LiveblogPlugin',)), settings, 'BLOG_LIVEBLOG_PLUGINS', ('LiveblogPlugin',)),
'BLOG_PLUGIN_TEMPLATE_FOLDERS': getattr(
settings, 'BLOG_PLUGIN_TEMPLATE_FOLDERS', (('plugins', _('Default template')),)),
} }
return default['BLOG_%s' % name] return default['BLOG_%s' % name]

View file

@ -149,6 +149,30 @@ To use this feature provide a directory name in **Template prefix** field in
the **Apphook configuration** admin (in *Layout* section): it will be the the **Apphook configuration** admin (in *Layout* section): it will be the
root of your custom templates set. root of your custom templates set.
****************
Plugin Templates
****************
Plugin templates live in the ``plugins`` folder of the folder specified by the **Template prefix**,
or by default ``djangocms_blog``.
By defining the setting ``BLOG_PLUGIN_TEMPLATE_FOLDERS`` you can allow multiple sets of
plugin templates allowing for different views per plugin instance. You could, for example,
have a plugin displaying latest posts as a list, a table or in masonry style.
To use this feature define ``BLOG_PLUGIN_TEMPLATE_FOLDERS`` as a list of available templates.
Each item of this list itself is a list of the form ``('[folder_name]', '[verbose name]')``.
Example:::
BLOG_PLUGIN_TEMPLATE_FOLDERS = (
('plugins', _('Default template')), # reads from templates/djangocms_blog/plugins/
('timeline', _('Vertical timeline')), # reads from templates/djangocms_blog/vertical/
('masonry', _('Masonry style')), # reads from templates/djangocms_blog/masonry/
)
Once defined, the plugin admin interface will allow content managers to select which template the plugin will use.
.. _sitemap: .. _sitemap:
******* *******

View file

@ -91,6 +91,8 @@ Global Settings
* BLOG_FEED_INSTANT_ITEMS: Number of items in Instant Article feed * BLOG_FEED_INSTANT_ITEMS: Number of items in Instant Article feed
* BLOG_FEED_LATEST_ITEMS: Number of items in latest items feed * BLOG_FEED_LATEST_ITEMS: Number of items in latest items feed
* BLOG_FEED_TAGS_ITEMS: Number of items in per tags feed * BLOG_FEED_TAGS_ITEMS: Number of items in per tags feed
* BLOG_PLUGIN_TEMPLATE_FOLDERS: (Sub-)folder from which the plugin templates are loaded. The default folder is ``plugins``. It goes into the ``djangocms_blog`` template folder (or, if set, the folder named in the app hook). This allows, e.g., different templates for showing a post list as tables, columns, ... . New templates have the same names as the standard templates in the ``plugins`` folder (``latest_entries.html``, ``authors.html``, ``tags.html``, ``categories.html``, ``archive.html``). Default behavior corresponds to this setting being ``( ("plugins", _("Default template") )``. To add new templates add to this setting, e.g., ``('timeline', _('Vertical timeline') )``.
****************** ******************
Read-only settings Read-only settings

View file

@ -189,11 +189,18 @@ class PluginTest(BaseTest):
context = self.get_plugin_context(pages[0], 'en', plugin) context = self.get_plugin_context(pages[0], 'en', plugin)
plugin_class = plugin.get_plugin_class_instance() plugin_class = plugin.get_plugin_class_instance()
self.assertEqual(plugin_class.get_render_template(context, plugin, ph), os.path.join('djangocms_blog', plugin_class.base_render_template)) self.assertEqual(plugin_class.get_render_template(context, plugin, ph),
os.path.join('djangocms_blog', plugin.template_folder, plugin_class.base_render_template))
self.app_config_1.app_data.config.template_prefix = 'whatever' self.app_config_1.app_data.config.template_prefix = 'whatever'
self.app_config_1.save() self.app_config_1.save()
self.assertEqual(plugin_class.get_render_template(context, plugin, ph), os.path.join('whatever', plugin_class.base_render_template)) tmp = plugin.template_folder
plugin.template_folder = 'whereever'
plugin.save()
self.assertEqual(plugin_class.get_render_template(context, plugin, ph),
os.path.join('whatever', 'whereever', plugin_class.base_render_template))
plugin.template_folder = tmp
plugin.save()
self.app_config_1.app_data.config.template_prefix = '' self.app_config_1.app_data.config.template_prefix = ''
self.app_config_1.save() self.app_config_1.save()