mirror of
https://github.com/Hopiu/wagtail-modeltranslation.git
synced 2026-03-17 06:20:33 +00:00
Compare commits
No commits in common. "master" and "v0.9.0" have entirely different histories.
31 changed files with 300 additions and 919 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -41,9 +41,3 @@ _build
|
|||
# vim
|
||||
*~
|
||||
*.swp
|
||||
|
||||
# vscode
|
||||
.vscode
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
|
|
|||
61
.travis.yml
61
.travis.yml
|
|
@ -1,54 +1,47 @@
|
|||
language: python
|
||||
python:
|
||||
- "3.8"
|
||||
- "3.6"
|
||||
env:
|
||||
- WAGTAIL="wagtail>=2.7,<2.8" DB=sqlite
|
||||
- WAGTAIL="wagtail>=2.0,<2.1" DB=sqlite
|
||||
matrix:
|
||||
include:
|
||||
# Latest Wagtail version
|
||||
- env: WAGTAIL="wagtail>=2.7,<2.8" DB=postgres
|
||||
- env: WAGTAIL="wagtail>=2.7,<2.8" DB=mysql
|
||||
- python: "3.8"
|
||||
- python: "3.7"
|
||||
- python: "3.6"
|
||||
- env: WAGTAIL="wagtail>=2.0,<2.1" DB=sqlite
|
||||
- env: WAGTAIL="wagtail>=2.0,<2.1" DB=postgres
|
||||
- env: WAGTAIL="wagtail>=2.0,<2.1" DB=mysql
|
||||
- python: "3.5"
|
||||
- python: "3.4"
|
||||
# Past Wagtail versions
|
||||
- python: "3.7"
|
||||
env: WAGTAIL="wagtail>=2.6,<2.7"
|
||||
- python: "3.7"
|
||||
env: WAGTAIL="wagtail>=2.5,<2.6"
|
||||
- python: "3.4" # Wagtail 2.5 was the last to support python 3.4
|
||||
env: WAGTAIL="wagtail>=2.5,<2.6"
|
||||
- python: "3.7"
|
||||
env: WAGTAIL="wagtail>=2.4,<2.5"
|
||||
- python: "3.7"
|
||||
env: WAGTAIL="wagtail>=2.3,<2.4"
|
||||
- python: "3.7"
|
||||
env: WAGTAIL="wagtail>=2.2,<2.3"
|
||||
- python: "3.7"
|
||||
env: WAGTAIL="wagtail>=2.1,<2.2"
|
||||
- python: "3.7"
|
||||
env: WAGTAIL="wagtail>=2.0,<2.1"
|
||||
- python: "3.6"
|
||||
env: WAGTAIL="wagtail>=1.13,<1.14"
|
||||
- python: "2.7" # Wagtail 1.13 was the latest tested against 2.7
|
||||
env: WAGTAIL="wagtail>=1.13,<1.14"
|
||||
- python: "3.7"
|
||||
env: WAGTAIL="wagtail>=1.13,<1.14"
|
||||
- python: "2.7"
|
||||
- python: "3.6"
|
||||
env: WAGTAIL="wagtail>=1.12,<1.13"
|
||||
- python: "3.7"
|
||||
env: WAGTAIL="wagtail>=1.12,<1.13"
|
||||
services:
|
||||
- mysql
|
||||
- postgresql
|
||||
addons:
|
||||
postgresql: "9.4"
|
||||
- python: "3.6"
|
||||
env: WAGTAIL="wagtail>=1.11,<1.12"
|
||||
- python: "3.6"
|
||||
env: WAGTAIL="wagtail>=1.10,<1.11"
|
||||
- python: "3.5"
|
||||
env: WAGTAIL="wagtail>=1.9,<1.10"
|
||||
- python: "3.3" # Wagtail 1.9 was the latest tested against 3.3
|
||||
env: WAGTAIL="wagtail>=1.9,<1.10"
|
||||
- python: "3.5"
|
||||
env: WAGTAIL="wagtail>=1.8,<1.9"
|
||||
- python: "3.5"
|
||||
env: WAGTAIL="wagtail>=1.6,<1.7"
|
||||
- python: "3.5"
|
||||
env: WAGTAIL="wagtail>=1.5,<1.6"
|
||||
- python: "3.5"
|
||||
env: WAGTAIL="wagtail>=1.4,<1.5"
|
||||
before_script:
|
||||
- mysql -e 'create database wagtail_modeltranslation;'
|
||||
- psql -c 'create database wagtail_modeltranslation;' -U postgres
|
||||
install:
|
||||
- pip install --upgrade -q pip setuptools
|
||||
- if [[ $DB == mysql ]] && [[ ${TRAVIS_PYTHON_VERSION:0:1} == "2" ]]; then pip install -q mysql-python; elif [[ $DB == mysql ]] && [[ ${TRAVIS_PYTHON_VERSION:0:1} == "3" ]]; then pip install -q mysqlclient; fi
|
||||
- if [[ $DB == postgres ]]; then pip install -q 'psycopg2-binary'; fi
|
||||
- if [[ $DB == postgres ]]; then pip install -q psycopg2; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '3.3' ]]; then pip install 'Django>=1.8,<1.9'; fi
|
||||
- pip install $WAGTAIL
|
||||
- pip install -e .
|
||||
script:
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ Contributors
|
|||
* Raphael Grill
|
||||
* Tom Dyson
|
||||
* Tim Tan
|
||||
* Benedikt Willi
|
||||
|
||||
|
||||
.. _Django-modeltranslation: https://github.com/deschler/django-modeltranslation
|
||||
|
|
|
|||
|
|
@ -1,11 +1,3 @@
|
|||
v0.6.0rc2:
|
||||
- added RichTextFieldPanel to the default list of patched panels
|
||||
- added settings to allow the patching of custom panels
|
||||
- slug auto-population is now made the same way as wagtail (no changes in live pages)
|
||||
- Fixed: When adding a page link in a translated RichTextField the link was always to the default language version of that page
|
||||
- Fixed: Copy content of streamfield fails with 414 Request-URI Too Long
|
||||
- Fixed: Panel patching failed with the error "AttributeError: 'list' object has no attribute 'children'"
|
||||
|
||||
v0.6.0rc1:
|
||||
- django-modeltranslation is now a dependency.
|
||||
- added compatibility with Python 3 (3.3, 3.4, 3.5).
|
||||
|
|
|
|||
|
|
@ -3,6 +3,5 @@ recursive-include docs *.rst conf.py Makefile make.bat
|
|||
recursive-include wagtail_modeltranslation/static *
|
||||
recursive-include wagtail_modeltranslation/management *
|
||||
recursive-include wagtail_modeltranslation/templatetags *
|
||||
recursive-include wagtail_modeltranslation/templates *
|
||||
global-exclude *.pyc
|
||||
global-exclude *.DS_Store
|
||||
|
|
|
|||
2
PKG-INFO
2
PKG-INFO
|
|
@ -1,6 +1,6 @@
|
|||
Metadata-Version: 1.0
|
||||
Name: wagtail-modeltranslation
|
||||
Version: 0.10.6
|
||||
Version: 0.8.1
|
||||
Summary: Translates Wagtail CMS models using a registration approach.
|
||||
Home-page: https://github.com/infoportugal/wagtail-modeltranslation
|
||||
Author: InfoPortugal S.A.
|
||||
|
|
|
|||
1
Pipfile
1
Pipfile
|
|
@ -8,4 +8,3 @@ bumpversion = "*"
|
|||
wheel = "*"
|
||||
|
||||
[dev-packages]
|
||||
twine = "*"
|
||||
|
|
|
|||
122
Pipfile.lock
generated
122
Pipfile.lock
generated
|
|
@ -1,10 +1,12 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "191a6f860a13836c57a16587784ceca36f791bfae1270cf937286a496e891114"
|
||||
"sha256": "8a50cf92fd274fbd58348130a7ab3568a8f694ad373cb5a67d45da7a46b96827"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {},
|
||||
"requires": {
|
||||
"python_version": "3.6"
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"name": "pypi",
|
||||
|
|
@ -24,120 +26,12 @@
|
|||
},
|
||||
"wheel": {
|
||||
"hashes": [
|
||||
"sha256:5e79117472686ac0c4aef5bad5172ea73a1c2d1646b808c35926bd26bdfb0c08",
|
||||
"sha256:62fcfa03d45b5b722539ccbc07b190e4bfff4bb9e3a4d470dd9f6a0981002565"
|
||||
"sha256:1ae8153bed701cb062913b72429bcf854ba824f973735427681882a688cb55ce",
|
||||
"sha256:9cdc8ab2cc9c3c2e2727a4b67c22881dbb0e1c503d592992594c5e131c867107"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.33.4"
|
||||
"version": "==0.31.0"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"bleach": {
|
||||
"hashes": [
|
||||
"sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16",
|
||||
"sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa"
|
||||
],
|
||||
"version": "==3.1.0"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:59b7658e26ca9c7339e00f8f4636cdfe59d34fa37b9b04f6f9e9926b3cece1a5",
|
||||
"sha256:b26104d6835d1f5e49452a26eb2ff87fe7090b89dfcaee5ea2212697e1e1d7ae"
|
||||
],
|
||||
"version": "==2019.3.9"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
"sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae",
|
||||
"sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"
|
||||
],
|
||||
"version": "==3.0.4"
|
||||
},
|
||||
"docutils": {
|
||||
"hashes": [
|
||||
"sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
|
||||
"sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274",
|
||||
"sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6"
|
||||
],
|
||||
"version": "==0.14"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
"sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407",
|
||||
"sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c"
|
||||
],
|
||||
"version": "==2.8"
|
||||
},
|
||||
"pkginfo": {
|
||||
"hashes": [
|
||||
"sha256:7424f2c8511c186cd5424bbf31045b77435b37a8d604990b79d4e70d741148bb",
|
||||
"sha256:a6d9e40ca61ad3ebd0b72fbadd4fba16e4c0e4df0428c041e01e06eb6ee71f32"
|
||||
],
|
||||
"version": "==1.5.0.1"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
|
||||
"sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"
|
||||
],
|
||||
"version": "==2.4.2"
|
||||
},
|
||||
"readme-renderer": {
|
||||
"hashes": [
|
||||
"sha256:bb16f55b259f27f75f640acf5e00cf897845a8b3e4731b5c1a436e4b8529202f",
|
||||
"sha256:c8532b79afc0375a85f10433eca157d6b50f7d6990f337fa498c96cd4bfc203d"
|
||||
],
|
||||
"version": "==24.0"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
|
||||
"sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
|
||||
],
|
||||
"version": "==2.22.0"
|
||||
},
|
||||
"requests-toolbelt": {
|
||||
"hashes": [
|
||||
"sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f",
|
||||
"sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0"
|
||||
],
|
||||
"version": "==0.9.1"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
|
||||
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
|
||||
],
|
||||
"version": "==1.12.0"
|
||||
},
|
||||
"tqdm": {
|
||||
"hashes": [
|
||||
"sha256:0a860bf2683fdbb4812fe539a6c22ea3f1777843ea985cb8c3807db448a0f7ab",
|
||||
"sha256:e288416eecd4df19d12407d0c913cbf77aa8009d7fddb18f632aded3bdbdda6b"
|
||||
],
|
||||
"version": "==4.32.1"
|
||||
},
|
||||
"twine": {
|
||||
"hashes": [
|
||||
"sha256:0fb0bfa3df4f62076cab5def36b1a71a2e4acb4d1fa5c97475b048117b1a6446",
|
||||
"sha256:d6c29c933ecfc74e9b1d9fa13aa1f87c5d5770e119f5a4ce032092f0ff5b14dc"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.13.0"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:b246607a25ac80bedac05c6f282e3cdaf3afb65420fd024ac94435cabe6e18d1",
|
||||
"sha256:dbe59173209418ae49d485b87d1681aefa36252ee85884c31346debd19463232"
|
||||
],
|
||||
"version": "==1.25.3"
|
||||
},
|
||||
"webencodings": {
|
||||
"hashes": [
|
||||
"sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78",
|
||||
"sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"
|
||||
],
|
||||
"version": "==0.5.1"
|
||||
}
|
||||
}
|
||||
"develop": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ Quick start
|
|||
...
|
||||
'wagtail_modeltranslation',
|
||||
'wagtail_modeltranslation.makemigrations',
|
||||
'wagtail_modeltranslation.migrate',
|
||||
)
|
||||
|
||||
3. Add 'django.middleware.locale.LocaleMiddleware' to ``MIDDLEWARE`` on your ``settings.py``::
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Installation
|
|||
Requirements
|
||||
============
|
||||
|
||||
* Wagtail >= 1.12
|
||||
* Wagtail >= 1.4
|
||||
|
||||
|
||||
|
||||
|
|
@ -48,7 +48,6 @@ To setup the application please follow these steps:
|
|||
...
|
||||
'wagtail_modeltranslation',
|
||||
'wagtail_modeltranslation.makemigrations',
|
||||
'wagtail_modeltranslation.migrate',
|
||||
)
|
||||
|
||||
- Add 'django.middleware.locale.LocaleMiddleware' to ``MIDDLEWARE`` (``MIDDLEWARE_CLASSES`` before django 1.10).
|
||||
|
|
@ -89,7 +88,7 @@ To setup the application please follow these steps:
|
|||
|
||||
To learn more about preparing Wagtail for Internationalisation check the `Wagtail i18n docs <http://docs.wagtail.io/en/latest/advanced_topics/i18n/>`_.
|
||||
|
||||
2. Create a ``translation.py`` file in your app directory and register ``TranslationOptions`` for every model you want to translate and for all subclasses of Page model.
|
||||
2. Create a ``translation.py`` file in your app directory and register ``TranslationOptions`` for every model you want to translate.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
|
|
|
|||
|
|
@ -28,15 +28,3 @@ This setting behaves as the above but should be used for panels that are compose
|
|||
.. code-block:: python
|
||||
|
||||
WAGTAILMODELTRANSLATION_CUSTOM_COMPOSED_PANELS = ['app_x.module_y.PanelZ']
|
||||
|
||||
|
||||
``WAGTAILMODELTRANSLATION_TRANSLATE_SLUGS``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Default: ``True``
|
||||
|
||||
This setting makes slug and url_path localized. If True, each page will have a slug and url_path per language.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
WAGTAILMODELTRANSLATION_TRANSLATE_SLUGS = True
|
||||
|
|
|
|||
12
runtests.py
12
runtests.py
|
|
@ -5,7 +5,10 @@ import sys
|
|||
import django
|
||||
from django.conf import settings
|
||||
from django.core.management import call_command
|
||||
from wagtail import VERSION
|
||||
try:
|
||||
from wagtail import VERSION
|
||||
except ImportError:
|
||||
VERSION = 1, 6, 3 # assume it's 1.6.3, the latest version without VERSION
|
||||
|
||||
|
||||
def runtests():
|
||||
|
|
@ -33,7 +36,7 @@ def runtests():
|
|||
|
||||
# Configure test environment
|
||||
import wagtail
|
||||
if VERSION < (2,):
|
||||
if VERSION[0] < 2:
|
||||
WAGTAIL_MODULES = [
|
||||
'wagtail.wagtailcore',
|
||||
'wagtail.wagtailadmin',
|
||||
|
|
@ -68,7 +71,7 @@ def runtests():
|
|||
]
|
||||
WAGTAIL_CORE = 'wagtail.core'
|
||||
|
||||
|
||||
|
||||
settings.configure(
|
||||
DATABASES=DATABASES,
|
||||
INSTALLED_APPS=[
|
||||
|
|
@ -90,7 +93,8 @@ def runtests():
|
|||
MIDDLEWARE_CLASSES=(),
|
||||
)
|
||||
|
||||
django.setup()
|
||||
if django.VERSION >= (1, 7):
|
||||
django.setup()
|
||||
failures = call_command(
|
||||
'test', 'wagtail_modeltranslation', interactive=False, failfast=False, verbosity=2)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
[bumpversion]
|
||||
current_version = 0.10.6
|
||||
current_version = 0.9.0
|
||||
commit = True
|
||||
tag = True
|
||||
|
||||
|
|
|
|||
13
setup.py
13
setup.py
|
|
@ -44,18 +44,17 @@ setup(
|
|||
'wagtail_modeltranslation.migrate.management',
|
||||
'wagtail_modeltranslation.migrate.management.commands'],
|
||||
package_data={'wagtail_modeltranslation': ['static/wagtail_modeltranslation/css/*.css',
|
||||
'static/wagtail_modeltranslation/js/*.js',
|
||||
'templates/*.html']},
|
||||
install_requires=['wagtail>=1.12', 'django-modeltranslation>=0.13'],
|
||||
'static/wagtail_modeltranslation/js/*.js']},
|
||||
install_requires=['Django<2.0', 'wagtail>=1.4', 'django-modeltranslation>=0.12.2'],
|
||||
download_url='https://github.com/infoportugal/wagtail-modeltranslation/archive/v0.8.tar.gz',
|
||||
classifiers=[
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2.6',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Programming Language :: Python :: 3.2',
|
||||
'Programming Language :: Python :: 3.3',
|
||||
'Programming Language :: Python :: 3.4',
|
||||
'Programming Language :: Python :: 3.5',
|
||||
'Programming Language :: Python :: 3.6',
|
||||
'Programming Language :: Python :: 3.7',
|
||||
'Programming Language :: Python :: 3.8',
|
||||
'Operating System :: OS Independent',
|
||||
'Environment :: Web Environment',
|
||||
'Intended Audience :: Developers',
|
||||
|
|
|
|||
323
tox.ini
323
tox.ini
|
|
@ -1,217 +1,158 @@
|
|||
[tox]
|
||||
envlist =
|
||||
py38-2.7.X,
|
||||
py37-2.7.X,
|
||||
py36-2.7.X,
|
||||
py35-2.7.X,
|
||||
py34-2.7.X,
|
||||
py37-2.6.X,
|
||||
py36-2.6.X,
|
||||
py35-2.6.X,
|
||||
py37-2.5.X,
|
||||
py36-2.5.X,
|
||||
py35-2.5.X,
|
||||
py34-2.5.X,
|
||||
py37-2.4.X,
|
||||
py36-2.4.X,
|
||||
py35-2.4.X,
|
||||
py34-2.4.X,
|
||||
py36-2.3.X,
|
||||
py35-2.3.X,
|
||||
py34-2.3.X,
|
||||
py36-2.2.X,
|
||||
py35-2.2.X,
|
||||
py34-2.2.X,
|
||||
py36-2.1.X,
|
||||
py35-2.1.X,
|
||||
py34-2.1.X,
|
||||
py36-2.0.X,
|
||||
py35-2.0.X,
|
||||
py34-2.0.X,
|
||||
py36-1.13.X,
|
||||
py35-1.13.X,
|
||||
py34-1.13.X,
|
||||
py27-1.13.X,
|
||||
py36-1.12.X,
|
||||
py35-1.12.X,
|
||||
py34-1.12.X,
|
||||
py27-1.12.X,
|
||||
py35-1.9.X,
|
||||
py34-1.9.X,
|
||||
py33-1.9.X,
|
||||
py27-1.9.X,
|
||||
py35-1.8.X,
|
||||
py34-1.8.X,
|
||||
py33-1.8.X,
|
||||
py27-1.8.X,
|
||||
py35-1.7.X,
|
||||
py34-1.7.X,
|
||||
py33-1.7.X,
|
||||
py27-1.7.X,
|
||||
py35-1.6.X,
|
||||
py34-1.6.X,
|
||||
py33-1.6.X,
|
||||
py27-1.6.X,
|
||||
py35-1.5.X,
|
||||
py34-1.5.X,
|
||||
py33-1.5.X,
|
||||
py27-1.5.X,
|
||||
py35-1.4.X,
|
||||
py34-1.4.X,
|
||||
py33-1.4.X,
|
||||
py27-1.4.X,
|
||||
|
||||
[testenv]
|
||||
commands =
|
||||
{envpython} runtests.py
|
||||
|
||||
[testenv:py38-2.7.X]
|
||||
basepython = python3.8
|
||||
deps =
|
||||
wagtail>=2.7,<2.8
|
||||
|
||||
[testenv:py37-2.7.X]
|
||||
basepython = python3.7
|
||||
deps =
|
||||
wagtail>=2.7,<2.8
|
||||
|
||||
[testenv:py36-2.7.X]
|
||||
basepython = python3.6
|
||||
deps =
|
||||
wagtail>=2.7,<2.8
|
||||
|
||||
[testenv:py35-2.7.X]
|
||||
[testenv:py35-1.9.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=2.7,<2.8
|
||||
wagtail>=1.9,<1.10
|
||||
|
||||
[testenv:py37-2.6.X]
|
||||
basepython = python3.7
|
||||
deps =
|
||||
wagtail>=2.6,<2.7
|
||||
|
||||
[testenv:py36-2.6.X]
|
||||
basepython = python3.6
|
||||
deps =
|
||||
wagtail>=2.6,<2.7
|
||||
|
||||
[testenv:py35-2.6.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=2.6,<2.7
|
||||
|
||||
[testenv:py37-2.5.X]
|
||||
basepython = python3.7
|
||||
deps =
|
||||
wagtail>=2.5,<2.6
|
||||
|
||||
[testenv:py36-2.5.X]
|
||||
basepython = python3.6
|
||||
deps =
|
||||
wagtail>=2.5,<2.6
|
||||
|
||||
[testenv:py35-2.5.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=2.5,<2.6
|
||||
|
||||
[testenv:py34-2.5.X]
|
||||
[testenv:py34-1.9.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=2.5,<2.6
|
||||
wagtail>=1.9,<1.10
|
||||
|
||||
[testenv:py37-2.4.X]
|
||||
basepython = python3.7
|
||||
[testenv:py33-1.9.X]
|
||||
basepython = python3.3
|
||||
deps =
|
||||
wagtail>=2.4,<2.5
|
||||
Django>=1.8,<1.9
|
||||
wagtail>=1.9,<1.10
|
||||
|
||||
[testenv:py36-2.4.X]
|
||||
basepython = python3.6
|
||||
deps =
|
||||
wagtail>=2.4,<2.5
|
||||
|
||||
[testenv:py35-2.4.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=2.4,<2.5
|
||||
|
||||
[testenv:py34-2.4.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=2.4,<2.5
|
||||
|
||||
[testenv:py36-2.3.X]
|
||||
basepython = python3.6
|
||||
deps =
|
||||
wagtail>=2.3,<2.4
|
||||
|
||||
[testenv:py35-2.3.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=2.3,<2.4
|
||||
|
||||
[testenv:py34-2.3.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=2.3,<2.4
|
||||
|
||||
[testenv:py36-2.2.X]
|
||||
basepython = python3.6
|
||||
deps =
|
||||
wagtail>=2.2,<2.3
|
||||
|
||||
[testenv:py35-2.2.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=2.2,<2.3
|
||||
|
||||
[testenv:py34-2.2.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=2.2,<2.3
|
||||
|
||||
[testenv:py36-2.1.X]
|
||||
basepython = python3.6
|
||||
deps =
|
||||
wagtail>=2.1,<2.2
|
||||
|
||||
[testenv:py35-2.1.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=2.1,<2.2
|
||||
|
||||
[testenv:py34-2.1.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=2.1,<2.2
|
||||
|
||||
[testenv:py36-2.0.X]
|
||||
basepython = python3.6
|
||||
deps =
|
||||
wagtail>=2.0,<2.1
|
||||
|
||||
[testenv:py35-2.0.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=2.0,<2.1
|
||||
|
||||
[testenv:py34-2.0.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=2.0,<2.1
|
||||
|
||||
[testenv:py36-1.13.X]
|
||||
basepython = python3.6
|
||||
deps =
|
||||
wagtail>=1.13,<2.0
|
||||
|
||||
[testenv:py35-1.13.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=1.13,<2.0
|
||||
|
||||
[testenv:py34-1.13.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=1.13,<2.0
|
||||
|
||||
[testenv:py27-1.13.X]
|
||||
[testenv:py27-1.9.X]
|
||||
basepython = python2.7
|
||||
deps =
|
||||
wagtail>=1.13,<2.0
|
||||
wagtail>=1.9,<1.10
|
||||
|
||||
[testenv:py36-1.12.X]
|
||||
basepython = python3.6
|
||||
deps =
|
||||
wagtail>=1.12,<1.13
|
||||
|
||||
[testenv:py35-1.12.X]
|
||||
[testenv:py35-1.8.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=1.12,<1.13
|
||||
wagtail>=1.8,<1.9
|
||||
|
||||
[testenv:py34-1.12.X]
|
||||
[testenv:py34-1.8.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=1.12,<1.13
|
||||
wagtail>=1.8,<1.9
|
||||
|
||||
[testenv:py27-1.12.X]
|
||||
[testenv:py33-1.8.X]
|
||||
basepython = python3.3
|
||||
deps =
|
||||
Django>=1.8,<1.9
|
||||
wagtail>=1.8,<1.9
|
||||
|
||||
[testenv:py27-1.8.X]
|
||||
basepython = python2.7
|
||||
deps =
|
||||
wagtail>=1.12,<1.13
|
||||
wagtail>=1.8,<1.9
|
||||
|
||||
|
||||
[testenv:py35-1.7.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=1.7,<1.8
|
||||
|
||||
[testenv:py34-1.7.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=1.7,<1.8
|
||||
|
||||
[testenv:py33-1.7.X]
|
||||
basepython = python3.3
|
||||
deps =
|
||||
Django>=1.8,<1.9
|
||||
wagtail>=1.7,<1.8
|
||||
|
||||
[testenv:py27-1.7.X]
|
||||
basepython = python2.7
|
||||
deps =
|
||||
wagtail>=1.7,<1.8
|
||||
|
||||
|
||||
[testenv:py35-1.6.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=1.6,<1.7
|
||||
|
||||
[testenv:py34-1.6.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=1.6,<1.7
|
||||
|
||||
[testenv:py33-1.6.X]
|
||||
basepython = python3.3
|
||||
deps =
|
||||
Django>=1.8,<1.9
|
||||
wagtail>=1.6,<1.7
|
||||
|
||||
[testenv:py27-1.6.X]
|
||||
basepython = python2.7
|
||||
deps =
|
||||
wagtail>=1.6,<1.7
|
||||
|
||||
[testenv:py35-1.5.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=1.5,<1.6
|
||||
|
||||
[testenv:py34-1.5.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=1.5,<1.6
|
||||
|
||||
[testenv:py33-1.5.X]
|
||||
basepython = python3.3
|
||||
deps =
|
||||
Django>=1.8,<1.9
|
||||
wagtail>=1.5,<1.6
|
||||
|
||||
[testenv:py27-1.5.X]
|
||||
basepython = python2.7
|
||||
deps =
|
||||
wagtail>=1.5,<1.6
|
||||
|
||||
[testenv:py35-1.4.X]
|
||||
basepython = python3.5
|
||||
deps =
|
||||
wagtail>=1.4,<1.5
|
||||
|
||||
[testenv:py34-1.4.X]
|
||||
basepython = python3.4
|
||||
deps =
|
||||
wagtail>=1.4,<1.5
|
||||
|
||||
[testenv:py33-1.4.X]
|
||||
basepython = python3.3
|
||||
deps =
|
||||
Django>=1.8,<1.9
|
||||
wagtail>=1.4,<1.5
|
||||
|
||||
[testenv:py27-1.4.X]
|
||||
basepython = python2.7
|
||||
deps =
|
||||
wagtail>=1.4,<1.5
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# coding: utf-8
|
||||
__version__ = '0.10.6'
|
||||
__version__ = '0.9.0'
|
||||
default_app_config = 'wagtail_modeltranslation.apps.ModeltranslationConfig'
|
||||
|
|
|
|||
|
|
@ -10,22 +10,9 @@ class ModeltranslationConfig(AppConfig):
|
|||
|
||||
def ready(self):
|
||||
from django.conf import settings
|
||||
from modeltranslation import settings as mt_settings
|
||||
|
||||
# Add Wagtail defined fields as modeltranslation custom fields
|
||||
wagtail_fields = (
|
||||
'StreamField',
|
||||
'RichTextField',
|
||||
)
|
||||
|
||||
# update both the standard settings and the modeltranslation settings,
|
||||
# as we cannot guarantee the load order, and so django_modeltranslation
|
||||
# may bootstrap itself either before, or after, our ready() gets called.
|
||||
custom_fields = getattr(settings, 'MODELTRANSLATION_CUSTOM_FIELDS', tuple())
|
||||
setattr(settings, 'MODELTRANSLATION_CUSTOM_FIELDS', tuple(set(custom_fields + wagtail_fields)))
|
||||
|
||||
mt_custom_fields = getattr(mt_settings, 'CUSTOM_FIELDS', tuple())
|
||||
setattr(mt_settings, 'CUSTOM_FIELDS', tuple(set(mt_custom_fields + wagtail_fields)))
|
||||
setattr(settings, 'MODELTRANSLATION_CUSTOM_FIELDS', getattr(settings, 'MODELTRANSLATION_CUSTOM_FIELDS', ()) + (
|
||||
'StreamField', 'RichTextField'))
|
||||
|
||||
from modeltranslation.models import handle_translation_registrations
|
||||
handle_translation_registrations()
|
||||
|
|
|
|||
|
|
@ -5,10 +5,7 @@ import types
|
|||
|
||||
from django.core.cache import cache
|
||||
from django.core.exceptions import ValidationError
|
||||
try:
|
||||
from django.urls import reverse
|
||||
except ImportError:
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.db import transaction, connection
|
||||
from django.db.models import Q, Value
|
||||
from django.db.models.functions import Concat, Substr
|
||||
|
|
@ -18,34 +15,39 @@ from django.utils.translation import ugettext_lazy as _
|
|||
from modeltranslation import settings as mt_settings
|
||||
from modeltranslation.translator import translator, NotRegistered
|
||||
from modeltranslation.utils import build_localized_fieldname, get_language
|
||||
|
||||
from wagtail.contrib.settings.models import BaseSetting
|
||||
from wagtail.contrib.settings.views import get_setting_edit_handler
|
||||
try:
|
||||
from wagtail.contrib.routable_page.models import RoutablePageMixin
|
||||
from wagtail.admin.edit_handlers import FieldPanel, \
|
||||
MultiFieldPanel, FieldRowPanel, InlinePanel, StreamFieldPanel, RichTextFieldPanel,\
|
||||
extract_panel_definitions_from_model_class, ObjectList
|
||||
MultiFieldPanel, FieldRowPanel, InlinePanel, StreamFieldPanel, RichTextFieldPanel
|
||||
from wagtail.core.models import Page, Site
|
||||
from wagtail.core.fields import StreamField, StreamValue
|
||||
from wagtail.core.url_routing import RouteResult
|
||||
from wagtail.core.utils import WAGTAIL_APPEND_SLASH
|
||||
from wagtail.images.edit_handlers import ImageChooserPanel
|
||||
from wagtail.search.index import SearchField
|
||||
from wagtail.snippets.models import get_snippet_models
|
||||
from wagtail.snippets.views.snippets import SNIPPET_EDIT_HANDLERS
|
||||
except ImportError:
|
||||
from wagtail.contrib.wagtailroutablepage.models import RoutablePageMixin
|
||||
from wagtail.wagtailadmin.edit_handlers import FieldPanel, \
|
||||
MultiFieldPanel, FieldRowPanel, InlinePanel, StreamFieldPanel, RichTextFieldPanel,\
|
||||
extract_panel_definitions_from_model_class, ObjectList
|
||||
MultiFieldPanel, FieldRowPanel, InlinePanel, StreamFieldPanel, RichTextFieldPanel
|
||||
from wagtail.wagtailcore.models import Page, Site
|
||||
from wagtail.wagtailcore.fields import StreamField, StreamValue
|
||||
from wagtail.wagtailcore.url_routing import RouteResult
|
||||
from wagtail.wagtailcore.utils import WAGTAIL_APPEND_SLASH
|
||||
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
|
||||
from wagtail.wagtailsearch.index import SearchField
|
||||
from wagtail.wagtailsnippets.models import get_snippet_models
|
||||
from wagtail.wagtailsnippets.views.snippets import SNIPPET_EDIT_HANDLERS
|
||||
from wagtail_modeltranslation.settings import CUSTOM_SIMPLE_PANELS, CUSTOM_COMPOSED_PANELS, TRANSLATE_SLUGS
|
||||
try:
|
||||
from wagtail.core.utils import WAGTAIL_APPEND_SLASH
|
||||
except ImportError:
|
||||
try:
|
||||
from wagtail.wagtailcore.utils import WAGTAIL_APPEND_SLASH
|
||||
except ImportError:
|
||||
WAGTAIL_APPEND_SLASH = True # Wagtail<1.5
|
||||
from wagtail_modeltranslation.settings import CUSTOM_SIMPLE_PANELS, CUSTOM_COMPOSED_PANELS
|
||||
from wagtail_modeltranslation.utils import compare_class_tree_depth
|
||||
from wagtail import VERSION
|
||||
|
||||
logger = logging.getLogger('wagtail.core')
|
||||
|
||||
|
|
@ -117,35 +119,29 @@ class WagtailTranslator(object):
|
|||
_patch_stream_field_meaningful_value(descriptor)
|
||||
|
||||
# OVERRIDE PAGE METHODS
|
||||
if TRANSLATE_SLUGS:
|
||||
model.set_url_path = _new_set_url_path
|
||||
model.route = _new_route
|
||||
model._update_descendant_url_paths = _new_update_descendant_url_paths
|
||||
if not hasattr(model, '_get_site_root_paths'):
|
||||
model.get_url_parts = _new_get_url_parts # Wagtail<1.11
|
||||
model._get_site_root_paths = _new_get_site_root_paths
|
||||
_patch_clean(model)
|
||||
model.set_url_path = _new_set_url_path
|
||||
model.route = _new_route
|
||||
model._update_descendant_url_paths = _new_update_descendant_url_paths
|
||||
if not hasattr(model, '_get_site_root_paths'):
|
||||
model.get_url_parts = _new_get_url_parts # Wagtail<1.11
|
||||
model._get_site_root_paths = _new_get_site_root_paths
|
||||
_patch_clean(model)
|
||||
|
||||
if not model.save.__name__.startswith('localized'):
|
||||
setattr(model, 'save', LocalizedSaveDescriptor(model.save))
|
||||
if not model.save.__name__.startswith('localized'):
|
||||
setattr(model, 'save', LocalizedSaveDescriptor(model.save))
|
||||
|
||||
def _patch_other_models(self, model):
|
||||
if hasattr(model, 'edit_handler'):
|
||||
edit_handler = model.edit_handler
|
||||
for tab in edit_handler.children:
|
||||
for tab in edit_handler:
|
||||
tab.children = self._patch_panels(tab.children)
|
||||
elif hasattr(model, 'panels'):
|
||||
model.panels = self._patch_panels(model.panels)
|
||||
else:
|
||||
panels = extract_panel_definitions_from_model_class(model)
|
||||
translation_registered_fields = translator.get_options_for_model(model).fields
|
||||
panels = filter(lambda field: field.field_name not in translation_registered_fields, panels)
|
||||
edit_handler = ObjectList(panels)
|
||||
if VERSION < (2, 5):
|
||||
SNIPPET_EDIT_HANDLERS[model] = edit_handler.bind_to_model(model)
|
||||
else:
|
||||
SNIPPET_EDIT_HANDLERS[model] = edit_handler.bind_to(model=model)
|
||||
|
||||
if model in get_snippet_models() and model in SNIPPET_EDIT_HANDLERS:
|
||||
del SNIPPET_EDIT_HANDLERS[model]
|
||||
else:
|
||||
get_setting_edit_handler.cache_clear()
|
||||
|
||||
def _patch_panels(self, panels_list, related_model=None):
|
||||
"""
|
||||
|
|
@ -262,9 +258,9 @@ def _localized_set_url_path(page, parent, language):
|
|||
# for the current language. If the value for the current language is invalid we get the one
|
||||
# for the default fallback language
|
||||
slug = getattr(page, localized_slug_field, None) or \
|
||||
getattr(page, default_localized_slug_field, None) or page.slug
|
||||
getattr(page, default_localized_slug_field, None) or page.slug
|
||||
parent_url_path = getattr(parent, localized_url_path_field, None) or \
|
||||
getattr(parent, default_localized_url_path_field, None) or parent.url_path
|
||||
getattr(parent, default_localized_url_path_field, None) or parent.url_path
|
||||
|
||||
setattr(page, localized_url_path_field, parent_url_path + slug + '/')
|
||||
|
||||
|
|
@ -459,7 +455,7 @@ def _update_translation_descendant_url_paths(old_record, page):
|
|||
default_localized_url_path = build_localized_fieldname('url_path', mt_settings.DEFAULT_LANGUAGE)
|
||||
for language in mt_settings.AVAILABLE_LANGUAGES:
|
||||
localized_url_path = build_localized_fieldname('url_path', language)
|
||||
old_url_path = getattr(old_record, localized_url_path) or getattr(old_record, default_localized_url_path) or ''
|
||||
old_url_path = getattr(old_record, localized_url_path) or getattr(old_record, default_localized_url_path)
|
||||
new_url_path = getattr(page, localized_url_path) or getattr(page, default_localized_url_path)
|
||||
|
||||
if old_url_path == new_url_path:
|
||||
|
|
@ -573,4 +569,5 @@ def patch_wagtail_models():
|
|||
registered_models.sort(key=compare_class_tree_depth)
|
||||
|
||||
for model_class in registered_models:
|
||||
WagtailTranslator(model_class)
|
||||
if issubclass(model_class, Page) or model_class in get_snippet_models() or issubclass(model_class, BaseSetting):
|
||||
WagtailTranslator(model_class)
|
||||
|
|
|
|||
|
|
@ -1,107 +0,0 @@
|
|||
# coding: utf-8
|
||||
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ungettext
|
||||
|
||||
try:
|
||||
from wagtail.core.models import Page
|
||||
from wagtail.admin import widgets
|
||||
from wagtail.admin.forms.pages import CopyForm
|
||||
except ImportError:
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailadmin import widgets
|
||||
from wagtail.wagtailadmin.forms import CopyForm
|
||||
|
||||
|
||||
class PatchedCopyForm(CopyForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
# CopyPage must be passed a 'page' kwarg indicating the page to be copied
|
||||
self.page = kwargs.pop('page')
|
||||
self.user = kwargs.pop('user', None)
|
||||
can_publish = kwargs.pop('can_publish')
|
||||
super(CopyForm, self).__init__(*args, **kwargs)
|
||||
|
||||
#self.fields['new_title'] = forms.CharField(initial=self.page.title, label=_("New title"))
|
||||
for code, name in settings.LANGUAGES:
|
||||
locale_title = "new_title_{}".format(code)
|
||||
locale_label = "{} [{}]".format(_("New title"), code)
|
||||
self.fields[locale_title] = forms.CharField(initial=self.page.title, label=locale_label)
|
||||
|
||||
#self.fields['new_slug'] = forms.SlugField(initial=self.page.slug, label=_("New slug"))
|
||||
for code, name in settings.LANGUAGES:
|
||||
locale_title = "new_slug_{}".format(code)
|
||||
locale_label = "{} [{}]".format(_("New slug"), code)
|
||||
self.fields[locale_title] = forms.SlugField(initial=self.page.slug, label=locale_label)
|
||||
|
||||
self.fields['new_parent_page'] = forms.ModelChoiceField(
|
||||
initial=self.page.get_parent(),
|
||||
queryset=Page.objects.all(),
|
||||
widget=widgets.AdminPageChooser(can_choose_root=True, user_perms='copy_to'),
|
||||
label=_("New parent page"),
|
||||
help_text=_("This copy will be a child of this given parent page.")
|
||||
)
|
||||
pages_to_copy = self.page.get_descendants(inclusive=True)
|
||||
subpage_count = pages_to_copy.count() - 1
|
||||
if subpage_count > 0:
|
||||
self.fields['copy_subpages'] = forms.BooleanField(
|
||||
required=False, initial=True, label=_("Copy subpages"),
|
||||
help_text=ungettext(
|
||||
"This will copy %(count)s subpage.",
|
||||
"This will copy %(count)s subpages.",
|
||||
subpage_count) % {'count': subpage_count})
|
||||
|
||||
if can_publish:
|
||||
pages_to_publish_count = pages_to_copy.live().count()
|
||||
if pages_to_publish_count > 0:
|
||||
# In the specific case that there are no subpages, customise the field label and help text
|
||||
if subpage_count == 0:
|
||||
label = _("Publish copied page")
|
||||
help_text = _("This page is live. Would you like to publish its copy as well?")
|
||||
else:
|
||||
label = _("Publish copies")
|
||||
help_text = ungettext(
|
||||
"%(count)s of the pages being copied is live. Would you like to publish its copy?",
|
||||
"%(count)s of the pages being copied are live. Would you like to publish their copies?",
|
||||
pages_to_publish_count) % {'count': pages_to_publish_count}
|
||||
|
||||
self.fields['publish_copies'] = forms.BooleanField(
|
||||
required=False, initial=True, label=label, help_text=help_text
|
||||
)
|
||||
|
||||
def clean(self):
|
||||
cleaned_data = super(CopyForm, self).clean()
|
||||
|
||||
# Make sure the slug isn't already in use
|
||||
# slug = cleaned_data.get('new_slug')
|
||||
|
||||
# New parent page given in form or parent of source, if parent_page is empty
|
||||
parent_page = cleaned_data.get('new_parent_page') or self.page.get_parent()
|
||||
|
||||
# check if user is allowed to create a page at given location.
|
||||
if not parent_page.permissions_for_user(self.user).can_add_subpage():
|
||||
raise ValidationError({
|
||||
'new_parent_page': _("You do not have permission to copy to page \"%(page_title)s\"") % {'page_title': parent_page.get_admin_display_title()}
|
||||
})
|
||||
|
||||
# Count the pages with the same slug within the context of our copy's parent page
|
||||
for code, name in settings.LANGUAGES:
|
||||
locale_slug = "new_slug_{}".format(code)
|
||||
slug = cleaned_data.get(locale_slug)
|
||||
|
||||
param = 'slug_' + code
|
||||
query = {param: slug}
|
||||
if slug and parent_page.get_children().filter(**query).count():
|
||||
raise ValidationError({
|
||||
locale_slug: _("This slug is already in use within the context of its parent page \"%s\"" % parent_page)
|
||||
})
|
||||
|
||||
# Don't allow recursive copies into self
|
||||
if cleaned_data.get('copy_subpages') and (self.page == parent_page or parent_page.is_descendant_of(self.page)):
|
||||
raise ValidationError({
|
||||
'new_parent_page': _("You cannot copy a page into itself when copying subpages")
|
||||
})
|
||||
|
||||
return cleaned_data
|
||||
|
|
@ -10,4 +10,3 @@ CUSTOM_SIMPLE_PANELS = [import_from_string(panel_class) for panel_class in
|
|||
getattr(settings, 'WAGTAILMODELTRANSLATION_CUSTOM_SIMPLE_PANELS', [])]
|
||||
CUSTOM_COMPOSED_PANELS = [import_from_string(panel_class) for panel_class in
|
||||
getattr(settings, 'WAGTAILMODELTRANSLATION_CUSTOM_COMPOSED_PANELS', [])]
|
||||
TRANSLATE_SLUGS = getattr(settings, 'WAGTAILMODELTRANSLATION_TRANSLATE_SLUGS', True)
|
||||
|
|
|
|||
|
|
@ -7,47 +7,22 @@ $(document).ready(function(){
|
|||
for (var i = 0; i < allStreamFields.length; i++) {
|
||||
//Current Field with all content
|
||||
var currentStreamField = allStreamFields[i];
|
||||
//Current field header
|
||||
var header;
|
||||
//Current field name
|
||||
var fieldLang = "";
|
||||
//Current field language
|
||||
var fieldName = "";
|
||||
if(versionCompare(WAGTAIL_VERSION,'2.6.0', {zeroExtend: true})===-1){
|
||||
// Wagtail < 2.6
|
||||
header = $(currentStreamField).children('h2')[0];
|
||||
//Search for the input field so that we can get is id to know the field's name.
|
||||
var streamFieldDiv = $(currentStreamField).find('div.sequence-container.sequence-type-stream')[0];
|
||||
var fieldInfos = $(streamFieldDiv).find('input')[0].id.split('-')[0];
|
||||
var lastUnderscore = fieldInfos.lastIndexOf("_");
|
||||
fieldName = fieldInfos.substring(0, lastUnderscore);
|
||||
fieldLang = fieldInfos.substring(lastUnderscore + 1, fieldInfos.length);
|
||||
} else if(versionCompare(WAGTAIL_VERSION,'2.7.0', {zeroExtend: true})===-1){
|
||||
// Wagtail < 2.7
|
||||
header = $(currentStreamField).children('.title-wrapper')[0];
|
||||
//Search for the input field so that we can get is id to know the field's name.
|
||||
var streamFieldDiv = $(currentStreamField).find('div.sequence-container.sequence-type-stream')[0];
|
||||
var fieldInfos = $(streamFieldDiv).find('input')[0].id.split('-')[0];
|
||||
var lastUnderscore = fieldInfos.lastIndexOf("_");
|
||||
fieldName = fieldInfos.substring(0, lastUnderscore);
|
||||
fieldLang = fieldInfos.substring(lastUnderscore + 1, fieldInfos.length);
|
||||
} else {
|
||||
// Wagtail >= 2.7
|
||||
header = $(currentStreamField).children('.title-wrapper')[0];
|
||||
//Search for the input field so that we can get is id to know the field's name.
|
||||
var streamFieldDiv = $(currentStreamField).find('.field-content')[0];
|
||||
var fieldInfos = $(streamFieldDiv).find('input')[0].id.split('-')[0];
|
||||
var lastUnderscore = fieldInfos.lastIndexOf("_");
|
||||
fieldName = fieldInfos.substring(0, lastUnderscore);
|
||||
fieldLang = fieldInfos.substring(lastUnderscore + 1, fieldInfos.length);
|
||||
}
|
||||
//Current Field header
|
||||
var header = $(currentStreamField).children('h2')[0];
|
||||
//Search for the input field so that we can get is id to know the field's name.
|
||||
var streamFieldDiv = $(currentStreamField).find('div.sequence-container.sequence-type-stream')[0];
|
||||
var fieldInfos = $(streamFieldDiv).children('input')[0].id.split('-')[0];
|
||||
var lastUnderscore = fieldInfos.lastIndexOf("_");
|
||||
var fieldName = fieldInfos.substring(0, lastUnderscore);
|
||||
var fieldLang = fieldInfos.substring(lastUnderscore + 1, fieldInfos.length);
|
||||
//The cycle to create the buttons for copy each language field
|
||||
header.innerHTML += '<div class="translation-field-copy-wrapper">Copy content from: </div>';
|
||||
var copyContentString = 'Copy content from';
|
||||
header.innerHTML += '<div class="translation-field-copy-wrapper">'+copyContentString+': </div>';
|
||||
for (var j = 0; j < langs.length; j++) {
|
||||
if (fieldLang != langs[j]) {
|
||||
var currentFieldID = fieldName + '_' + fieldLang;
|
||||
var targetFieldID = fieldName + '_' + langs [j];
|
||||
$(header).children('.translation-field-copy-wrapper')[0].innerHTML += '<button class="button translation-field-copy" current-lang-code="' + currentFieldID + '" data-lang-code="' + targetFieldID + '">' + langs[j] + '</button>';
|
||||
$(header).children('.translation-field-copy-wrapper')[0].innerHTML += '<button class="translation-field-copy" current-lang-code="'+ currentFieldID +'" data-lang-code="'+ targetFieldID +'">'+langs[j]+'</button>';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -80,11 +55,11 @@ function requestCopyField(originID, targetID) {
|
|||
})
|
||||
.done(function(data) {
|
||||
/* Put the html data in the targetID field */
|
||||
var wrapperDiv = $('#' + targetID + '-count').parents('.input')[0];
|
||||
var wrapperDiv = $("#"+targetID+"-count").parents('.input')[0];
|
||||
$(wrapperDiv).html(data);
|
||||
})
|
||||
.fail(function(error) {
|
||||
console.log('wagtail-modeltranslation error: ' + error.responseText);
|
||||
console.log("wagtail-modeltranslation error: %s", error.responseText);
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
* Compares two software version numbers (e.g. "1.7.1" or "1.2b").
|
||||
*
|
||||
* This function was born in http://stackoverflow.com/a/6832721.
|
||||
*
|
||||
* @param {string} v1 The first version to be compared.
|
||||
* @param {string} v2 The second version to be compared.
|
||||
* @param {object} [options] Optional flags that affect comparison behavior.
|
||||
* @param {boolean} [options.lexicographical = false] Switch to compare version strings lexicographically instead of naturally.
|
||||
* @param {boolean} [options.zeroExtend = false] Switch to pad version with "zero" parts instead to be considered smaller.
|
||||
* <ul>
|
||||
* <li>
|
||||
* <tt>lexicographical: true</tt> compares each part of the version strings lexicographically instead of
|
||||
* naturally; this allows suffixes such as "b" or "dev" but will cause "1.10" to be considered smaller than
|
||||
* "1.2".
|
||||
* </li>
|
||||
* <li>
|
||||
* <tt>zeroExtend: true</tt> changes the result if one version string has less parts than the other. In
|
||||
* this case the shorter string will be padded with "zero" parts instead of being considered smaller.
|
||||
* </li>
|
||||
* </ul>
|
||||
* @returns {number|NaN}
|
||||
* <ul>
|
||||
* <li>0 if the versions are equal</li>
|
||||
* <li>a negative integer (-1) if v1 < v2</li>
|
||||
* <li>a positive integer (1) if v1 > v2</li>
|
||||
* <li>NaN if either version string is in the wrong format</li>
|
||||
* </ul>
|
||||
*
|
||||
* @copyright by Jon Papaioannou (["john", "papaioannou"].join(".") + "@gmail.com")
|
||||
* @license This function is in the public domain. Do what you want with it, no strings attached.
|
||||
*/
|
||||
function versionCompare(v1, v2, options) {
|
||||
var lexicographical = options && options.lexicographical,
|
||||
zeroExtend = options && options.zeroExtend,
|
||||
v1parts = v1.split('.'),
|
||||
v2parts = v2.split('.');
|
||||
|
||||
function isValidPart(x) {
|
||||
return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
|
||||
}
|
||||
|
||||
if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
|
||||
return NaN;
|
||||
}
|
||||
|
||||
if (zeroExtend) {
|
||||
while (v1parts.length < v2parts.length) v1parts.push("0");
|
||||
while (v2parts.length < v1parts.length) v2parts.push("0");
|
||||
}
|
||||
|
||||
if (!lexicographical) {
|
||||
v1parts = v1parts.map(Number);
|
||||
v2parts = v2parts.map(Number);
|
||||
}
|
||||
|
||||
for (var i = 0; i < v1parts.length; ++i) {
|
||||
if (v2parts.length == i) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (v1parts[i] == v2parts[i]) {
|
||||
continue;
|
||||
}
|
||||
else if (v1parts[i] > v2parts[i]) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (v1parts.length != v2parts.length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,36 +1,23 @@
|
|||
$(document).ready(function () {
|
||||
/* Only non-live pages should auto-populate the slug from the title */
|
||||
if (!$('body').hasClass('page-is-live')) {
|
||||
if(!translate_slugs) {
|
||||
lang_code = default_lang.replace("-", "_");
|
||||
title_selector = '#id_title_' + lang_code;
|
||||
slug_selector = '#id_slug';
|
||||
slugAutoPopulateTranslation(title_selector, slug_selector);
|
||||
} else {
|
||||
$.each(langs, function (idx, lang_code) {
|
||||
lang_code = lang_code.replace("-", "_");
|
||||
title_selector = '#id_title_' + lang_code;
|
||||
slug_selector = '#id_slug_' + lang_code;
|
||||
slugAutoPopulateTranslation(title_selector, slug_selector);
|
||||
var slugFollowsTitle = false;
|
||||
|
||||
$.each(langs, function (idx, lang_code) {
|
||||
lang_code = lang_code.replace("-", "_");
|
||||
$('#id_title_' + lang_code).on('focus', function () {
|
||||
/* slug should only follow the title field if its value matched the title's value at the time of focus */
|
||||
var currentSlug = $('#id_slug_' + lang_code).val();
|
||||
var slugifiedTitle = cleanForSlug(this.value);
|
||||
slugFollowsTitle = (currentSlug == slugifiedTitle);
|
||||
});
|
||||
}
|
||||
|
||||
$('#id_title_' + lang_code).on('keyup keydown keypress blur', function () {
|
||||
if (slugFollowsTitle) {
|
||||
var slugifiedTitle = cleanForSlug(this.value);
|
||||
$('#id_slug_' + lang_code).val(slugifiedTitle);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function slugAutoPopulateTranslation(title_selector, slug_selector) {
|
||||
var slugFollowsTitle = false;
|
||||
|
||||
$(title_selector).on('focus', function () {
|
||||
/* slug should only follow the title field if its value matched the title's value at the time of focus */
|
||||
var currentSlug = $(slug_selector).val();
|
||||
var slugifiedTitle = cleanForSlug(this.value, true);
|
||||
slugFollowsTitle = (currentSlug == slugifiedTitle);
|
||||
});
|
||||
|
||||
$(title_selector).on('keyup keydown keypress blur', function () {
|
||||
if (slugFollowsTitle) {
|
||||
var slugifiedTitle = cleanForSlug(this.value, true);
|
||||
$(slug_selector).val(slugifiedTitle);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
{% extends "wagtailadmin/base.html" %}
|
||||
{% load i18n %}
|
||||
{% block titletag %}{% blocktrans with title=page.get_admin_display_title %}Copy {{ title }}{% endblocktrans %}{% endblock %}
|
||||
{% block content %}
|
||||
{% trans "Copy" as copy_str %}
|
||||
{% include "wagtailadmin/shared/header.html" with title=copy_str subtitle=page.get_admin_display_title icon="doc-empty-inverse" %}
|
||||
|
||||
<div class="nice-padding">
|
||||
<form action="{% url 'wagtailadmin_pages:copy' page.id %}" method="POST" novalidate>
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="next" value="{{ next }}" />
|
||||
|
||||
<ul class="fields">
|
||||
{% for field in form.visible_fields %}
|
||||
{% include "wagtailadmin/shared/field_as_li.html" with field=field %}
|
||||
{% endfor %}
|
||||
|
||||
{% if form.copy_subpages %}
|
||||
{% include "wagtailadmin/shared/field_as_li.html" with field=form.copy_subpages %}
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
<input type="submit" value="{% trans 'Copy this page' %}" class="button">
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
{{ block.super }}
|
||||
{% include "wagtailadmin/pages/_editor_js.html" %}
|
||||
{% endblock %}
|
||||
|
|
@ -6,9 +6,9 @@ from django import template
|
|||
from django.utils.translation import activate, get_language
|
||||
|
||||
try:
|
||||
from django.urls import resolve
|
||||
except ImportError:
|
||||
from django.core.urlresolvers import resolve
|
||||
except ImportError:
|
||||
from django.urls import resolve
|
||||
|
||||
from six import iteritems
|
||||
|
||||
|
|
|
|||
|
|
@ -52,13 +52,9 @@ class PatchTestPage(WagtailPage):
|
|||
|
||||
|
||||
@register_snippet
|
||||
class PatchTestSnippetNoPanels(models.Model):
|
||||
class PatchTestSnippet(models.Model):
|
||||
name = models.CharField(max_length=10)
|
||||
|
||||
|
||||
@register_snippet
|
||||
class PatchTestSnippet(PatchTestSnippetNoPanels):
|
||||
|
||||
panels = [
|
||||
FieldPanel('name')
|
||||
]
|
||||
|
|
@ -78,8 +74,7 @@ class FieldPanelSnippet(models.Model):
|
|||
@register_snippet
|
||||
class ImageChooserPanelSnippet(models.Model):
|
||||
image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
on_delete=models.CASCADE,
|
||||
'wagtailimages.Image'
|
||||
)
|
||||
|
||||
panels = [
|
||||
|
|
@ -127,10 +122,7 @@ class MultiFieldPanelSnippet(FieldPanelSnippet, ImageChooserPanelSnippet, FieldR
|
|||
class BaseInlineModel(MultiFieldPanelSnippet):
|
||||
field_name = models.CharField(max_length=10)
|
||||
|
||||
image_chooser = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
on_delete=models.CASCADE,
|
||||
)
|
||||
image_chooser = models.ForeignKey('wagtailimages.Image')
|
||||
|
||||
fieldrow_name = models.CharField(max_length=10)
|
||||
|
||||
|
|
@ -166,8 +158,7 @@ class FieldPanelPage(WagtailPage):
|
|||
|
||||
class ImageChooserPanelPage(WagtailPage):
|
||||
image = models.ForeignKey(
|
||||
'wagtailimages.Image',
|
||||
on_delete=models.CASCADE,
|
||||
'wagtailimages.Image'
|
||||
)
|
||||
|
||||
content_panels = [
|
||||
|
|
|
|||
|
|
@ -21,5 +21,3 @@ MODELTRANSLATION_AUTO_POPULATE = False
|
|||
MODELTRANSLATION_FALLBACK_LANGUAGES = {'default': (MODELTRANSLATION_DEFAULT_LANGUAGE,)}
|
||||
|
||||
ROOT_URLCONF = 'wagtail_modeltranslation.tests.urls'
|
||||
|
||||
TRANSLATE_SLUGS = True
|
||||
|
|
|
|||
|
|
@ -13,10 +13,9 @@ from django.test.utils import override_settings
|
|||
from django.utils.translation import get_language, trans_real
|
||||
from modeltranslation import settings as mt_settings, translator
|
||||
try:
|
||||
from wagtail.snippets.views.snippets import get_snippet_edit_handler
|
||||
from wagtail import VERSION
|
||||
except ImportError:
|
||||
from wagtail.wagtailsnippets.views.snippets import get_snippet_edit_handler
|
||||
from wagtail import VERSION
|
||||
VERSION = 1, 6, 3 # assume it's 1.6.3, the latest version without VERSION
|
||||
from .util import page_factory
|
||||
|
||||
from wagtail_modeltranslation.tests.test_settings import TEST_SETTINGS
|
||||
|
|
@ -48,7 +47,8 @@ class WagtailModeltranslationTransactionTestBase(TransactionTestCase):
|
|||
if not WagtailModeltranslationTransactionTestBase.synced:
|
||||
# In order to perform only one syncdb
|
||||
WagtailModeltranslationTransactionTestBase.synced = True
|
||||
mgr = dummy_context_mgr()
|
||||
mgr = (override_settings(**TEST_SETTINGS) if django.VERSION < (1, 8)
|
||||
else dummy_context_mgr())
|
||||
with mgr:
|
||||
# 1. Reload translation in case USE_I18N was False
|
||||
from django.utils import translation as dj_trans
|
||||
|
|
@ -99,14 +99,15 @@ class WagtailModeltranslationTransactionTestBase(TransactionTestCase):
|
|||
|
||||
# 5. makemigrations
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
call_command('makemigrations', verbosity=2, interactive=False)
|
||||
|
||||
# 6. Syncdb
|
||||
call_command('migrate', verbosity=0, interactive=False, run_syncdb=True,
|
||||
call_command('makemigrations', verbosity=2, interactive=False,
|
||||
database=connections[DEFAULT_DB_ALIAS].alias)
|
||||
|
||||
# 6. Syncdb
|
||||
call_command('migrate', verbosity=0, migrate=False, interactive=False, run_syncdb=True,
|
||||
database=connections[DEFAULT_DB_ALIAS].alias, load_initial_data=False)
|
||||
|
||||
# 7. Make sure Page translation fields are created
|
||||
call_command('sync_page_translation_fields', interactive=False, verbosity=0)
|
||||
call_command('sync_page_translation_fields', interactive=False, verbosity=0, database=connections[DEFAULT_DB_ALIAS].alias)
|
||||
|
||||
# 8. patch wagtail models
|
||||
from wagtail_modeltranslation.patch_wagtailadmin import patch_wagtail_models
|
||||
|
|
@ -307,8 +308,6 @@ class WagtailModeltranslationTest(WagtailModeltranslationTestBase):
|
|||
|
||||
def test_snippet_patching(self):
|
||||
self.check_fieldpanel_patching(panels=models.FieldPanelSnippet.panels)
|
||||
self.check_panels_patching(models.FieldPanelSnippet, ['name_de', 'name_en'])
|
||||
|
||||
self.check_imagechooserpanel_patching(panels=models.ImageChooserPanelSnippet.panels)
|
||||
self.check_fieldrowpanel_patching(panels=models.FieldRowPanelSnippet.panels)
|
||||
self.check_streamfieldpanel_patching(panels=models.StreamFieldPanelSnippet.panels)
|
||||
|
|
@ -318,24 +317,6 @@ class WagtailModeltranslationTest(WagtailModeltranslationTestBase):
|
|||
# which is the SnippetInlineModel
|
||||
self.check_inlinepanel_patching(panels=models.SnippetInlineModel.panels)
|
||||
|
||||
# Case we don't define panels on snippet
|
||||
self.check_panels_patching(models.PatchTestSnippetNoPanels, ['name_de', 'name_en'])
|
||||
|
||||
def check_panels_patching(self, model, model_fields):
|
||||
patched_edit_handler = get_snippet_edit_handler(model)
|
||||
|
||||
if VERSION[0] < 2:
|
||||
form = patched_edit_handler.get_form_class(model)
|
||||
else:
|
||||
form = patched_edit_handler.get_form_class()
|
||||
|
||||
try:
|
||||
# python 3
|
||||
self.assertEqual(model_fields, list(form.base_fields.keys()))
|
||||
except AttributeError:
|
||||
# python 2.7
|
||||
self.assertItemsEqual(model_fields, form.base_fields.keys())
|
||||
|
||||
def test_page_form(self):
|
||||
"""
|
||||
In this test we use the InlinePanelPage model because it has all the possible "patchable" fields
|
||||
|
|
@ -344,7 +325,7 @@ class WagtailModeltranslationTest(WagtailModeltranslationTestBase):
|
|||
|
||||
page_edit_handler = models.InlinePanelPage.get_edit_handler()
|
||||
|
||||
if VERSION < (2,):
|
||||
if VERSION[0] < 2:
|
||||
form = page_edit_handler.get_form_class(models.InlinePanelPage)
|
||||
else:
|
||||
form = page_edit_handler.get_form_class()
|
||||
|
|
@ -377,9 +358,13 @@ class WagtailModeltranslationTest(WagtailModeltranslationTestBase):
|
|||
In this test we use the InlinePanelSnippet model because it has all the possible "patchable" fields
|
||||
so if the created form has all fields the the form was correctly patched
|
||||
"""
|
||||
try:
|
||||
from wagtail.snippets.views.snippets import get_snippet_edit_handler
|
||||
except ImportError:
|
||||
from wagtail.wagtailsnippets.views.snippets import get_snippet_edit_handler
|
||||
snippet_edit_handler = get_snippet_edit_handler(models.InlinePanelSnippet)
|
||||
|
||||
if VERSION < (2,):
|
||||
if VERSION[0] < 2:
|
||||
form = snippet_edit_handler.get_form_class(models.InlinePanelSnippet)
|
||||
else:
|
||||
form = snippet_edit_handler.get_form_class()
|
||||
|
|
|
|||
|
|
@ -1,29 +1,12 @@
|
|||
# coding: utf-8
|
||||
from modeltranslation.translator import (TranslationOptions, register,
|
||||
translator)
|
||||
from modeltranslation.translator import translator, register, TranslationOptions
|
||||
|
||||
from wagtail_modeltranslation.tests.models import TestRootPage, TestSlugPage1, TestSlugPage2, PatchTestPage, \
|
||||
PatchTestSnippet, FieldPanelPage, ImageChooserPanelPage, FieldRowPanelPage, MultiFieldPanelPage, InlinePanelPage, \
|
||||
FieldPanelSnippet, ImageChooserPanelSnippet, FieldRowPanelSnippet, MultiFieldPanelSnippet, PageInlineModel, \
|
||||
BaseInlineModel, StreamFieldPanelPage, StreamFieldPanelSnippet, SnippetInlineModel, InlinePanelSnippet, \
|
||||
TestSlugPage1Subclass, RoutablePageTest
|
||||
|
||||
from wagtail_modeltranslation.tests.models import (BaseInlineModel,
|
||||
FieldPanelPage,
|
||||
FieldPanelSnippet,
|
||||
FieldRowPanelPage,
|
||||
FieldRowPanelSnippet,
|
||||
ImageChooserPanelPage,
|
||||
ImageChooserPanelSnippet,
|
||||
InlinePanelPage,
|
||||
InlinePanelSnippet,
|
||||
MultiFieldPanelPage,
|
||||
MultiFieldPanelSnippet,
|
||||
PageInlineModel,
|
||||
PatchTestPage,
|
||||
PatchTestSnippet,
|
||||
PatchTestSnippetNoPanels,
|
||||
RoutablePageTest,
|
||||
SnippetInlineModel,
|
||||
StreamFieldPanelPage,
|
||||
StreamFieldPanelSnippet,
|
||||
TestRootPage, TestSlugPage1,
|
||||
TestSlugPage1Subclass,
|
||||
TestSlugPage2)
|
||||
|
||||
# Wagtail Models
|
||||
|
||||
|
|
@ -52,14 +35,11 @@ class PatchTestPageTranslationOptions(TranslationOptions):
|
|||
fields = ('description',)
|
||||
|
||||
|
||||
@register(PatchTestSnippetNoPanels)
|
||||
class PatchTestSnippetNoPanelsTranslationOptions(TranslationOptions):
|
||||
class PatchTestSnippetTranslationOptions(TranslationOptions):
|
||||
fields = ('name',)
|
||||
|
||||
|
||||
@register(PatchTestSnippet)
|
||||
class PatchTestSnippetTranslationOptions(TranslationOptions):
|
||||
pass
|
||||
translator.register(PatchTestSnippet, PatchTestSnippetTranslationOptions)
|
||||
|
||||
|
||||
# Panel Patching Models
|
||||
|
|
|
|||
|
|
@ -2,23 +2,17 @@
|
|||
|
||||
from modeltranslation.decorators import register
|
||||
from modeltranslation.translator import TranslationOptions
|
||||
from wagtail_modeltranslation import settings
|
||||
try:
|
||||
from wagtail.core.models import Page
|
||||
except ImportError:
|
||||
from wagtail.wagtailcore.models import Page
|
||||
|
||||
|
||||
|
||||
@register(Page)
|
||||
class PageTR(TranslationOptions):
|
||||
fields = (
|
||||
'title',
|
||||
'slug',
|
||||
'seo_title',
|
||||
'search_description',
|
||||
'url_path',
|
||||
)
|
||||
if settings.TRANSLATE_SLUGS:
|
||||
fields += (
|
||||
'slug',
|
||||
'url_path',
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,35 +2,21 @@
|
|||
|
||||
import json
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from six import iteritems
|
||||
from django.conf import settings
|
||||
from django.conf.urls import url
|
||||
from django.http import HttpResponse, QueryDict
|
||||
from django.shortcuts import redirect, render
|
||||
from django.templatetags.static import static
|
||||
from django.utils.html import escape, format_html, format_html_join
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.http import HttpResponse
|
||||
from django.http import QueryDict
|
||||
from django.utils.html import format_html, format_html_join, escape
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from wagtail_modeltranslation import settings as wmt_settings
|
||||
from modeltranslation import settings as mt_settings
|
||||
|
||||
from .patch_wagtailadmin_forms import PatchedCopyForm
|
||||
|
||||
from six import iteritems
|
||||
try:
|
||||
from wagtail.core import hooks
|
||||
from wagtail.core.models import Page
|
||||
from wagtail.core.rich_text.pages import PageLinkHandler
|
||||
from wagtail.core import __version__ as WAGTAIL_VERSION
|
||||
from wagtail.admin import messages
|
||||
from wagtail.admin.views.pages import get_valid_next_url_from_request
|
||||
except ImportError:
|
||||
from wagtail.wagtailcore import hooks
|
||||
from wagtail.wagtailcore.models import Page
|
||||
from wagtail.wagtailcore.rich_text import PageLinkHandler
|
||||
from wagtail.wagtailcore import __version__ as WAGTAIL_VERSION
|
||||
from wagtail.wagtailadmin import messages
|
||||
from wagtail.wagtailadmin.views.pages import get_valid_next_url_from_request
|
||||
|
||||
|
||||
@hooks.register('insert_editor_js')
|
||||
|
|
@ -39,25 +25,15 @@ def translated_slugs():
|
|||
'wagtail_modeltranslation/js/wagtail_translated_slugs.js',
|
||||
]
|
||||
|
||||
js_includes = format_html_join('\n', '<script src="{0}"></script>', (
|
||||
(static(filename),) for filename in js_files)
|
||||
)
|
||||
js_includes = format_html_join('\n', '<script src="{0}{1}"></script>', (
|
||||
(settings.STATIC_URL, filename) for filename in js_files)
|
||||
)
|
||||
|
||||
lang_codes = []
|
||||
for lang in settings.LANGUAGES:
|
||||
lang_codes.append("'%s'" % lang[0])
|
||||
|
||||
js_languages = """
|
||||
<script>
|
||||
var langs=[{langs}];
|
||||
var default_lang='{default_lang}';
|
||||
var translate_slugs={translate_slugs};
|
||||
</script>
|
||||
""".format(
|
||||
langs=", ".join(lang_codes),
|
||||
default_lang=mt_settings.DEFAULT_LANGUAGE,
|
||||
translate_slugs='true' if wmt_settings.TRANSLATE_SLUGS else 'false'
|
||||
)
|
||||
js_languages = "<script>var langs=[%s];</script>" % (", ".join(lang_codes))
|
||||
|
||||
return format_html(js_languages) + js_includes
|
||||
|
||||
|
|
@ -131,26 +107,21 @@ def streamfields_translation_copy():
|
|||
|
||||
# includes the javascript file in the html file
|
||||
js_files = [
|
||||
'wagtail_modeltranslation/js/version_compare.js',
|
||||
'wagtail_modeltranslation/js/copy_stream_fields.js',
|
||||
]
|
||||
|
||||
js_includes = format_html_join('\n', '<script src="{0}"></script>', (
|
||||
(static(filename),) for filename in js_files)
|
||||
)
|
||||
js_includes = format_html_join('\n', '<script src="{0}{1}"></script>', (
|
||||
(settings.STATIC_URL, filename) for filename in js_files)
|
||||
)
|
||||
|
||||
js_wagtail_version = """
|
||||
<script>
|
||||
var WAGTAIL_VERSION='{wagtail_version}';
|
||||
</script>
|
||||
""".format(wagtail_version=WAGTAIL_VERSION)
|
||||
return format_html(js_wagtail_version) + js_includes
|
||||
return js_includes
|
||||
|
||||
|
||||
@hooks.register('insert_editor_css')
|
||||
def modeltranslation_page_editor_css():
|
||||
filename = 'wagtail_modeltranslation/css/page_editor_modeltranslation.css'
|
||||
return format_html('<link rel="stylesheet" href="{}" >'.format(static(filename)))
|
||||
return format_html('<link rel="stylesheet" href="'
|
||||
+ settings.STATIC_URL
|
||||
+ 'wagtail_modeltranslation/css/page_editor_modeltranslation.css" >')
|
||||
|
||||
|
||||
@hooks.register('register_rich_text_link_handler')
|
||||
|
|
@ -176,70 +147,3 @@ def register_localized_page_link_handler():
|
|||
return "<a>"
|
||||
|
||||
return ('page', LocalizedPageLinkHandler)
|
||||
|
||||
|
||||
@hooks.register('before_copy_page')
|
||||
def before_copy_page(request, page):
|
||||
parent_page = page.get_parent()
|
||||
can_publish = parent_page.permissions_for_user(request.user).can_publish_subpage()
|
||||
form = PatchedCopyForm(request.POST or None, user=request.user, page=page, can_publish=can_publish)
|
||||
next_url = get_valid_next_url_from_request(request)
|
||||
|
||||
if request.method == 'POST':
|
||||
# Prefill parent_page in case the form is invalid (as prepopulated value for the form field,
|
||||
# because ModelChoiceField seems to not fall back to the user given value)
|
||||
parent_page = Page.objects.get(id=request.POST['new_parent_page'])
|
||||
|
||||
if form.is_valid():
|
||||
# Receive the parent page (this should never be empty)
|
||||
if form.cleaned_data['new_parent_page']:
|
||||
parent_page = form.cleaned_data['new_parent_page']
|
||||
|
||||
if not page.permissions_for_user(request.user).can_copy_to(parent_page,
|
||||
form.cleaned_data.get('copy_subpages')):
|
||||
raise PermissionDenied
|
||||
|
||||
# Re-check if the user has permission to publish subpages on the new parent
|
||||
can_publish = parent_page.permissions_for_user(request.user).can_publish_subpage()
|
||||
|
||||
update_attrs = {}
|
||||
for code, name in settings.LANGUAGES:
|
||||
slug = "slug_{}".format(code)
|
||||
title = "title_{}".format(code)
|
||||
update_attrs[slug] = form.cleaned_data["new_{}".format(slug)]
|
||||
update_attrs[title] = form.cleaned_data["new_{}".format(title)]
|
||||
|
||||
# Copy the page
|
||||
new_page = page.copy(
|
||||
recursive=form.cleaned_data.get('copy_subpages'),
|
||||
to=parent_page,
|
||||
update_attrs=update_attrs,
|
||||
keep_live=(can_publish and form.cleaned_data.get('publish_copies')),
|
||||
user=request.user,
|
||||
)
|
||||
|
||||
# Give a success message back to the user
|
||||
if form.cleaned_data.get('copy_subpages'):
|
||||
messages.success(
|
||||
request,
|
||||
_("Page '{0}' and {1} subpages copied.").format(
|
||||
page.get_admin_display_title(), new_page.get_descendants().count())
|
||||
)
|
||||
else:
|
||||
messages.success(request, _("Page '{0}' copied.").format(page.get_admin_display_title()))
|
||||
|
||||
for fn in hooks.get_hooks('after_copy_page'):
|
||||
result = fn(request, page, new_page)
|
||||
if hasattr(result, 'status_code'):
|
||||
return result
|
||||
|
||||
# Redirect to explore of parent page
|
||||
if next_url:
|
||||
return redirect(next_url)
|
||||
return redirect('wagtailadmin_explore', parent_page.id)
|
||||
|
||||
return render(request, 'modeltranslation_copy.html', {
|
||||
'page': page,
|
||||
'form': form,
|
||||
'next': next_url
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue