the urlize function from django.utils.html converts urls to clickable links. My problem is that I want to append a target="_blank" into the "< href..>", so that I open this link in a new tab. Is there any way that I can extend the urlize function to receive an extra argument? or should I make a custom filter using regexes to do this stuff? Is this efficient?
You can add a custom filter, as described here:
I used this one:
# <app name>/templatetags/url_target_blank.py
from django import template
register = template.Library()
def url_target_blank(text):
return text.replace('<a ', '<a target="_blank" ')
url_target_blank = register.filter(url_target_blank, is_safe = True)
Example of usage:
{% load url_target_blank %}
...
{{ post_body|urlize|url_target_blank }}
Works fine for me :)
Shortest version, that I use in my projects. Create a new filter, that extends the default filter of Django:
from django import template
from django.template.defaultfilters import stringfilter
from django.utils.safestring import mark_safe
from django.utils.html import urlize as urlize_impl
register = template.Library()
#register.filter(is_safe=True, needs_autoescape=True)
#stringfilter
def urlize_target_blank(value, limit, autoescape=None):
return mark_safe(urlize_impl(value, trim_url_limit=int(limit), nofollow=True, autoescape=autoescape).replace('<a', '<a target="_blank"'))
There is no capability in the built-in urlize() to do this. Due to Django's license you can copy the code of django.utils.html.urlize and django.template.defaultfilters.urlize into your project or into a separate app and use the new definitions instead.
You shouldn't add target="_blank" to your links, it's deprecated. Users should decide themselves if where they want to open a link.
You can still open the link with unobtrusive JavaScript like so (using jQuery):
$('.container a').click(function(e){e.preventDefault();window.open(this.href);});
That said, you could write your own filter, but you'd have to copy a lot of code from django.utils.html.urlize, not really DRY.
Related
I have a post object which has content attribute which is basically a TextField. I want to show first few sentences (not words, I want it to truncate after 2-3 full stops, or something like that) as preview of post on my webpage.
{{ post.content }}
How do I do that in my template?
First, you need to split the given text into sentences, you can use the function provided in this answer
Next, register your custom template tag that uses the above function, and here you go:
from django import template
from django.template.defaultfilters import stringfilter
from <your utils package> import split_into_sentences
register = template.Library()
#register.filter
#stringfilter
def truncate_sentences(value, length=3):
sentences = split_into_sentences(value)
return ' '.join(sentences[:length])
Then simply use the custom template tag in your template:
{{ post.content|truncate_sentences:3 }}
I have url:path('<int:id>',views.article_detail,name="detail")
It works on the site.
<p>{{article.title}} </p>
But if I try to give a link in the email, for example
<p>article </p>
In link I heve only
http://articles/36
Link like
<p>artickle! </p>
not work.
You have two ways to accomplish what you need.
If it’s just one time work then I suggest something quick:
On your view import the settings and send to the template the ‘settings.BASE_URL’ value
from django.conf import settings
base_url = settings.BASE_URL
you can pass the value in your context to create the url as you already tried to do.
Another option is to create a tag to get the base url from the setting and generate the complete url base on the given parameter
from django import template
from django.conf import settings
base_url = settings.BASE_URL
register = template.Library()
#register.simple_tag
def add_domain(partial_url):
return base_url + partial_url
In your template just use
{% add_domain url_generated %}
This is just an example, you could define a more complex tag to generate the url included the domain with a flag parameter.
When I try to call this in my template
{% if member.departments.relationship(department).is_manager is True %}
I get this error
Could not parse the remainder: '(department).is_manager' from 'member.departments.relationship(department).is_manager'
But the same call works when I debug my view
(Pdb) member.departments.relationship(department).is_manager
True
Here is my view
def department_detail(request, uid):
department = Department.nodes.get(uid=uid)
return render(request, 'department/detail.html', {'department': department,})
To solve it, I made use of templatetags. Fun and powerful to learn:
Added /templatetags to same directory as models.py
Added /templatetags/init.py
Added /templatetags/department_extras.py
department_extras.py:
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
#register.filter
def check_is_manager(member, department):
if member.departments.relationship(department).is_manager is True:
html_response = """<i class="fa fa-user-tie" title="Manager"></i>"""
else:
html_response = ""
return mark_safe(html_response)
then in template:
{% load department_extras %}
{{member|check_is_manager:department}}
Disclaimer: If I was using a standard ORM then I would not have this problem, and I am only using it for visual effect, not business logic. If it weren't for the fact that 3 views and other models will need the same functionality, then I would have passed in an additional argument to the template.
I like templatetags because they are almost like sub-views that can act as common denominators across views so that you don't have to keep passing in supplemental data in your arguments of each view.
I'm using wagtail without its templates (I built an API using rest-framework).
I would like to change the format of the images in the rich text editor
For example this is my RichText field right now:
<p>test test test</p>
<p><br/></p><p><embed alt=\"IMG_1232.jpg\" embedtype=\"image\" format=\"test\" id=\"4\"/><br/></p>"
Instead I would like it to include only the direct link to the image, and even better to the image with the filter I defined (with register_image_format).
e.g.:
<p>test test test</p>
<p><br/></p><p><embed href="/media/IMG_1232.width-400"/><br/></p>"
Is it possible?
I looked into hallo.js but not sure what to do with it...
Thanks
Add a method to your model which returns the result of calling the richtext filter on your rich text field. You can then use this method in place of the field itself within the api_fields definition:
from wagtail.core.templatetags import wagtailcore_tags
def MyPage(Page):
body = RichTextField()
def rendered_body(self):
return wagtailcore_tags.richtext(self.body)
api_fields = [
APIField('rendered_body'),
]
To get the full URL for images, embed and documents, you have to run the content of the richtext block through the richtext filter template tag.
from wagtail.wagtailcore.templatetags import wagtailcore_tags
rich_text = wagtailcore_tags.richtext(rich_text_source)
rich_text should have embed and images with full URL.
Using with DRF it would look something like this, if your doing it in your serializer
from django.contrib.auth.models import User
from django.utils.timezone import now
from rest_framework import serializers
from wagtail.wagtailcore.templatetags import wagtailcore_tags
class SomeSerializer(serializers.Serializer):
rich_text = serializers.SerializerMethodField()
def get_rich_text(self, obj):
return wagtailcore_tags.richtext(obj.rich_text.source)
I am new to django framework. I have a doubt with the package of library. can any one explain me about the template.library() function and in what purpose we are used #register.filter() before starting a function. I have defined the code below.
from django import template
register = template.Library()
#register.filter()
def boldcoffee(value):
'''Returns input wrapped in HTML <b> tags'''
return '<b>%s</b>' % value
This is a custom template filter. It allows you run your code in the template:
{{ some_var|boldcoffee }}
If some_var is "blah" then the rendered output will be:
<b>blah</b>
You can check the built-in template tags and filters for example of what can be done with this technique.
This is the custom template tag which is provided by django.
You can make own template tag and filter in django.
So register is used to add your custom filter in library.