In Django templates, you can use either {{ _("Hello World") }} or {% trans "Hello World" %} to mark strings to be translated. In docs, the “official” approach seems to be the {% trans %} tag, but the _() syntax is mentioned too once.
How these approaches differ (except syntax) and why should be one preferable rather than the other?
One difference is that you obviously can’t use {% trans %} with tags and filters. But does that mean that I can just use _() everywhere, like {{ _("String") }}? It works and looks much cleaner and more consistent than using {% trans "String" %} with standalone strings and _() with tags and filters.
So it seems that there’s technically no difference as of Django 1.5. Template engine internally marks a variable for translation (by setting its
translateattribute) in two cases:{% trans VAR %}(seeTranslateNode), or_(and ends with)(seeVariable.__init__).Later, when the variable is being resolved, Django wraps it with
ugettextorpgettextif it sees thetranslateattribute.However, as can be seen from source code, there are some flexibility considerations in favor of
{% trans %}tag:{% trans "String" noop %}, which will put the string for translation into .po files, but won’t actually translate the output when rendering (no internaltranslateattribute on variable, nougettextcall);{% trans "May" context "verb" %};{% trans "String" as.translated_string %}
* As of Django 1.4.
Please feel free to correct me or post a better answer in case I’m missing anything.