1Tools for using Babel with Django 2================================= 3 4This package contains various utilities for integration of `Babel`_ into the 5`Django`_ web framework: 6 7 * A message extraction plugin for Django templates. 8 * A middleware class that adds the Babel `Locale`_ object to requests. 9 * A set of template tags for date and number formatting. 10 11 12Extracting Messages 13------------------- 14 15Babel provides a message extraction framework similar to GNU ``xgettext``, but 16more extensible and geared towards Python applications. While Django does 17provide `wrapper scripts`_ for making the use of ``xgettext`` more 18convenient, the extraction functionality is rather limited. For example, you 19can't use template files with an extension other than ``.html``, and everything 20needs to be in your project package directory. 21 22Extraction Method Mapping 23^^^^^^^^^^^^^^^^^^^^^^^^^ 24 25So enmerkar comes with an extraction method plugin that can extract 26localizable messages from Django template files. Python is supported out of the 27box by Babel. To use this extraction functionality, create a file called 28``babel.cfg`` in your project directory (the directory above your project 29package), with the content: 30 31.. code-block:: ini 32 33 [django: templates/**.*] 34 [django: mypkg/*/templates/**.*] 35 [python: mypkg/**.py] 36 37This instructs Babel to look for any files in the top-level ``templates`` 38directory, or any files in application ``templates`` directories, and use the 39extraction method named “django” to extract messages from those template files. 40You'll need to adjust those glob patterns to wherever you my be storing your 41templates. 42 43Also, any files with the extension ``.py`` inside your package directory (replace 44“mypkg” with the actual name of your Django project package) are processed by 45the “python” extraction method. 46 47If you don't use setuptools, or for some reason haven't installed enmerkar 48using setuptools/pip, you'll need to define what function the extraction method 49“django” maps to. This is done in an extra section at the top of the 50configuration file: 51 52.. code-block:: ini 53 54 [extractors] 55 django = enmerkar.extract:extract_django 56 57The encoding of the templates is assumed to be UTF-8. If you are using a 58different encoding, you will need to specify it in the configuration. For 59example: 60 61.. code-block:: ini 62 63 [django: templates/**.*] 64 encoding = iso-8859-1 65 66 67Running the Extraction Process 68^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 69 70Once you've set up the configuration file, the actual extraction is performed 71by executing the command-line program ``pybabel`` which is installed alongside 72the Babel package: 73 74.. code-block:: bash 75 76 $ cd projectdir 77 $ pybabel extract -F babel.cfg -o mypkg/locale/django.pot . 78 79This creates the PO file template in ``mypkg/locale/django.pot``. 80 81 82Creating and Updating Translations Catalogs 83^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 84 85If you don't already have translation catalogs, you need to create them. This 86is done using the ``pybabel init`` command: 87 88.. code-block:: bash 89 90 $ pybabel init -D django -i mypkg/locale/django.pot -d mypkg/locale -l en_US 91 $ pybabel init -D django -i mypkg/locale/django.pot -d mypkg/locale -l de_DE 92 93This should create two files: ``mypkg/locale/en_US/django.po`` and 94``mypkg/locale/de_DE/django.po``. These files are where you put the actual 95translations. 96 97When you modify your Python source files or your templates, you genereally need 98to sync the translation catalogs. For that, you first perform a fresh 99extraction as described in the previous section, so that the ``django.pot`` file 100gets updated. 101 102Then, you run the ``pybabel update`` command to merge the changes into the 103translation catalogs: 104 105```bash 106$ pybabel update -D django -i mypkg/locale/django.pot -d mypkg/locale 107``` 108 109This will update all the ``.po`` files found in the ``mypkg/locale`` directory. 110 111 112Compiling Translations Catalogs 113^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 114 115Finally, you need to compile those ``.po`` files to binary ``.mo`` files. Use the 116`pybabel compile` command for that: 117 118.. code-block:: bash 119 120 $ pybabel compile -D django -d mypkg/locale 121 122Add the ``--statistics`` option to get information about the completeness of your 123translations: 124 125.. code-block:: bash 126 127 $ pybabel compile -D django -d mypkg/locale --statistics 128 129 130Using ``setup.py`` 131^^^^^^^^^^^^^^^^^^ 132 133Much of the above process can be automated if you add a ``setup.py`` script to 134your project and use the distutils/setuptools commands that come with Babel. 135This is described at `Distutils/Setuptools Integration`_. 136 137 138Using the Middleware 139-------------------- 140 141To use the enmerkar middleware, add it to the list of ``MIDDLEWARE_CLASSES`` in your 142settings module. If you're also using Django's own ``LocaleMiddleware`` to vary 143the locale based on user preference, the enmerkar middleware must be inserted 144after the Django one: 145 146.. code-block:: python 147 148 MIDDLEWARE_CLASSES = ( 149 ... 150 'django.middleware.locale.LocaleMiddleware', 151 'enmerkar.middleware.LocaleMiddleware', 152 ... 153 ) 154 155This adds a ``locale`` attribute to the request object, which is an instance of 156the Babel ``Locale`` class. You can access the locale via ``request.locale`` when 157the request object is available, or otherwise use the 158``django_babel.middleware.get_current_locale()`` function to get the current 159locale from a thread-local cache. 160 161 162Using the Template Tags 163----------------------- 164 165The template filters provided by enmerkar allow formatting of date/time and 166number values in a locale-sensitive manner, providing much more powerful 167alternatives to the ``date``, ``time``, and ``floatformat`` filters that come with 168Django. 169 170To make the template filters/tags available, you need to add enmerkar to 171the list of ``INSTALLED_APPS`` in your settings module: 172 173.. code-block:: python 174 175 INSTALLED_APPS = ( 176 ... 177 'enmerkar', 178 ... 179 ) 180 181And in every template you want to use the filters, you need to explicitly load 182the library: 183 184.. code-block:: django 185 186 {% load babel %} 187 188General information on date/time and number formatting can be found at 189`Date Formatting`_ and `Number Formatting`_. 190 191The following filters are made available. The examples assume a locale of 192``en_US``. 193 194 195``datefmt`` 196^^^^^^^^^^^ 197 198Renders a string representation of a date. 199 200* **Input**: ``datetime.date``, ``datetime.datetime``, or a float/int timestamp 201* **Parameters**: the format name or pattern (optional) 202 203Assuming that ``book.pubdate`` returns a ``datetime.date`` or 204``datetime.datetime`` object: 205 206.. code-block:: django 207 208 {{ book.pubdate|datefmt:"short" }} 209 210would render: **4/1/07**, and 211 212.. code-block:: django 213 214 {{ book.pubdate|datefmt:"E, MMM dd yyyy GGG" }} 215 216would render: **Sun, Apr 01 2007 AD** 217 218``datetimefmt`` 219^^^^^^^^^^^^^^^ 220 221Renders a string representation of a date and time. 222 223* **Input**: ``datetime.datetime``, or a float/int timestamp 224* **Parameters**: the format name or pattern (optional) 225 226Examples: 227 228.. code-block:: django 229 230 {{ book.pubdate|datetimefmt:"short" }} 231 232would render: **4/1/07 3:30 PM**, and 233 234.. code-block:: django 235 236 {{ book.pubdate|datetimefmt:"E, MMM dd yyyy GGG' - 'HH:mm:ss'" }} 237 238would render: **Sun, Apr 01 2007 AD - 15:30:00** 239 240``timefmt`` 241^^^^^^^^^^^ 242 243Renders a string representation of a time. 244 245* **Input**: ``datetime.datetime``, ``datetime.time``, or a float/int timestamp 246* **Parameters**: the format name or pattern (optional) 247 248Examples: 249 250.. code-block:: django 251 252 {{ book.pubdate|timefmt:"short" }} 253 254would render: **3:30 PM**, and 255 256.. code-block:: django 257 258 {{ book.pubdate|timefmt:"h 'o''clock' a'" }} 259 260would render: **3 o'clock PM** 261 262``decimalfmt`` 263^^^^^^^^^^^^^^ 264 265Renders a string representation of a decimal number. 266 267* **Input**: a `Decimal` object, or a float/int/long value 268* **Parameters**: the format name or pattern (optional) 269 270Examples: 271 272.. code-block:: django 273 274 {{ book.pagecount|decimalfmt }} 275 276would render: **1,234**, and 277 278.. code-block:: django 279 280 {{ book.pagecount|decimalfmt:"#,##0.00" }} 281 282would render: **1,234.00** 283 284``currencyfmt`` 285^^^^^^^^^^^^^^^ 286 287Renders a number formatted as a currency value. 288 289* **Input**: a ``Decimal`` object, or a float/int/long value 290* **Parameters**: the currency code 291 292Examples: 293 294.. code-block:: django 295 296 {{ book.price|currencyfmt:"USD" }} 297 298would render: **$49.90** 299 300``percentfmt`` 301^^^^^^^^^^^^^^ 302 303Renders a string representation of a number as a percentage. 304 305* **Input**: a ``Decimal`` object, or a float/int/long value 306* **Parameters**: the format name or pattern (optional) 307 308Examples: 309 310Assuming ``book.rebate`` would return ``0.15``, 311 312.. code-block:: django 313 314 {{ book.rebate|percentfmt }} 315 316would render **15%**, and 317 318.. code-block:: django 319 320 {{ book.rebate|percentfmt:"#,##0.00%" }} 321 322would render **15.00%**. 323 324``scientificfmt`` 325^^^^^^^^^^^^^^^^^ 326 327Renders a string representation of a number using scientific notation. 328 329* **Input**: a ``Decimal`` object, or a float/int/long value 330* **Parameters**: none 331 332Examples: 333 334Assuming ``book.numsold`` would return 1.000.000, 335 336.. code-block:: django 337 338 {{ book.numsold|scientificfmt }} 339 340would render **10E5**. 341 342 343 344.. _Babel: http://babel.pocoo.org/ 345.. _Django: https://www.djangoproject.com/ 346.. _wrapper scripts: https://docs.djangoproject.com/en/dev/topics/i18n/translation/#localization-how-to-create-language-files 347.. _Distutils/Setuptools Integration: http://babel.pocoo.org/en/stable/setup.html 348.. _Date Formatting: http://babel.pocoo.org/en/stable/dates.html 349.. _Number Formatting: http://babel.pocoo.org/en/stable/numbers.html 350.. _Locale: http://babel.pocoo.org/en/stable/api/core.html#babel.core.Locale 351