{ "info": { "author": "Jonathan Ellenberger", "author_email": "jonathan_ellenberger@wgbh.org", "bugtrack_url": null, "classifiers": [ "Framework :: Django" ], "description": "# django-multilingualfield #\n\n## About ##\n\nA [south](http://south.aeracode.org/)-compatible suite of django fields that make it easy to manage multiple translations of text-based content (including files/images).\n\n### Current Version ###\n\n0.3\n\n## Installation ##\n\nInstallation is easy with [pip](https://pypi.python.org/pypi/pip):\n\n```bash\n$ pip install django-multilingualfield\n```\n\n### Requirements ###\n\n`django-multilingualfield` will install the following dependencies:\n\n* `django-classy-tags` >= 0.3.4.1\n* `lxml` >= 3.1.2\n\n### Settings ###\n\nTo use `django-multilingualfield`, first add `multilingualfield` to `INSTALLED_APPS`:\n\n```python\nINSTALLED_APPS += ('multilingualfield')\n```\n\nSecondly, make sure that [`LANGUAGES`](https://docs.djangoproject.com/en/dev/ref/settings/#languages) is properly defined in your settings file.\n\nIf you don't have [`LANGUAGE_CODE`](https://docs.djangoproject.com/en/dev/ref/settings/#language-code) set in your settings file it will default to 'en-us' (U.S. English). It is recommended you manually set [`LANGUAGE_CODE`](https://docs.djangoproject.com/en/dev/ref/settings/#language-code) (even if you are keeping the default value of 'en-us') *IN ADDITION TO* adding an entry for that language code (as the _first_ language) in [`LANGUAGES`](https://docs.djangoproject.com/en/dev/ref/settings/#languages). Here's an example:\n\n```python\nLANGUAGE_CODE = 'en'\n\nLANGUAGES = [\n ('en', 'English'),\n ('es', 'Español') # See note below note\n]\n```\n> #### NOTE ####\n> `ñ` is the UTF8 encoding for '\u00f1'\n\nIf you'd like to use MultiLingual* fields in templates you'll need django's `'django.middleware.locale.LocalMiddleware'` added to your [`MIDDLEWARE_CLASSES`](https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-MIDDLEWARE_CLASSES) setting and `'django.core.context_processors.i18n'` added to your [`TEMPLATE_CONTEXT_PROCESSORS`](https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-TEMPLATE_CONTEXT_PROCESSORS) setting:\n\n```python\nMIDDLEWARE_CLASSES += (\n 'django.middleware.locale.LocaleMiddleware',\n)\n\nTEMPLATE_CONTEXT_PROCESSORS += (\n 'django.core.context_processors.i18n',\n)\n```\n\n> #### NOTE ####\n> django-multilingualfield uses [`django.utils.translation.get_language`](https://docs.djangoproject.com/en/dev/ref/utils/#django.utils.translation.get_language) to determine which translation to serve by default.\n> To better understand how Django determines language preference read the aptly titled ['How Django discovers language preference'](https://docs.djangoproject.com/en/dev/topics/i18n/translation/#how-django-discovers-language-preference) section from the i18n topic page within the official django documentation.\n\n## Overview ##\n\ndjango has [excellent translation tools](https://docs.djangoproject.com/en/dev/topics/i18n/translation/) but a recent project at WGBH required manually-written translations for nearly all text & image content served by the site.\n\nI didn't want to create multiple `CharField`, `TextField` or `ImageField` attributes for each field that needed translations (i.e. 'title_en' and 'title_es') for multiple reasons:\n\n1. They'd be a giant pain to keep track of.\n2. Templates and/or views would be polluted with alot of crufty if/else statements.\n3. The site needed to launch with support for English and Spanish but I figured new languages would be added down the road and wanted to make any future additions as smooth as possible.\n\n### Available Fields ###\n\n`django-multilingualfield` contains three fields ready-for-use in your django project.\n\n1. `multilingualfield.fields.MultiLingualCharField`: Functionality mirrors that of django's `django.db.models.CharField`\n2. `multilingualfield.fields.MultiLingualTextField`: Functionality mirrors that of django's `django.db.models.TextField`\n2. `multilingualfield.fields.MultiLingualFileField`: Functionality mirrors that of django's `django.db.models.FileField`\n\nAt the database level, `MultiLingualCharField`, `MultiLingualTextField` and `MultiLingualFileField` are essentially identical in that their content is stored within 'text' columns (as opposed to either 'varchar' or 'text'); they diverge only in the widgets/forms they use.\n\nAny options you would pass to a `CharField`, `TextField` or `FileField` (i.e. `blank=True`, `max_length=50`, `upload_to='path/'`, `storage=StorageClass()`) will work as expected but `max_length` **will not be enforced at a database level** (only during form creation and input validation).\n\n## Examples ##\n\n### Model Example ###\n\nUse `MultiLingualCharField`, `MultiLingualTextField` and `MultiLingualFileField` just like you would any django field:\n\n```python\nfrom django.db import models\n\nfrom multilingualfield import fields as mlf_fields\n\nclass TestModel(models.Model):\n title = mlf_fields.MultiLingualCharField(\n max_length=180\n )\n short_description = mlf_fields.MultiLingualCharField(\n max_length=300\n )\n long_description = mlf_fields.MultiLingualTextField(\n blank=True,\n null=True\n )\n image = mlf_fields.MultiLingualFileField(\n upload_to='images/',\n blank=True,\n null=True\n )\n```\n\n`django-multilingualfield` is fully integrated with [south](http://south.aeracode.org/) so migrate to your heart's content!\n\n#### What's Stored In The Database ####\n\nIf `LANGUAGES` is set in your project's settings like this...\n\n```python\nLANGUAGES = [\n ('en', 'English'),\n ('es', 'Español')\n]\n```\n\n...then `django-multilingualfield` will store translations for a piece of text in a single 'text' db column as XML in the following structure:\n\n```xml\n\n \n Hello\n \n \n Hola\n \n\n```\n > ##### NOTE #####\n > The example above includes whitespace for readability, the final value stored in the database will have all between-tag whitespace removed.\n\n#### What's Served By The Application ####\n\nEven though `MultiLingualCharField` and `MultiLingualTextField` instances are stored in the database as XML they are served to the application as a python object. The above block of XML would return an instance of `multilingualfield.fields.MultiLingualText` with two attributes:\n\n* `en` (with a value of `u'Hello'`)\n* `es` (with a value of `u'Hola'`)\n\nThe translation corresponding to the current language of the active thread (as determined by calling [`django.utils.translation.get_language`](https://docs.djangoproject.com/en/dev/ref/utils/#django.utils.translation.get_language)) will be returned by directly accessing the field.\n\n#### Creating Instances in the Shell ####\n\nLet's create an instance of our above example model (`TestModel`) in the python shell:\n\n```bash\n$ python manage.py shell\n```\n\n```python\n>>> from testapp.models import TestModel\n>>> from multilingualfield.datastructures import MultiLingualText\n>>> title = MultiLingualText()\n>>> title.en = 'Hello'\n>>> title.es = 'Hola'\n>>> x = TestModel(title=title)\n>>> x.save()\n>>> x.title.en\nu'Hello'\n>>> x.title.es\nu'Hola'\n>>> x.title\nu'Hello'\n>>> from django.utils.translation import get_language, activate\n>>> get_language()\n'en-us'\n# NOTE: 'en-us' will ALWAYS be the current language in the active\n# thread when you load the python shell via manage.py. To learn why\n# visit: https://code.djangoproject.com/ticket/12131#comment:6\n>>> activate('en')\n>>> get_language()\n'en'\n>>> activate('es')\n>>> get_language()\n'es'\n>>> x.title\nu'Hola'\n>>> activate('en')\n>>> x.title\n'en'\n```\n\n### Admin Integration ###\n\nBoth `MultiLingualCharField` and `MultiLingualTextField` are admin-ready and will provide either a `TextInput` (for `MultiLingualCharField` instances) or `Textarea` (for `MultiLingualTextField` instances) field for each language listed in `settings.LANGUAGES`.\n\n#### Improved Admin Styling ####\n\nThe default formfields for MultiLingual* fields do not include admin-friendly styling so if you want them to look pretty within the admin you have a few options:\n\n1. Swap-out `admin.ModelAdmin` for `MultiLingualFieldModelAdmin` in your admin configs for models that have MultiLingual* fields:\n\n ```python\n # testapp.admin\n from django.contrib import admin\n\n from multilingualfield.admin import MultiLingualFieldModelAdmin\n\n from .models import TestModel\n\n\n class TestModelAdmin(MultiLingualFieldModelAdmin):\n \"\"\"\n Adds admin-friendly styling to all MultiLingual* fields\n for TestModel within the admin\n \"\"\"\n list_display = ('title',)\n\n admin.site.register(TestModel, TestModelAdmin)\n ```\n\n2. Manually specify MultiLingual* widgets with [`formfield_overrides`](https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.formfield_overrides):\n\n ```python\n # testapp.admin\n from django.contrib import admin\n\n from multilingualfield import widgets as mlf_widgets\n from multilingualfield import fields as mlf_fields\n\n from .models import TestModel\n\n\n class TestModelAdmin(admin.ModelAdmin):\n \"\"\"\n Adds admin-friendly styling to all MultiLingual* fields\n for TestModel via formfield_overrides\n \"\"\"\n list_display = ('title',)\n formfield_overrides = {\n mlf_fields.MultiLingualCharField: {\n 'widget': mlf_widgets.MultiLingualCharFieldDjangoAdminWidget\n },\n mlf_fields.MultiLingualTextField: {\n 'widget': mlf_widgets.MultiLingualTextFieldDjangoAdminWidget\n },\n }\n\n admin.site.register(TestModel, TestModelAdmin)\n ```\n\n3. Manually specify MultiLingual* widgets on a ModelForm subclass:\n\n ```python\n # testapp.forms\n from django.forms.models import ModelForm\n\n from multilingualfield import widgets as mlf_widgets\n\n from .models import TestModel\n\n\n class TestModelForm(ModelForm):\n\n class Meta:\n model = TestModel\n fields=(\n 'title',\n 'short_description',\n 'long_description'\n )\n widgets = {\n 'title': mlf_widgets.MultiLingualCharFieldDjangoAdminWidget,\n 'short_description': mlf_widgets.MultiLingualCharFieldDjangoAdminWidget,\n 'long_description': mlf_widgets.MultiLingualTextFieldDjangoAdminWidget\n }\n ```\n\n Integrating the custom form into your admin configuration:\n\n ```python\n # testapp.admin\n from django.contrib import admin\n\n from .forms import TestModelForm\n from .models import TestModel\n\n\n class TestModelAdmin(admin.ModelAdmin):\n \"\"\"\n Adds admin-friendly styling to all MultiLingual* fields\n via a custom form\n \"\"\"\n form = TestModelForm\n\n admin.site.register(TestModel, TestModelAdmin)\n ```\n\n### Template Example ###\n\nTemplate usage is simple & straight forward, here's an example template for how you might render a instance of `TestModel`:\n\n```python\n{% load i18n %}\n\n \n {{ object.title }}\n \n \n

{{ object.title }}

\n

{{ object.short_description }}

\n {% if object.long_description %}\n {{ object.long_description }}\n {% else %}\n {% trans 'No long description provided' %}\n {% endif %}\n \n\n```\n\n> #### NOTE ####\n> For more information about the `trans` templatetag used in the example above check out the [django docs](https://docs.djangoproject.com/en/dev/topics/i18n/translation/#trans-template-tag).\n\nThe example above is typical for most use cases (when you want to render values associated with the user's current language thread) but you always have access to the language-specific attributes:\n\n```html\n{% load i18n %}\n\n \n {{ object.title }}\n \n \n

{{ object.title }}

\n \n

{% trans 'Title (English)' %}: {{ object.title.en }}

\n\n \n

{% trans 'Title (Spanish)' %}: {{ object.title.es }}

\n\n

{{ object.short_description }}

\n {% if object.long_description %}\n {{ object.long_description }}\n {% else %}\n {% trans 'No long description provided' %}\n {% endif %}\n \n\n```", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/WGBH/django-multilingualfield/", "keywords": null, "license": "MIT License, see LICENSE", "maintainer": null, "maintainer_email": null, "name": "django-multilingualfield", "package_url": "https://pypi.org/project/django-multilingualfield/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/django-multilingualfield/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/WGBH/django-multilingualfield/" }, "release_url": "https://pypi.org/project/django-multilingualfield/0.3.1/", "requires_dist": null, "requires_python": null, "summary": "A south-compatible suite of django fields that make it easy to manage multiple translations of text-based content (including files/images).", "version": "0.3.1" }, "last_serial": 1281467, "releases": { "0.3": [ { "comment_text": "", "digests": { "md5": "9d92ab5ac47f2b84235e9e78e9b38d90", "sha256": "6f33072c1313215a656a4e9e47cd302422f6b740910b13e7f45debf4e3439f61" }, "downloads": -1, "filename": "django-multilingualfield-0.3.tar.gz", "has_sig": false, "md5_digest": "9d92ab5ac47f2b84235e9e78e9b38d90", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19502, "upload_time": "2014-04-24T00:04:16", "url": "https://files.pythonhosted.org/packages/8d/b0/e6a04334efbf8f72b946a57db30c46b12d5e6a434147e374eb72fec81784/django-multilingualfield-0.3.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "24e2805f5b57008198457b139dd731bc", "sha256": "059870879caf20cfa45043493db0e28ea6cfc16fb6e69dab09c5f754f2ba060d" }, "downloads": -1, "filename": "django-multilingualfield-0.3.1.tar.gz", "has_sig": false, "md5_digest": "24e2805f5b57008198457b139dd731bc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21045, "upload_time": "2014-10-24T14:39:07", "url": "https://files.pythonhosted.org/packages/c3/d8/f3192ab4e43660263ce52941137fb9f3e03f5927e33d79036ba171544cf8/django-multilingualfield-0.3.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "24e2805f5b57008198457b139dd731bc", "sha256": "059870879caf20cfa45043493db0e28ea6cfc16fb6e69dab09c5f754f2ba060d" }, "downloads": -1, "filename": "django-multilingualfield-0.3.1.tar.gz", "has_sig": false, "md5_digest": "24e2805f5b57008198457b139dd731bc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21045, "upload_time": "2014-10-24T14:39:07", "url": "https://files.pythonhosted.org/packages/c3/d8/f3192ab4e43660263ce52941137fb9f3e03f5927e33d79036ba171544cf8/django-multilingualfield-0.3.1.tar.gz" } ] }