diff --git a/djangocms_blog/cms_plugins.py b/djangocms_blog/cms_plugins.py index 70bb4b5..637cf18 100644 --- a/djangocms_blog/cms_plugins.py +++ b/djangocms_blog/cms_plugins.py @@ -18,9 +18,13 @@ class BlogPlugin(CMSPluginBase): def get_render_template(self, context, instance, placeholder): 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: - 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): @@ -32,9 +36,10 @@ class BlogLatestEntriesPlugin(BlogPlugin): model = LatestPostsPlugin form = LatestEntriesForm 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 - base_render_template = 'plugins/latest_entries.html' + base_render_template = 'latest_entries.html' def render(self, context, instance, placeholder): context = super(BlogLatestEntriesPlugin, self).render(context, instance, placeholder) @@ -51,8 +56,9 @@ class BlogLatestEntriesPluginCached(BlogPlugin): model = LatestPostsPlugin form = LatestEntriesForm filter_horizontal = ('categories',) - fields = ('app_config', 'latest_posts', 'tags', 'categories') - base_render_template = 'plugins/latest_entries.html' + fields = ['app_config', 'latest_posts', 'tags', 'categories'] + \ + ['template_folder'] if len(get_setting('PLUGIN_TEMPLATE_FOLDERS')) > 1 else [] + base_render_template = 'latest_entries.html' def render(self, context, instance, placeholder): context = super(BlogLatestEntriesPluginCached, self).render(context, instance, placeholder) @@ -65,8 +71,9 @@ class BlogAuthorPostsPlugin(BlogPlugin): module = get_setting('PLUGIN_MODULE_NAME') name = get_setting('AUTHOR_POSTS_PLUGIN_NAME') model = AuthorEntriesPlugin - base_render_template = 'plugins/authors.html' + base_render_template = 'authors.html' filter_horizontal = ['authors'] + exclude = ['template_folder'] if len(get_setting('PLUGIN_TEMPLATE_FOLDERS')) >= 1 else [] def render(self, context, instance, placeholder): context = super(BlogAuthorPostsPlugin, self).render(context, instance, placeholder) @@ -78,7 +85,8 @@ class BlogTagsPlugin(BlogPlugin): module = get_setting('PLUGIN_MODULE_NAME') name = get_setting('TAGS_PLUGIN_NAME') 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): context = super(BlogTagsPlugin, self).render(context, instance, placeholder) @@ -91,7 +99,8 @@ class BlogCategoryPlugin(BlogPlugin): module = get_setting('PLUGIN_MODULE_NAME') name = get_setting('CATEGORY_PLUGIN_NAME') 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): context = super(BlogCategoryPlugin, self).render(context, instance, placeholder) @@ -111,7 +120,8 @@ class BlogArchivePlugin(BlogPlugin): module = get_setting('PLUGIN_MODULE_NAME') name = get_setting('ARCHIVE_PLUGIN_NAME') 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): context = super(BlogArchivePlugin, self).render(context, instance, placeholder) diff --git a/djangocms_blog/migrations/0024_auto_20160706_1524.py b/djangocms_blog/migrations/0024_auto_20160706_1524.py new file mode 100644 index 0000000..bd658c8 --- /dev/null +++ b/djangocms_blog/migrations/0024_auto_20160706_1524.py @@ -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')]), + ), + ] diff --git a/djangocms_blog/models.py b/djangocms_blog/models.py index 91df778..1bd1df5 100644 --- a/djangocms_blog/models.py +++ b/djangocms_blog/models.py @@ -33,6 +33,7 @@ from .settings import get_setting BLOG_CURRENT_POST_IDENTIFIER = get_setting('CURRENT_POST_IDENTIFIER') BLOG_CURRENT_NAMESPACE = get_setting('CURRENT_NAMESPACE') +BLOG_PLUGIN_TEMPLATE_FOLDERS = get_setting('PLUGIN_TEMPLATE_FOLDERS') try: # pragma: no cover from cmsplugin_filer_image.models import ThumbnailOption # NOQA @@ -378,6 +379,13 @@ class BasePostPlugin(CMSPlugin): current_site = models.BooleanField( _('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: abstract = True diff --git a/djangocms_blog/settings.py b/djangocms_blog/settings.py index 0199182..30fc346 100644 --- a/djangocms_blog/settings.py +++ b/djangocms_blog/settings.py @@ -135,5 +135,8 @@ def get_setting(name): 'BLOG_LIVEBLOG_PLUGINS': getattr( settings, 'BLOG_LIVEBLOG_PLUGINS', ('LiveblogPlugin',)), + 'BLOG_PLUGIN_TEMPLATE_FOLDERS': getattr( + settings, 'BLOG_PLUGIN_TEMPLATE_FOLDERS', (('plugins', _('Default template')),)), + } return default['BLOG_%s' % name] diff --git a/docs/features.rst b/docs/features.rst index 55b9f13..bf46071 100644 --- a/docs/features.rst +++ b/docs/features.rst @@ -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 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: ******* diff --git a/docs/settings.rst b/docs/settings.rst index 36d658a..b3f0afe 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -91,6 +91,8 @@ Global Settings * BLOG_FEED_INSTANT_ITEMS: Number of items in Instant Article feed * BLOG_FEED_LATEST_ITEMS: Number of items in latest items 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 diff --git a/tests/test_plugins.py b/tests/test_plugins.py index e926fe4..7ef7202 100644 --- a/tests/test_plugins.py +++ b/tests/test_plugins.py @@ -189,11 +189,18 @@ class PluginTest(BaseTest): context = self.get_plugin_context(pages[0], 'en', plugin) 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.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.save()