Skip to content

Commit

Permalink
Merge pull request #3875 from mkoistinen/mkoistinen-feature/render_mo…
Browse files Browse the repository at this point in the history
…del_add_block

Add render_model_add_block tag
  • Loading branch information
yakky committed Feb 20, 2015
2 parents 42cad70 + b7ab3a1 commit a5dae7d
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 2 deletions.
2 changes: 1 addition & 1 deletion cms/templates/cms/toolbar/plugin.html
@@ -1,6 +1,6 @@
{% spaceless %}{% load i18n l10n sekizai_tags static cms_tags %}

<div class="cms_plugin cms_plugin-{% if generic %}{{ generic.app_label }}-{{ generic.module_name }}-{% if attribute_name %}{{ attribute_name|slugify }}-{% endif %}{% endif %}{{ instance.pk|unlocalize }}{% if render_model_icon %} cms_render_model_icon{% elif render_model %} cms_render_model{% elif render_model_block %} cms_render_model cms_render_model_block{% elif render_model_add %} cms_render_model_add{% endif %}">{% if render_model_icon %}<img src="{% static 'cms/img/toolbar/render_model_placeholder.png' %}">{% elif render_model_add %}<img src="{% static 'cms/img/toolbar/render_model_placeholder.png' %}">{% else %}{{ rendered_content }}{% endif %}</div>
<div class="cms_plugin cms_plugin-{% if generic %}{{ generic.app_label }}-{{ generic.module_name }}-{% if attribute_name %}{{ attribute_name|slugify }}-{% endif %}{% endif %}{{ instance.pk|unlocalize }}{% if render_model_icon %} cms_render_model_icon{% elif render_model %} cms_render_model{% elif render_model_block %} cms_render_model cms_render_model_block{% elif render_model_add %} cms_render_model_add{% endif %}">{% if content %}{{ content }}{% elif render_model_icon %}<img src="{% static 'cms/img/toolbar/render_model_placeholder.png' %}">{% elif render_model_add %}<img src="{% static 'cms/img/toolbar/render_model_placeholder.png' %}">{% else %}{{ rendered_content }}{% endif %}</div>

{% addtoblock "js" %}
<script>
Expand Down
47 changes: 47 additions & 0 deletions cms/templatetags/cms_tags.py
Expand Up @@ -983,6 +983,53 @@ def get_context(self, context, instance, language,
register.tag(CMSEditableObjectAdd)


class CMSEditableObjectAddBlock(CMSEditableObject):
"""
Templatetag that links arbitrary content to the addform for the specified
model (based on the provided model instance).
"""
name = 'render_model_add_block'
options = Options(
Argument('instance'),
Argument('language', default=None, required=False),
Argument('view_url', default=None, required=False),
Argument('view_method', default=None, required=False),
'as',
Argument('varname', required=False, resolve=False),
blocks=[('endrender_model_add_block', 'nodelist')],
)

def render_tag(self, context, **kwargs):
"""
Renders the block and then inject the resulting HTML in the template
context
"""
context.push()
template = self.get_template(context, **kwargs)
data = self.get_context(context, **kwargs)
data['content'] = mark_safe(kwargs['nodelist'].render(data))
data['rendered_content'] = data['content']
output = render_to_string(template, data)
context.pop()
if kwargs.get('varname'):
context[kwargs['varname']] = output
return ''
else:
return output

def get_context(self, context, instance, language,
view_url, view_method, varname, nodelist):
"""
Uses _get_empty_context and adds the `render_model_icon` variable.
"""
extra_context = self._get_empty_context(context, instance, None,
language, view_url, view_method,
editmode=False)
extra_context['render_model_add'] = True
return extra_context
register.tag(CMSEditableObjectAddBlock)


class CMSEditableObjectBlock(CMSEditableObject):
"""
Templatetag that links a content extracted from a generic django model
Expand Down
70 changes: 70 additions & 0 deletions cms/tests/templatetags.py
Expand Up @@ -380,3 +380,73 @@ def test_render_placeholder_as_var(self):
context = RequestContext(request)
with self.assertNumQueries(4):
template.render(context)

def test_render_model_add(self):
from django.core.cache import cache
from cms.test_utils.project.sampleapp.models import Category

cache.clear()
page = create_page('Test', 'col_two.html', 'en', published=True)
template = Template(
"{% load cms_tags %}{% render_model_add category %}")
user = self._create_user("admin", True, True)
request = RequestFactory().get('/')
request.user = user
request.current_page = page
request.session = {}
request.toolbar = CMSToolbar(request)
request.toolbar.edit_mode = True
request.toolbar.is_staff = True
context = RequestContext(request, {'category': Category()})
with self.assertNumQueries(0):
output = template.render(context)
expected = 'cms_plugin cms_plugin-sampleapp-category-add-None '
'cms_render_model_add'
self.assertIn(expected, output)

# Now test that it does NOT render when not in edit mode
request = RequestFactory().get('/')
request.user = user
request.current_page = page
request.session = {}
request.toolbar = CMSToolbar(request)
context = RequestContext(request, {'category': Category()})
with self.assertNumQueries(0):
output = template.render(context)
expected = ''
self.assertEqual(expected, output)

def test_render_model_add_block(self):
from django.core.cache import cache
from cms.test_utils.project.sampleapp.models import Category

cache.clear()
page = create_page('Test', 'col_two.html', 'en', published=True)
template = Template(
"{% load cms_tags %}{% render_model_add_block category %}wrapped{% endrender_model_add_block %}")
user = self._create_user("admin", True, True)
request = RequestFactory().get('/')
request.user = user
request.current_page = page
request.session = {}
request.toolbar = CMSToolbar(request)
request.toolbar.edit_mode = True
request.toolbar.is_staff = True
context = RequestContext(request, {'category': Category()})
with self.assertNumQueries(0):
output = template.render(context)
expected = 'cms_plugin cms_plugin-sampleapp-category-add-None '
'cms_render_model_add'
self.assertIn(expected, output)

# Now test that it does NOT render when not in edit mode
request = RequestFactory().get('/')
request.user = user
request.current_page = page
request.session = {}
request.toolbar = CMSToolbar(request)
context = RequestContext(request, {'category': Category()})
with self.assertNumQueries(0):
output = template.render(context)
expected = 'wrapped'
self.assertEqual(expected, output)
51 changes: 50 additions & 1 deletion docs/reference/templatetags.rst
Expand Up @@ -631,7 +631,56 @@ It will render to something like:

.. _django-hvad: https://github.com/kristianoellegaard/django-hvad

{% endblock %}

render_model_add_block
======================

``render_model_add_block`` is similar to ``render_model_add`` but instead of
emitting an icon that is linked to the add model form in a modal dialog, it
wraps arbitrary markup with the same "link". This allows the developer to create
front-end editing experiences better suited to the project.

All arguments are identical to ``render_model_add``, but the templatetag is used
in two parts to wrap the markup that should be wrapped.

.. code-block:: html+django

{% render_model_add_block my_model_instance %}<div>New Object</div>{% endrender_model_add_block %}


It will render to something like:

.. code-block:: html+django

<div class="cms_plugin cms_plugin-myapp-mymodel-1 cms_render_model_add">
<div>New Object</div>
</div>


.. warning::

You **must** pass an *instance* of your model as instance parameter. The
instance passed could be an existing models instance, or one newly created
in your view/plugin. It does not even have to be saved, it is introspected
by the templatetag to determine the desired model class.


**Arguments:**

* ``instance``: instance of your model in the template
* ``edit_fields`` (optional): a comma separated list of fields editable in the
popup editor;
* ``language`` (optional): the admin language tab to be linked. Useful only for
`django-hvad`_ enabled models.
* ``view_url`` (optional): the name of a url that will be reversed using the
instance ``pk`` and the ``language`` as arguments;
* ``view_method`` (optional): a method name that will return a URL to a view;
the method must accept ``request`` as first parameter.
* ``varname`` (optional): the templatetag output can be saved as a context
variable for later use.

.. _django-hvad: https://github.com/kristianoellegaard/django-hvad


.. templatetag:: page_language_url

Expand Down

0 comments on commit a5dae7d

Please sign in to comment.