Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

django cms integration #1

Merged
merged 13 commits into from

3 participants

@jssevestre

Hello

please see attached simple code to use django-terms with django-cms:

TermsProcessor
a context processor to parse all plugins output

TermsIndexPlugin
to display all terms on a page as

BR

@BertrandBordage

Excellent! I start reviewing it right now!

@BertrandBordage

Hum... I think rendered_context.replace('<br>', '<br/>') would be better.

I agree

@BertrandBordage

I prefer relative imports in this case: from .html import....

@BertrandBordage

Is there a reason for this import to be here? No offense, I am just wondering :)

No offense, i'm not an expert
I just follow/copy http://django-cms.readthedocs.org/en/latest/extending_cms/custom_plugins.html#example

It's better on top.

Yes, it's better on top :)
And you are doing pretty well!

@BertrandBordage

Same thing here: from .models import Term.
Could you also add another newline before and after the class? 'Just for PEP8 compliance.

@BertrandBordage

I don't think adding newlines between definitions is the proper way to do styling :)
Since django-cms is using sekizai_tags, you could use something like this before (to add 5px after each dd that is followed by a dt):

{% addtoblock 'css' %}
  <style>
    dl.terms-index dd+dt {
        margin-top: 5px;
    }
  </style>
{% endaddtoblock %}

may be it's better without styling in this base template.
But I will add 'terms-index' class to

so users could style

terms/cms_plugin_processors.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+from .html import TermsHTMLReconstructor
+from django.template import Context, Template
+
+
+def TermsProcessor(instance, placeholder, rendered_content, original_context):
+ """
+ This processor mark all terms in all placeholders plugins except termsplugins
+ """
+ if 'terms' in original_context:
+ return rendered_content
+ else:
@BertrandBordage Owner

This else statement is useless. If 'terms' in original_context is True, you return something, which also means you leave this function. The else is therefore verified each time it is parsed.

ok removed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@BertrandBordage

This line still needs to be replaced with a str.replace. Or it could even be removed, since this exception is only raised in DEBUG mode.

I replace with rendererd_content.replace
I think we can't let the exeption raise even in DEBUG mode.
it's a parsing bug, and this is a workaround !

It's not a parsing bug, it's an HTML malformation that should never happen, which is why I chose to give it this particular importance.
<br> is not the only tag that is oftenly malformed, you can also take the cases of <input> and <link>. What you are trying to make should idealy be an exhaustive list of common cases handled by TermsHTMLReconstructor. And it is not the job of django-terms to guess why someone made a mistake.

So, in my opinion, this is not where these replacements should be done, and the list would necesserally buggy (your replacement is not handling <BR> or <BR >).

This is why, in the develop branch, I chose to replace my bad HTMLReconstructor with the excellent BeautifulSoup4. It automatically fixes these common malformations. But the develop branch isn't stable yet, so you have to wait and... Set DEBUG to False or fix your HTML malformations.

OK, it's not the place to fix other app bugs !

  • HTML <br> malformation from django-cms
  • <br> HTMLValidationWarning from HTMLReconstructor

So I clean those 2 lines and wait for develop branch

@BertrandBordage

This has no effect. A Python string being immutable, this method is not modifying it in place, it returns another string.

@BertrandBordage

That's it! Do you have anything else to change, or can I merge your pull request?
Besides, I will then create an AUTHORS file containing our names.

@jssevestre

Fine,
No more change in code right now !
May be a usage note will be usefull : just wait a moment !

@jssevestre jssevestre Usage note
for cms_plugin_processor and TermsIndexPLugin
578739b
@BertrandBordage

CMS_PLUGIN_PROCESSORS = (

@BertrandBordage

If I can remember correctly, one doesn't need to add 'app.cms_pluginto INSTALLED_APPS in order to use its plugins.'terms'` should be enough.

@BertrandBordage

Typo: definitions.

@jssevestre

2ea5f2a fix README review

@BertrandBordage BertrandBordage commented on the diff
terms/cms_plugins.py
@@ -0,0 +1,19 @@
+from cms.plugin_base import CMSPluginBase
+from cms.plugin_pool import plugin_pool
+from cms.models.pluginmodel import CMSPlugin
+from django.utils.translation import ugettext_lazy as _
+from .models import Term
+
+
+class TermsIndexPlugin(CMSPluginBase):
+ model = CMSPlugin
+ name = _("Terms Index Plugin")
+ render_template = "term_plugin.html"
+
+ def render(self, context, instance, placeholder):
+ terms = Term.objects.all()
@BertrandBordage Owner

I just realized something: if you select every Term, you will also display those who have no definition but a link instead. So you either need to apply a .exclude(description='') to this QuerySet or handle this (not so) special case in the template.

IMHO we should add link in the template, maybe a short version like

<dd>{{ term.definition|safe }} {{ term.url|urlizetrunc:15 }}</dd>

If there is a description, it will be add after. Else, it will be the only content.

@BertrandBordage Owner

Good. Maybe a newline this time? Only if there is a url, of course. And maybe more letters shown in the urlizetrunc. Something like:

<dd>
  {{ term.definition|safe }}
  {% if term.url %}
    <br/>
    {{ term.url|urlizetrunc:40 }}
  {% endif %}
</dd>

No, if definition is empty and url not, the new line is still there.
Perhaps, but more complex :

{{ term.definition|safe }}
{% if term.url and term.definition %}<br/>{%endif %}
{{ term.url|urlizetrunc:40 }}
@BertrandBordage Owner

Oh, yes. Sorry. Go on, I think this will be the last one before I merge all your changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@BertrandBordage BertrandBordage merged commit 5f2558a into from
@coveralls

Coverage Status

Changes Unknown when pulling d70125f on jssevestre:master into ** on BertrandBordage:master**.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
25 README.rst
@@ -62,9 +62,12 @@ Usage
* `Middleware`_ (to give django-terms a try or for development)
* `Template filter`_ (for production)
+ * `cms_plugin_processor`_ (if you are using django-CMS)
The added terms should now be automatically linked to their definitions.
+For django-CMS users : display all terms and their definitions with the `TermsIndexPlugin`_.
+
Middleware
----------
@@ -140,6 +143,26 @@ Example:
TERMS_ADDITIONAL_IGNORED_CLASSES = ['code-snippet']
+cms_plugin_processor
+--------------------
+
+A cms_plugin_processor is available if you are using django-CMS.
+It will parse all plugin output.
+
+Add this in `settings.py`::
+
+ CMS_PLUGIN_PROCESSORS = (
+ [...]
+ 'terms.cms_plugin_processors.TermsProcessor',
+ [...]
+ )
+
+
+TermsIndexPlugin
+----------------
+
+If you are using django-CMS, you can display all terms and their definitions with the "Terms Index Plugin".
+
Settings
========
@@ -308,7 +331,7 @@ Resolver404
HTMLValidationWarning
.....................
-:Raised by: `Middleware`_ and `Template filter`_.
+:Raised by: `Middleware`_, `Template filter`_. and `cms_plugin_processor`_
:Raised in: `TERMS_DEBUG`_ mode. Otherwise we try to make terms replacements
work anyway.
:Reason: This happens when django-terms finds a problem in the architecture
View
22 terms/cms_plugin_processors.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+
+from .html import TermsHTMLReconstructor
+from django.template import Context, Template
+
+
+def TermsProcessor(instance, placeholder, rendered_content, original_context):
+ """
+ This processor mark all terms in all placeholders plugins except termsplugins
+ """
+ if 'terms' in original_context:
+ return rendered_content
+
+ parser = TermsHTMLReconstructor()
+ parser.feed(rendered_content)
+
+ t = Template('{{ content|safe }}')
+ c = Context({
+ 'content': parser.out,
+ })
+ return t.render(c)
View
19 terms/cms_plugins.py
@@ -0,0 +1,19 @@
+from cms.plugin_base import CMSPluginBase
+from cms.plugin_pool import plugin_pool
+from cms.models.pluginmodel import CMSPlugin
+from django.utils.translation import ugettext_lazy as _
+from .models import Term
+
+
+class TermsIndexPlugin(CMSPluginBase):
+ model = CMSPlugin
+ name = _("Terms Index Plugin")
+ render_template = "term_plugin.html"
+
+ def render(self, context, instance, placeholder):
+ terms = Term.objects.all()
@BertrandBordage Owner

I just realized something: if you select every Term, you will also display those who have no definition but a link instead. So you either need to apply a .exclude(description='') to this QuerySet or handle this (not so) special case in the template.

IMHO we should add link in the template, maybe a short version like

<dd>{{ term.definition|safe }} {{ term.url|urlizetrunc:15 }}</dd>

If there is a description, it will be add after. Else, it will be the only content.

@BertrandBordage Owner

Good. Maybe a newline this time? Only if there is a url, of course. And maybe more letters shown in the urlizetrunc. Something like:

<dd>
  {{ term.definition|safe }}
  {% if term.url %}
    <br/>
    {{ term.url|urlizetrunc:40 }}
  {% endif %}
</dd>

No, if definition is empty and url not, the new line is still there.
Perhaps, but more complex :

{{ term.definition|safe }}
{% if term.url and term.definition %}<br/>{%endif %}
{{ term.url|urlizetrunc:40 }}
@BertrandBordage Owner

Oh, yes. Sorry. Go on, I think this will be the last one before I merge all your changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ context['terms'] = terms
+ return context
+
+
+plugin_pool.register_plugin(TermsIndexPlugin)
View
8 terms/templates/term_plugin.html
@@ -0,0 +1,8 @@
+<dl class="terms-index">
+{% for term in terms %}
+ <dt>{{ term|capfirst }}</dt>
+ <dd>{{ term.definition|safe }}
+ {% if term.url and term.definition %}<br/>{%endif %}
+ {{ term.url|urlizetrunc:40 }}</dd>
+{% endfor %}
+</dl>
Something went wrong with that request. Please try again.