Skip to content

Commit

Permalink
Merge pull request #1414 from digi604/new_i18n
Browse files Browse the repository at this point in the history
Removes Multilingual Middleware and updates the i18n configuration of the cms. CMS_LANGUAGES has been completely overhauled and all the old i18n settings removed.
  • Loading branch information
digi604 committed Oct 3, 2012
2 parents 987d7de + 237609f commit 4b968ce
Show file tree
Hide file tree
Showing 82 changed files with 1,623 additions and 1,231 deletions.
6 changes: 3 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ python:
- "2.6"
- "2.7"
env:
- DJANGO="django>=1.3,<1.4"
- DJANGO="django>=1.4,<1.5"
- DJANGO=test_requirements/django-1.3.txt
- DJANGO=test_requirements/django-1.4.txt
install:
- pip install -q $DJANGO django-mptt==0.5.1 django-reversion==1.6 django-classy-tags==0.3.4.1 django-sekizai==0.6.1 html5lib==0.95 jinja2==2.6 PIL==1.1.7 pygments==1.5 south==0.7.5 sphinx==1.1.3 argparse
- pip install -q -r $DJANGO --use-mirrors
script:
python runtests.py
notifications:
Expand Down
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Contributors (in alphabetical order):
* Ian Lewis
* indexofire
* Ionel Cristian Maries
* Iván Raskovsky
* Ivan Vershigora
* izi
* Jameel Al-Aziz
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@

- fixed an incompatibility with Python 2.5

==== 2.4.0 ===-

- CMS_LANGUAGE setting has changed
- CMS_HIDE_UNTRANSLATED setting removed
- CMS_LANGUAGE_FALLBACK setting removed
- CMS_LANGUAGE_CONF setting removed
- CMS_SITE_LANGUAGES setting removed
- CMS_FRONTEND_LANGUAGES setting removed
- MultilingualMiddleware has been removed




Expand Down
13 changes: 4 additions & 9 deletions cms/admin/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from cms.forms.widgets import UserSelectAdminWidget
from cms.models import (Page, PagePermission, PageUser, ACCESS_PAGE,
PageUserGroup)
from cms.utils.i18n import get_language_tuple, get_language_list
from cms.utils.mail import mail_page_user_change
from cms.utils.page import is_valid_page_slug
from cms.utils.page_resolver import get_page_from_path, is_valid_url
Expand Down Expand Up @@ -60,7 +61,7 @@ class PageAddForm(forms.ModelForm):
help_text=_('The default title'))
slug = forms.CharField(label=_("Slug"), widget=forms.TextInput(),
help_text=_('The part of the title that is used in the URL'))
language = forms.ChoiceField(label=_("Language"), choices=settings.CMS_LANGUAGES,
language = forms.ChoiceField(label=_("Language"), choices=get_language_tuple(),
help_text=_('The current language of the content fields.'))

class Meta:
Expand All @@ -74,13 +75,7 @@ def __init__(self, *args, **kwargs):
if not self.fields['site'].initial:
self.fields['site'].initial = Site.objects.get_current().pk
site_id = self.fields['site'].initial
languages = []
language_mappings = dict(settings.LANGUAGES)
if site_id in settings.CMS_SITE_LANGUAGES:
for lang in settings.CMS_SITE_LANGUAGES[site_id]:
languages.append((lang, language_mappings.get(lang, lang)))
else:
languages = settings.CMS_LANGUAGES
languages = get_language_tuple(site_id)
self.fields['language'].choices = languages
if not self.fields['language'].initial:
self.fields['language'].initial = get_language()
Expand Down Expand Up @@ -139,7 +134,7 @@ def clean_slug(self):

def clean_language(self):
language = self.cleaned_data['language']
if not language in dict(settings.CMS_LANGUAGES).keys():
if not language in get_language_list():
raise ValidationError("Given language does not match language settings.")
return language

Expand Down
24 changes: 7 additions & 17 deletions cms/admin/pageadmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from cms.utils import (copy_plugins, helpers, moderator, permissions, plugins,
get_template_from_request, get_language_from_request,
placeholder as placeholder_utils, admin as admin_utils, cms_static_url)
from cms.utils.i18n import get_language_dict, get_language_list, get_language_tuple, get_language_object
from cms.utils.page_resolver import is_valid_url
from cms.utils.admin import jsonify_request
from cms.utils.permissions import has_plugin_permission
Expand Down Expand Up @@ -441,13 +442,13 @@ def get_form(self, request, obj=None, **kwargs):
installed_plugins = plugin_pool.get_all_plugins(placeholder_name, obj)
plugin_list = CMSPlugin.objects.filter(language=language, placeholder=placeholder, parent=None).order_by('position')
other_plugins = CMSPlugin.objects.filter(placeholder=placeholder, parent=None).exclude(language=language)
dict_cms_languages = dict(settings.CMS_LANGUAGES)
dict_cms_languages = get_language_dict()
for plugin in other_plugins:
if (not plugin.language in copy_languages) and (plugin.language in dict_cms_languages):
copy_languages[plugin.language] = dict_cms_languages[plugin.language]

language = get_language_from_request(request, obj)
if copy_languages and len(settings.CMS_LANGUAGES) > 1:
if copy_languages and len(get_language_list()) > 1:
show_copy = True
widget = PluginEditor(attrs={
'installed': installed_plugins,
Expand Down Expand Up @@ -566,14 +567,7 @@ def _get_site_languages(self, obj):
site_id = None
if obj:
site_id = obj.site_id
languages = []
if site_id and site_id in settings.CMS_SITE_LANGUAGES:
for lang in settings.CMS_SITE_LANGUAGES[site_id]:
lang_label = dict(settings.CMS_LANGUAGES).get(lang, dict(settings.LANGUAGES).get(lang, lang))
languages.append((lang, lang_label))
else:
languages = settings.CMS_LANGUAGES
return languages
return get_language_tuple(site_id)

def update_language_tab_context(self, request, obj, context=None):
if not context:
Expand Down Expand Up @@ -676,11 +670,7 @@ def changelist_view(self, request, extra_context=None):
site_id = int(site_id)

# languages
languages = []
if site_id and site_id in settings.CMS_SITE_LANGUAGES:
languages = settings.CMS_SITE_LANGUAGES[site_id]
else:
languages = [lang[0] for lang in settings.CMS_LANGUAGES]
languages = get_language_list(site_id)

# parse the cookie that saves which page trees have
# been opened already and extracts the page ID
Expand Down Expand Up @@ -986,7 +976,7 @@ def delete_translation(self, request, object_id, extra_context=None):
raise PermissionDenied

message = _('Title and plugins with language %(language)s was deleted') % {
'language': [name for code, name in settings.CMS_LANGUAGES if code == language][0]
'language': get_language_object(language)['name']
}
self.log_change(request, titleobj, message)
self.message_user(request, message)
Expand Down Expand Up @@ -1189,7 +1179,7 @@ def copy_plugins(self, request):

if not page.has_change_permission(request):
return HttpResponseForbidden(ugettext("You do not have permission to change this page"))
if not language or not language in [ lang[0] for lang in settings.CMS_LANGUAGES ]:
if not language or not language in get_language_list():
return HttpResponseBadRequest(ugettext("Language must be set to a supported language!"))
if language == copy_from:
return HttpResponseBadRequest(ugettext("Language must be different than the copied language!"))
Expand Down
5 changes: 3 additions & 2 deletions cms/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
calling these methods!
"""
import datetime
from cms.utils.i18n import get_language_list

from django.conf import settings
from django.contrib.auth.models import User
Expand Down Expand Up @@ -125,7 +126,7 @@ def create_page(title, template, language, menu_title=None, slug=None,
assert template in [tpl[0] for tpl in settings.CMS_TEMPLATES]

# validate language:
assert language in [lang[0] for lang in settings.CMS_LANGUAGES]
assert language in get_language_list()

# set default slug:
if not slug:
Expand Down Expand Up @@ -220,7 +221,7 @@ def create_title(language, title, page, menu_title=None, slug=None,
See docs/extending_cms/api_reference.rst for more info
"""
# validate language:
assert language in [lang[0] for lang in settings.CMS_LANGUAGES]
assert language in get_language_list()

# validate page
assert isinstance(page, Page)
Expand Down
3 changes: 2 additions & 1 deletion cms/app_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
class CMSApp(object):
name = None
urls = None
menus = []
menus = []
app_name = None
2 changes: 1 addition & 1 deletion cms/apphook_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def register(self, app):
"but the 'menus' attribute is empty, did you make a typo?")
name = app.__name__
if name in self.apps.keys():
raise AppAlreadyRegistered, "[%s] an cms app with this name is already registered" % name
raise AppAlreadyRegistered, "[%s] a cms app with this name is already registered" % name
self.apps[name] = app

def get_apphooks(self):
Expand Down
124 changes: 69 additions & 55 deletions cms/appresolver.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import with_statement
from cms.apphook_pool import apphook_pool
from cms.utils.i18n import force_language, get_language_list
from cms.utils.moderator import get_page_queryset

from django.conf import settings
Expand All @@ -10,6 +12,7 @@
RegexURLPattern
from django.db.models import Q
from django.utils.importlib import import_module
from django.utils.translation import get_language

APP_RESOLVERS = []

Expand All @@ -18,8 +21,8 @@ def clear_app_resolvers():
APP_RESOLVERS = []

def applications_page_check(request, current_page=None, path=None):
"""Tries to find if given path was resolved over application.
Applications have higher priority than other cms pages.
"""Tries to find if given path was resolved over application.
Applications have higher priority than other cms pages.
"""
if current_page:
return current_page
Expand All @@ -28,6 +31,9 @@ def applications_page_check(request, current_page=None, path=None):
# This removes the non-CMS part of the URL.
path = request.path.replace(reverse('pages-root'), '', 1)
# check if application resolver can resolve this
for lang in get_language_list():
if path.startswith(lang + "/"):
path = path[len(lang + "/"):]
for resolver in APP_RESOLVERS:
try:
page_id = resolver.resolve_page_id(path)
Expand All @@ -46,30 +52,44 @@ def applications_page_check(request, current_page=None, path=None):

class AppRegexURLResolver(RegexURLResolver):
page_id = None
url_patterns = None

url_patterns_dict = {}

@property
def url_patterns(self):
language = get_language()
if language in self.url_patterns_dict:
return self.url_patterns_dict[language]
else:
return []

def resolve_page_id(self, path):
"""Resolves requested path similar way how resolve does, but instead
of return callback,.. returns page_id to which was application
of return callback,.. returns page_id to which was application
assigned.
"""
tried = []
match = self.regex.search(path)
if match:
new_path = path[match.end():]
for pattern in self.url_patterns:
try:
sub_match = pattern.resolve(new_path)
except Resolver404, e:
if 'tried' in e.args[0]:
tried.extend([(pattern.regex.pattern + ' ' + t) for t in e.args[0]['tried']])
elif 'path' in e.args[0]:
tried.extend([(pattern.regex.pattern + ' ' + t) for t in e.args[0]['path']])
if isinstance(pattern, AppRegexURLResolver):
try:
return pattern.resolve_page_id(new_path)
except Resolver404:
pass
else:
if sub_match:
return pattern.page_id
tried.append(pattern.regex.pattern)
raise Resolver404, {'tried': tried, 'path': new_path}
try:
sub_match = pattern.resolve(new_path)
except Resolver404, e:
if 'tried' in e.args[0]:
tried.extend([[pattern] + t for t in e.args[0]['tried']])
elif 'path' in e.args[0]:
tried.extend([[pattern] + t for t in e.args[0]['path']])
else:
if sub_match:
return pattern.page_id
tried.append(pattern.regex.pattern)
raise Resolver404, {'tried': tried, 'path': new_path}


def recurse_patterns(path, pattern_list, page_id):
Expand Down Expand Up @@ -117,7 +137,7 @@ def get_app_urls(urls):
yield getattr(mod, 'urlpatterns')
else:
yield urlconf


def get_patterns_for_title(path, title):
"""
Expand All @@ -138,12 +158,12 @@ def get_patterns_for_title(path, title):
def get_app_patterns():
"""
Get a list of patterns for all hooked apps.
How this works:
By looking through all titles with an app hook (application_urls) we find all
urlconf modules we have to hook into titles.
If we use the ML URL Middleware, we namespace those patterns with the title
language.
Expand All @@ -156,54 +176,48 @@ def get_app_patterns():
except Site.DoesNotExist:
current_site = None
included = []

# we don't have a request here so get_page_queryset() can't be used,
# so, if CMS_MODERATOR, use, public() queryset, otherwise
# use draft(). This can be done, because url patterns are used just
# so, if CMS_MODERATOR, use, public() queryset, otherwise
# use draft(). This can be done, because url patterns are used just
# in frontend
is_draft = not settings.CMS_MODERATOR

title_qs = Title.objects.filter(page__publisher_is_draft=is_draft, page__site=current_site)

if 'cms.middleware.multilingual.MultilingualURLMiddleware' in settings.MIDDLEWARE_CLASSES:
use_namespaces = True
hooked_applications = {}
else:
use_namespaces = False
hooked_applications = []


hooked_applications = {}

# Loop over all titles with an application hooked to them
for title in title_qs.exclude(application_urls=None).exclude(application_urls='').select_related():
path = title.path
if use_namespaces:
mixid = "%s:%s:%s" % (path + "/", title.application_urls, title.language)
else:
mixid = "%s:%s" % (path + "/", title.application_urls)
if mixid in included:
mix_id = "%s:%s:%s" % (path + "/", title.application_urls, title.language)
if mix_id in included:
# don't add the same thing twice
continue
continue
if not settings.APPEND_SLASH:
path += '/'
if use_namespaces:
if title.language not in hooked_applications:
hooked_applications[title.language] = []
hooked_applications[title.language] += get_patterns_for_title(path, title)
if title.page_id not in hooked_applications:
hooked_applications[title.page_id] = {}
app = apphook_pool.get_apphook(title.application_urls)
if app.app_name:
inst_ns = title.page.reverse_id if title.page.reverse_id else app.app_name
app_ns = app.app_name, inst_ns
else:
hooked_applications += get_patterns_for_title(path, title)
included.append(mixid)
app_ns = None, None
with force_language(title.language):
hooked_applications[title.page_id][title.language] = (app_ns, get_patterns_for_title(path, title))
included.append(mix_id)
# Build the app patterns to be included in the cms urlconfs
app_patterns = []
if use_namespaces:
for ns, currentpatterns in hooked_applications.items():
extra_patterns = patterns('', *currentpatterns)
resolver = AppRegexURLResolver(r'', 'app_resolver', namespace=ns)
resolver.url_patterns = extra_patterns
app_patterns.append(resolver)
APP_RESOLVERS.append(resolver)
else:
extra_patterns = patterns('', *hooked_applications)
resolver = AppRegexURLResolver(r'', 'app_resolver')
resolver.url_patterns = extra_patterns
for page_id in hooked_applications.keys():
resolver = None
for lang in hooked_applications[page_id].keys():
(app_ns, inst_ns), current_patterns = hooked_applications[page_id][lang]
if not resolver:
resolver = AppRegexURLResolver(r'', 'app_resolver', app_name=app_ns, namespace=inst_ns)
resolver.page_id = page_id
extra_patterns = patterns('', *current_patterns)
resolver.url_patterns_dict[lang] = extra_patterns
app_patterns.append(resolver)
APP_RESOLVERS.append(resolver)
return app_patterns
return app_patterns
Loading

1 comment on commit 4b968ce

@ojii
Copy link
Contributor

@ojii ojii commented on 4b968ce Oct 3, 2012

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be really cool if you didn't just merge your own pull requests, especially big ones like this...

Please sign in to comment.