django 'urlize' strings form text just like twitter - django

heyy there
i want to parse a text,let's name it 'post', and 'urlize' some strings if they contain a particular character, in a particular position.
my 'pseudocode' trial would look like that:
def urlize(post)
for string in post
if string icontains ('#')
url=(r'^searchn/$',
searchn,
name='news_searchn'),
then apply url to the string
return urlize(post)
i want the function to return to me the post with the urlized strings, where necessary (just like twitter does).
i don't understand: how can i parse a text, and search for certain strings?
is there ok to make a function especially for 'urlizing' some strings? The function should return the entire post, no matter if it has such kind of strings.
is there another way Django offers?
Thank you

First, I guess you mostly need this function in templates (you want to present the post "urlized").
There's the built-in template tag urlize, which is used like
{{ value|urlize }}
which takes a string value and returns it with links.
If you want to customize the logic, you can create your own template tag.
EDIT:
To find the # words you can use a simple regex search:
import re
a = "hello #world. foo #bar! #foo_bar"
re.findall("#(\w+)",a)
>> ['world', 'bar', 'foo_bar']

Related

Django: Refer to an url name in a template and passing parameter

I know you can refer to a urlname in a template so that you don't need to hardcode your url links in your templates whenever you want to change them.
For example in a template, I use:
The link
My problem is, if I want to pass a more complex parameter to be used in the url regex. In my case, I want to pass a concatenation of two strings separated by an "_". Those strings come from Python objects and I don't get how to do that. Let's say for example, those strings are the firstname and lastname of a user.
I tried:
The link
And others tricks but none worked.
Can someone help?
Simply, you don't.
You either adjust your url to have two capture groups (which would also require a slight change to the view)
url(r'(?P<first_name>\w+)_(?P<last_name>\w+)/$', view_name, name='url_name')
{% url 'urlname' user.firstname user.lastname %}
Or you just find a different url that suffices.
Please have a look at this thread. The good answer for you, assuming you're using posititionnal arguments :
The link
Assuming your url conf is like so :
url(r'^urlname/(?P<parameter>(catching regexp))$',...)

Django HTML truncation

I'm using the build-in truncatewords_html filter of Django and it adds "..." in the end, instead, I want to replace this with a link "See More".
How can I achieve this?
It would be best to write your own filter. You could take the source code for truncatewords_html and use it as a template for your filter. It should take a few changes to get what you want, and then you will just need to register your template and make sure you load it on the page you want to use it on and you should be good.
See this page for more info
https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
https://code.djangoproject.com/browser/django/trunk/django/template/defaultfilters.py#L288
You should be able to copy the method and just change the Code to this.
return Truncator(value).words(length, html=True, truncate=' see more')
You want to make 'see more' a link, that will take more code. I would change the filter to accept another param which is the link for 'see more'.
Then instead of just having 'see more' passed to Truncator you would pass the HTML link.
If you wanted to pass a custom link, that could be done like this.
Define your custom filter:
from django import template
from django.utils.safestring import mark_safe
from django.utils.text import truncate_html_words
register = template.Library()
#register.filter
def truncatewords_html_with_link(value, arg):
"""
Truncates HTML after a certain number of words and concatenates a link
Argument: String - Number of words to truncate after and the link,
separated by a comma
"""
arg_list = arg.split(',')
try:
length = int(arg_list[0])
except ValueError:
return value
return mark_safe(truncate_html_words(value, length, arg_list[1]))
Call it from your template:
{{ text|truncatewords_html_with_link:"5, <a class=\"read-more\" href=\"/your_url/\">Read More</a>" }}
The relevant code in Django 1.8 reads:
truncate = pgettext(
'String to return when truncating text',
'%(truncated_text)s...')
If you are using LOCALE and translation files, place the following into your *.po files:
msgid "String to return when truncating text"
msgstr "Short version: %(truncated_text)s <a class='see-more-link'>see more</a>"
Though, depending on what should happen when you click on the link adding it that way might not be very helpful. You could use another placeholder for it, but then you would have to make sure to replace the placeholder whereever this message string is used.

Parse request URL in JSTL

I want to display a specific message based on the URL request on a JSP.
the request URL can be:
/app/cars/{id}
OR
/app/people/{id}
On my messages.properties I've got:
events.action.cars=My car {0} event
events.action.people=My person {1} event
Finally, on my JSP page I want to have the following code:
<spring:message code="events.${element.cause}.${?????}"
arguments="${element.param['0']},${element.param['1']}"/>
I need help figuring out which expression I could use to parse the request URL and obtain the word before the ID.
You can access the request URI in JSTL (actually: EL) as follows:
${pageContext.request.requestURI}
(which thus returns HttpServletRequest#getRequestURI())
Then, to determine it, you'll have to play a bit round with JSTL functions taglib. It offers several string manipulation methods like split(), indexOf(), substringAfter(), etc. No, no one supports regex. Just parse it.
Kickoff example:
<c:set var="pathinfo" value="${fn:split(pageContext.request.requestURI, '/')}" />
<c:set var="id" value="${pathinfo[pathinfo.length - 1]}" />
And use it as ${id}.
/app/(cars|people)/([^/]*)$
will put cars or people in backreference \1, depending on the match, and whatever is left right of the last slash in backreference \2.
My solution so far is to have a RequestUtils class that match the regex ".?/jsp/(\w+)/..jsp" and return the group(1).
in my Jsp I got:
<% request.setAttribute("entity", RequestUtils.getEntityURI(request)); %>
<spring:message code="events.${element.cause}.${entity}"
arguments="${element.param['0']},${element.param['1']}"/>
this of course did the trick. But still it would be better not to have any Java code within the JSP.
If I understand you correctly, I think you need to do something like this:
#RequestMapping(value="/owners/{ownerId}", method=RequestMethod.GET)
public String findOwner(#PathVariable String ownerId, Model model) {
model.addAttribute("ownerId", ownerId);
return "myview";
}
As you can see, here the ownerId is read from the URL by Spring MVC. After that, you simply put the variable in the Model map so you can use it in your JSP.

How do you mark strings as "Safe" in a view (or the template) in Jinja2?

Typically when you want to mark string output as safe in Jinja2 you do something like this:
{{ output_string|safe() }}
However, what if output_string is always safe? I don't want to repeat myself every time by using the safe filter.
I have a custom filter called "emailize" that preps urls for output in an email. The ampersands always seem to become escaped. Is there a way in my custom filter to mark the output as safe?
Check SafeString, like for example:
from django.utils.safestring import SafeString
...
return context.update({
'html_string': SafeString(html_string),
})
Use the Markup class:
class jinja2.Markup([string])
Marks a string as being safe for inclusion in HTML/XML output without needing to be escaped.

Django view returns string which is not represented correctly in html template

A view I am using returns a string to a html template. The string which is returned contains special characters which are not represented correctly in the template. To put it simply a string which is returned from the view might look like this:
test = "\"Foo bar\""
return render_to_response('index.html', {'test': test})
And is displayed in the html template like this:
& quot;Foo bar& quot;
How can I fix the encoding so it is displayed correctly?
Use the safe filter when printing:
{{ test|safe }}
Or, do this in the view:
from django.utils.safestring import mark_safe
test = mark_safe("\"Foo bar\"")
Please note that by doing this you are telling Django that the contents of the string are safe and do not need HTML escaping. If you are planning to put anything whatsoever that could come from the user this would then leave you vulnerable to XSS attacks, so use with caution.
Your best bet is to consult the Django documentation, which explains this in detail:
https://docs.djangoproject.com/en/2.0/ref/templates/language/#automatic-html-escaping