use slugify in template

10,071

Solution 1

This will generate the needed url:

{% for n in news %}
      <a href="{% url CompanyHub.views.getNews n.title|slugify n.pk %}" >{{n.description}}</a>
{% endfor %}

The examples above save slugify_field in database, as they later search for it. Otherwise in database you'll have a normal title, and slugified title in code for searching.. No easy way to compare them. But the way you've explained is simpler. You will have this kind of view:

def news(request, slug, news_id):
    news = News.objects.filter(pk=news_id)

UPDATE: To use unicode symbols in slugify, you'll need a conversion first. Look at this: How to make Django slugify work properly with Unicode strings?. It uses the Unidecode library

Then add a custom filter:

from unidecode import unidecode
from django.template.defaultfilters import slugify

def slug(value):
    return slugify(unidecode(value))

register.filter('slug', slug)

then in your template use this:

{% load mytags %}
<a href="{% url CompanyHub.views.getNews n.title|slug n.pk %}

Here is an example:

{{ "影師嗎 1 2 3"|slug}}

renders as:

ying-shi-ma-1-2-3

Solution 2

Have you tried n.title|slugify and see if that works for you.

ref: https://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#slugify

Note: although this is possible, just make sure the 'slugified' element is never used for any part of routing... (ie, purely for display only)

Share:
10,071

Related videos on Youtube

Asma Gheisari
Author by

Asma Gheisari

Updated on September 24, 2022

Comments

  • Asma Gheisari
    Asma Gheisari about 1 year

    I want to have SEO-friendly URL,my current url in urls.py :

    (ur'^company/news/(?P<news_title>.*)/(?P<news_id>\d+)/$','CompanyHub.views.getNews')
    

    I use it in template:

    {% for n in news %}
         <a href="{% url CompanyHub.views.getNews n.title,n.pk %}" >{{n.description}}</a>
    {% endfor %}
    

    I use news_id to get news object with that PK . I want to convert this url:

    ../company/news/tile of news,with comma/11
    

    to:

    ../company/news/tile-of-news-with-comma/11
    

    by doing some thing like this in template:

    {% for n in news %}
          <a href="{% url CompanyHub.views.getNews slugify(n.title),n.pk %}" >{{n.description}}</a>
    {% endfor %}
    

    I checked out these questions: question1 question2 question3 and this article but they save an slugify field in database while I wanna generate it on demand.in addition I want to run a query by news_id.

    I think this question is good,but I don't know how to use news_id to fetch my news object

    • Amber
      Amber over 11 years
      You may instead want to implement a permalink() method on your news objects. You can call slugify from there without having to worry about template syntax.
  • Asma Gheisari
    Asma Gheisari over 11 years
    slugify returns blank on it.maybe because title contains unicode characters
  • Jon Clements
    Jon Clements over 11 years
    @Asma I wouldn't have thought Unicode would be a problem... Umm, not sure what to suggest then - it should "just work"
  • Asma Gheisari
    Asma Gheisari over 11 years
    I don't know what U mean by Routing.title is just a part of url to make it SEO-friendly.
  • Jon Clements
    Jon Clements over 11 years
    @Asma that's fine - I just mean only use it for SEO friendly URL's... and not be dependant on it to match as part of a route in urls.py by itself
  • Asma Gheisari
    Asma Gheisari over 11 years
    as I said in before answer,title contains unicode string,so slugify doesn't work on it!
  • Asma Gheisari
    Asma Gheisari over 11 years
    tnx,I tryed it out.but I don't want to change my unicode characters,like your example that make those chinese characters to it's equal in english,I want when people enter those chinese words they can find it in search engine.
  • Tisho
    Tisho over 11 years
    Then you might need to write your own slug function, or to use urlencode() instead of unidecode() ... But you might have problems with non-ascii symbols in URL.