"Read More" for Django WYSIWYG editor - python

I am using django-summernote editor for creating posts with text and images which are saved in a character field as HTML tags.
I want to add a read-more functionality where a limited sized preview is shown for all the posts. An idea could be to truncate the character field, but it may lead to truncation of HTML image tags if they happen to be positioned between the boundary.
How to get around this?

Django has two template filters you can use to make sure your HTML doesn't get malformed: truncatechars_html and truncatewords_html
Template filters are just functions, so you can import them anywhere you need in your Python code and assign the result to a variable you can use elsewhere, etc.
Example:
from django.template.defaultfilters import truncatechars_html
html = """<p>Look, I’m some HTML. You can truncate me
with Django template filters</p>"""
truncated_value = truncatechars_html(html, 30)

I'm late to this party but this post came up in search results. I just got a working solution to this myself with a custom template filter. This allows you to drop in the break on a case by case basis like WordPress. Here is what I did (with help from this post and the Django docs):
Sample post submitted in a textfield:
<p>Here is some sample text</p>
<!--more-->
<img src="cool_photo.jpg" />
in templatetags/read_more.py
from django import template
from django.template.defaultfilters import stringfilter
register = template.Library()
#register.filter(name='read_more')
#stringfilter
def read_more(value):
pattern = "<!--more-->"
return value.split(pattern, 1)[0]
in the template that's rendering the truncated version:
{% load read_more %}
{{ object.body|read_more|safe }}
Since the split pattern is an html comment there's no need to cut it from the main post body template:
{{ object.body|safe }}

Related

HTML not rendering well when using markdown2 converted

I'm working on a Django project in Python and using markdown2 to convert some markdown text into HTML but it appears to not be doing it well or I'm missing something in the code.
In my views.py file I'm using a custom function to extract some text from an .md file in markdown format and with the markdown2 module I try pass it on to the HTML template like so:
text = markdown2.markdown(util.get_entry(entry))
But in the HTML, if I inspect the source code what is supposed to render as HTML comes out like this:
<h1>HTML</h1>
Am I missing something in my code? Is the error on the HTML template or in my views.py file?
Thanks in advance!
You probably have rendered the content in the template with:
{{ text }}
Django will by default escape the content, and thus replace < with <, etc.
You can make use of the |safe template filter [Django-doc] to prevent this:
{{ text|safe }}

Changing css styles from view in Django

Sorry in advance if there is an obvious answer to this, I'm still learning the ropes with Django.
I'm creating a website which has 6 pre determined subjects (not stored in DB)
english, civics, literature, language, history, bible
each subject is going to be associated with a unique color.
I've got a template for a subject.html page and a view that loads from the url appname/subject/subjectname
what I need to do is apply particular css to style the page according to the subject accessed. for example if the user goes to appname/subject/english I want the page to be "themed" to english.
I hope I've made myself clear, also I would like to know if there is a way I can add actual css code to the stylesheet and not have to change attributes one by one from the back-end.
thanks very much!
In templates you can use conditionals for add css, like this:
<div class="{% if subject=='civics' %}civic-class{% endif %}"></div>
For this, subject value should come from view.
Now, for themed page, you could use the extends tag. Let's supose:
def your_view(request):
subject # Here you get the url subject, 'how' is up to you
if subject == 'english'
template_base = '/some/html/tenplate.html'
elif subject == 'civis':
template_base = '/some/other/template.html'
... # then you return 'template_base' variable to template
Then in template:
{% extends template_base %} # at the top
Hope this helps, is the same logic if you use Class-Based views.
Django's views are not responsible for the presentation, it's the template (and css etc of course)'s reponsability. Now assuming you have the same view serving different subjects, the view obviously need to know which is the current subject (I assume from a captured part of the url passed as argument to the view), so it can easily pass this information to the template, which in turn can use it to add a subject-specific class to the body tag. Then you only have to write your css accordingly.
As an example:
# urls.py
patterns = urlpatterns('',
#...
url(r'whatever/(P?<subject>[a-z-]+>)/$', 'myviews.index', ...),
)
# myviews.py
def index(request, subject):
# do whatever
context = {
# whatever else
'subject':subject
}
return render(request, "whatever/index.html", context)
# whatever/index.html
<html>
# headers etc
<body class="something {{ subject }} etc">
# whatever here
</body>
</html>
You can do this is many ways.
In general you need to return some variable from your view to the html and depending on this variable select a style sheet, if your variable name will match you style sheet's name you can do "{{variable}}.css", if not you can use JQuery.

Locale/Internationalization in django

I realize there is a utility django.utils.translation that will translate "Hello" in "Hola" somehow but I wanted more control over the exact translations.
Right now my django project is achieving multilingual support with a View.py wrapper for render with some logic to determine the user's preferred locale or falling back to a default locale.
My templates are currently in this type of structure:
templates/en_US/index.html
templates/es_MX/index.html
with some logic that will let it fall back to templates/en_US/index.html if, say, templates/pt_PT/index.html doesn't exist.
I want to create a custom tag/function (https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/) in my template layer that can translate a token to a string so I can move away from maintaining a set of template files for each locale. For example:
<h2> {% t 'index.welcome' %} </h2>
in en-US it would become:
<h2> Welcome </h2>
in es-MX it would become:
<h2> Hola </h2>
So I thought I could to this like this:
from django import template
register = template.Library()
#register.simple_tag
def t(token):
# determine locale and look up the token and get its value
# in the appropriate locale file (with some fall-back logic)
But I don't have access to the request object in a registered tag so I can't determine what I need to find the locale.
All of this functionality, and more, is already provided by Django's Internationalization framework, as documented here: https://docs.djangoproject.com/en/1.8/topics/i18n/translation/
Translations in templates, specifically, are done by way of the trans template tag, such as {% trans 'Welcome' %}.
(As mentioned in my comment above)

Using variables in Django model content

i like to use the url template tag in my model's content.
example:
models content:
Car.description = 'this is a link to our main page: home'
in template.html:
<div>{{ Car.description }}</div>
result
<div>this is a link to our main page: home
is it possible, or do i have to write my own template tag?
thanks in advance
Roman
Assuming you have this:
car.description = 'this is a link to our main page: home'
You can do:
from django.template import Context, Template
from django.core.urlresolvers import reverse
class Car(models.Model):
def description_with_url(self):
return Template(self.description).render({'url': reverse('home')})
or use the same logic in custom template tag instead of method..
I can't figure out why you would need to do that. Assuming that I fully-understood your question, you are attempting to store something within a model's field that then behaves "dynamically" when rendered.
A model field's content that stores a URL should contain a URL and only a URL by utilizing the URLField.
Else, if you're dynamically building the URL from somewhere else, simply use template markup, i.e. the url template tag as it is meant to be used; it can also take parameters depending on the specific URL pattern. I.e. the url tag is meant to be used in the template's context.
Let me know if you update the question to describe what you are trying to achieve. But storing "behaviour" at data level is something to simply stay away from.

Render django application within TextField

I am creating an application to display articles. In my model, I have a TextField that will contain the content of the article.
Now I would like to be able to render another application within my article. Let say I have a poll application and I would like to display a poll in the middle of the article. How can I do that ?
I tried by putting a {% render_poll 42 %} within the post but, as expected, it just display that within the generated page.
Should I create some kind of tag (like let say [poll=42]) and parse it before displaying the rendered html page ? (I use the markdown library, maybe I could extend it.) How can I do that to stay in a nice "django friendly" way ? I want that, when in the admin panel, I can easily insert poll (or other apps) within an article.
You could compile the TextField string as a template. Ie.:
from django.db import models
from django.template import Template, Context
class YourModel(models.Model):
body = models.TextField()
def render_body(self, context=None):
template = Template(self.body)
context = context or {}
context['object'] = self
return template.render(Context(context))
Then in the actual template, you could use {{ your_model.render_body }} rather than {{ your_model.body }}.

Categories

Resources