Compare commits

...
998 Commits
Author SHA1 Message Date
Martin Koistinen b1a1492b89 Bump to 3.1.6 2016-04-26 12:38:07 -04:00
Martin Koistinen 382a092010 Update CHANGLOG, release notes, AUTHORS 2016-04-26 12:37:28 -04:00
Martin Koistinen 7ea5098754 Update translations 2016-04-26 12:37:07 -04:00
Martin Koistinen 941b57af02 Merge pull request #5211 from mkoistinen/feature/sanitize_appconfig_widget_31
Sanitize AppConfig Widget (forward port from 3.0)
2016-04-26 10:24:45 -04:00
Martin Koistinen d64edceb58 Further escaping for JS 2016-04-26 09:23:59 -04:00
Angelo Dini c642a9b0c1 Merge pull request #5207 from mkoistinen/feature/sanitize_pagefield_output_31
Sanitize Pagefield Output (forward port from 3.0)
2016-04-26 10:26:07 +02:00
Martin Koistinen dff4eb2241 Adds test for widget escaping 2016-04-25 20:21:06 -04:00
Martin Koistinen 8f4ecc311b Forward-port from 3.0 2016-04-25 18:32:31 -04:00
Martin Koistinen 34bbd12920 Merge pull request #5188 from yakky/feature/fix_5138
Correct the fix in #5133
2016-04-20 21:21:46 -04:00
Iacopo Spalletti 9259845f93 Correct the fix in #5133 2016-04-20 20:46:45 +02:00
Martin Koistinen dccb411d7f Merge pull request #5187 from mkoistinen/issue/fix_bad_merge_in_test_requirements
Fix bad git merge
2016-04-20 14:39:17 -04:00
Martin Koistinen 3164ea2040 Fix bad git merge 2016-04-20 14:37:53 -04:00
Martin Koistinen c455d3c614 Merge pull request #5168 from mkoistinen/issue/removes_mark_safe
Address security concerns in render_model* tags
2016-04-20 13:03:55 -04:00
Martin Koistinen e149e0bdd9 Changelog entry 2016-04-20 09:41:02 -04:00
Martin Koistinen 5bedd2b6da Update docs to make it clearer what will happen with setting is removed 2016-04-20 09:40:55 -04:00
Martin Koistinen 8a4e152f8e Merge pull request #3 from vxsx/issue/removes_mark_safe
use `html` instead of `text` method in the message open
2016-04-20 09:03:11 -04:00
Vadim Sikora 2f26ac67ce use html instead of text method in the message open
modern browsers will use escaped version of the text, meaning
`>script<alert(1);>/script<` would actually render script
tag with an alert in the message
2016-04-19 10:52:22 +02:00
Martin Koistinen b68175970a Remove unneeded code-paths 2016-04-18 13:11:42 -04:00
Martin Koistinen 6b9e112448 Better organise imports 2016-04-18 12:07:20 -04:00
Martin Koistinen ac76517411 Updates per comments 2016-04-18 12:05:58 -04:00
Martin Koistinen 370d322e32 Address security concerns in render_model* tags 2016-04-17 00:54:08 -04:00
Iacopo Spalletti 3bfbea6e43 Merge pull request #5138 from yakky/merge/5133
Merge #5133
2016-04-07 09:15:37 +02:00
Iacopo Spalletti 628072b6e2 Skip failing test due to incompatible plugins 2016-04-07 07:54:12 +02:00
Iacopo Spalletti 962305a955 Fix requirements 2016-04-06 16:48:09 +02:00
Iacopo Spalletti 6425a0759c Add south migration 2016-04-06 14:35:27 +02:00
Piotr Jakimiak 85cd73b479 Add missing permission name 2016-04-06 14:19:23 +02:00
Iacopo Spalletti 0eb535fafc Merge pull request #5005 from yakky/feature/fix_uninstall_app
Fix #5004
2016-02-20 21:31:04 +01:00
Iacopo Spalletti bcd5926fa2 Fix #5004 2016-02-14 16:54:15 +01:00
Iacopo Spalletti 33b374a7fe Merge pull request #4990 from yakky/merge/3.0.17.pre1
Merge from 3.0.x branch
2016-02-10 22:45:44 +01:00
Iacopo Spalletti e26853c4b6 Merge remote-tracking branch 'upstream/support/3.0.x' into support/3.1.x 2016-02-10 21:22:01 +01:00
Iacopo Spalletti 4414c66423 Merge pull request #4986 from yakky/feature/fix_cache_settings
Fix cache settings
2016-02-10 18:27:26 +01:00
Iacopo Spalletti 447175af18 Merge pull request #4989 from yakky/merge/4975
Add missing block into page change_form template.
2016-02-09 14:27:23 +01:00
Iacopo Spalletti 706e52ed21 Pick right xvfwrapper 2016-02-09 13:39:33 +01:00
Martin Bambas 7b2d513a8e Add missing block into page change_form template. 2016-02-09 08:28:59 +01:00
Iacopo Spalletti 40902a74fd Pin django-classy-tags 2016-02-07 19:29:11 +01:00
Iacopo Spalletti fef05cabdf Update changelog 2016-02-07 18:05:47 +01:00
Iacopo Spalletti 8fbd4fd0a6 Fix cache settings 2016-02-07 17:56:45 +01:00
Iacopo Spalletti ac64b76654 Bump to 3.1.6.dev1 2016-01-29 16:19:49 +01:00
Iacopo Spalletti 7651c0127e Bump version to 3.1.5 2016-01-29 16:00:34 +01:00
Iacopo Spalletti 9c5f99f9eb Update changelog 2016-01-29 16:00:15 +01:00
Iacopo Spalletti 20f95807a4 Merge pull request #4960 from yakky/feature/prepare_315
Update changelog and other updates for 3.1.5
2016-01-29 09:44:38 +01:00
Iacopo Spalletti 9f16969ee7 Update changelog and other updates for 3.1.5 2016-01-27 19:56:25 +01:00
Iacopo Spalletti 53518b91fc Merge pull request #4946 from yakky/feature/fix_plugin_validation
Move templates validation in app.ready
2016-01-26 14:54:43 +01:00
Martin Koistinen 70142436ae Merge pull request #4955 from yakky/feature/render_super
Improve CMSPluginBase.render documentation
2016-01-26 14:37:32 +01:00
Iacopo Spalletti 01cbda0183 Merge pull request #4950 from yakky/merge/4771
Merge #4772
2016-01-26 07:35:04 +01:00
Iacopo Spalletti 159b597896 Improve CMSPluginBase.render documentation 2016-01-26 07:27:39 +01:00
Iacopo Spalletti 82acedefee Merge remote-tracking branch 'upstream/support/3.1.x' into merge/4771 2016-01-25 16:46:43 +01:00
Iacopo Spalletti 6ede6f59c6 Merge remote-tracking branch 'upstream/support/3.1.x' into feature/fix_plugin_validation 2016-01-25 16:46:25 +01:00
Martin Koistinen 8ebae458c6 Merge pull request #4949 from yakky/feature/fix_context
Fix CMSEditableObject context generation
2016-01-25 08:40:54 -05:00
Iacopo Spalletti 19abf1c4c4 Add test for #4771 2016-01-24 16:32:33 +01:00
Marijn Goedegebure e5f7d0ec38 #4771 Adjusted get_object_public_url and get_object_draft_url to use language attribute. 2016-01-24 16:31:37 +01:00
Iacopo Spalletti f9a8b38b60 Fix CMSEditableObject context generation 2016-01-23 13:51:00 +01:00
Iacopo Spalletti ea2ce14b75 Move templates validation in app.ready 2016-01-23 10:41:54 +01:00
Iacopo Spalletti b4eee45e9b Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD 2016-01-16 13:21:00 +01:00
Iacopo Spalletti dee09dfe09 Merge pull request #4925 from yakky/feature/fix_file_test
fix test
2016-01-16 09:36:12 +01:00
Iacopo Spalletti 17a6868a04 fix test 2016-01-16 08:07:39 +01:00
Iacopo Spalletti 42bd941c46 Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD 2016-01-14 20:12:51 +01:00
Iacopo Spalletti 84575c4497 Merge pull request #4896 from yakky/feature/fix_toolbar_ext
Fix ExtensionToolbar when language is removed but titles still exists…
2016-01-14 20:12:26 +01:00
Paulo 2df20b1a40 Merge pull request #4910 from czpython/fixes/pages-menu-missing-on-fresh-install-3.1
Fixes/pages menu missing on fresh install 3.1
2016-01-13 09:09:41 -05:00
Paulo 3941e426e4 on 3.1 there's only 10 2016-01-12 21:32:50 -05:00
Paulo c59b8fcfe7 fixes invalid translation on startup 2016-01-12 18:12:29 -05:00
Paulo d99f1cfc3e fixes failing tests 2016-01-12 17:42:39 -05:00
Paulo 55ce5c0dd2 cosmetics 2016-01-12 17:41:15 -05:00
Paulo 758da5b987 fixes issue with page menu missing 2016-01-12 17:41:03 -05:00
Iacopo Spalletti 1a5179cc17 Fix ExtensionToolbar when language is removed but titles still exists. See nephila/djangocms-page-meta#34 2016-01-09 07:30:32 +01:00
Paulo 2865f19afd fixes incorrect language on placeholder text for redirect field 2016-01-08 16:10:17 -05:00
Iacopo Spalletti ae74399b0b Merge pull request #4892 from czpython/docs/upgrade-docs-for-3.1.5
Adds 3.1.5 upgrade docs.
2016-01-07 13:54:24 +01:00
Paulo d0d119cd85 Adds 3.1.5 upgrade docs. 2016-01-06 10:32:00 -05:00
Iacopo Spalletti 27cf2ab9c7 Merge pull request #4888 from yakky/merge/3.0.16.pre2
Sync 3.1 and 3.0 branch
2016-01-05 13:40:52 +01:00
Iacopo Spalletti 583afaa85a Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD 2016-01-05 11:46:29 +01:00
Iacopo Spalletti 95f9944ade Merge pull request #4887 from yakky/merge/4858
Merge #4546 in 3.0.x
2016-01-05 11:41:36 +01:00
Steffen Jasper 48a1b845a2 Fix PageSelectWidget JS synax
Original JS raise exception: `Syntax error, unrecognized expression
#id_page_2 option[value]`
2016-01-05 10:26:57 +01:00
Paulo bfe7002961 Merge pull request #4881 from czpython/fixes/3.1-issue-4856
Fixes 3.1 issue #4856
2015-12-31 09:14:52 -05:00
Paulo 21d34a3b9f small note on why update_fields 2015-12-30 15:24:31 -05:00
Paulo 2d79296b28 adds fix for #4856 2015-12-30 15:23:30 -05:00
Paulo 164d74bdad rewrites/fixes test for issue #4856 2015-12-30 15:21:29 -05:00
Paulo 23419bab0c adjust ckeditor tests 2015-12-30 15:17:27 -05:00
Martin Koistinen ba4ef1478d Merge pull request #4854 from divio/dont_assume_toolbar_is_present
Don't assume toolbar is present
2015-12-16 08:58:45 -05:00
Martin Koistinen f4f0ee7da9 Fix literal in doc 2015-12-15 15:33:51 -05:00
Martin Koistinen d1aba902f8 Clean up description a bit in the docs 2015-12-15 15:01:16 -05:00
Martin Koistinen a86dce368a Don't assume the toolbar property will exist 2015-12-15 15:01:06 -05:00
Iacopo Spalletti d19a54a14d Merge pull request #4851 from yakky/feature/fix_redirect_toolbar_disable
Fix redirect when disabling toolbar
2015-12-14 15:12:38 +01:00
Iacopo Spalletti eaf7959b6c Fix redirect when disabling toolbar 2015-12-13 22:06:02 +01:00
Iacopo Spalletti 75fb886c9a Bump development version 2015-11-24 14:54:34 +01:00
Iacopo Spalletti ebde18f595 Bump development version 2015-11-24 14:53:38 +01:00
Martin Koistinen 31fe02c988 Bump to 3.0.16 2015-11-24 01:02:18 -05:00
Martin Koistinen 608932e277 Update authors 2015-11-24 01:02:05 -05:00
Martin Koistinen 8dc6e6f0cf Update changelog 2015-11-24 01:02:01 -05:00
Martin Koistinen 99dc645adb Update translations 2015-11-24 01:01:51 -05:00
Martin Koistinen 4dc7320a8f Bump to 3.1.4 2015-11-24 00:56:00 -05:00
Martin Koistinen d0c3b3fb6d Update changelog 2015-11-24 00:55:52 -05:00
Martin Koistinen 1c30252764 Update authors 2015-11-24 00:55:46 -05:00
Martin Koistinen 2caeb3cd10 Update translations 2015-11-24 00:55:39 -05:00
Martin Koistinen c8c2113e3c Merge pull request #4751 from divio/revert-4748-pin_djangocms_admin_style_31
Revert "CMS 3.1.x cannot use admin-style 2.8+"
2015-11-19 12:38:51 -05:00
Martin Koistinen ded7fd0886 Merge pull request #4750 from divio/revert-4749-pin_djangocms_admin_style_30
Revert "CMS 3.0 cannot use admin-style >= 2.8.0"
2015-11-19 12:38:42 -05:00
Martin Koistinen f625d421dd Revert "CMS 3.1.x cannot use admin-style 2.8+" 2015-11-19 12:37:23 -05:00
Martin Koistinen 966592f1bc Revert "CMS 3.0 cannot use admin-style >= 2.8.0" 2015-11-19 12:37:14 -05:00
Martin Koistinen aaac7fa4ce Merge pull request #4749 from divio/pin_djangocms_admin_style_30
CMS 3.0 cannot use admin-style >= 2.8.0
2015-11-19 11:51:16 -05:00
Martin Koistinen 6620bdf26b Merge pull request #4748 from divio/pin_djangocms_admin_style_31
CMS 3.1.x cannot use admin-style 2.8+
2015-11-19 11:51:02 -05:00
Martin Koistinen e4d461cd41 CMS 3.0 cannot use admin-style >= 2.8.0 2015-11-19 11:27:08 -05:00
Martin Koistinen 980c9219d4 CMS 3.1.x cannot use admin-style 2.8+ 2015-11-19 11:26:21 -05:00
Iacopo Spalletti d5ad2286f3 Merge pull request #4738 from yakky/merge/3.0.16.pre
Merge from 3.0.x
2015-11-19 13:22:25 +01:00
Iacopo Spalletti 02cb24901d Merge remote-tracking branch 'upstream/support/3.0.x' into merge/3.0.16.pre 2015-11-19 10:12:32 +01:00
Iacopo Spalletti dca9fee375 Hotfix for googlemap change 2015-11-19 10:10:53 +01:00
Iacopo Spalletti 00dcc99a84 Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD 2015-11-19 09:15:23 +01:00
Iacopo Spalletti 83acd7e57c Merge pull request #4727 from divio/fix_revert_to_live_30
Fix revert to live 30
2015-11-18 23:39:08 +01:00
Iacopo Spalletti ef60fe921d Remove exception 2015-11-18 21:42:01 +01:00
Iacopo Spalletti be96744dd5 Merge pull request #4732 from divio/revert-4725-feature/change_migration
Revert "Change migration dependency"
2015-11-18 18:32:53 +01:00
Iacopo Spalletti 6eb3e9ecee Ping djangocms-admin-style 2015-11-18 10:14:20 +01:00
Iacopo Spalletti 7a25cb843f Fix dependency versions 2015-11-18 08:03:15 +01:00
Iacopo Spalletti fa07552860 Revert "Change migration dependency" 2015-11-18 07:59:19 +01:00
Martin Koistinen 4172a4e5f1 Merge pull request #4725 from yakky/feature/change_migration
Change migration dependency
2015-11-17 22:43:25 -05:00
Martin Koistinen 3c3dbed015 Don't show 'Revert to live' if there isn't one! 2015-11-17 01:13:44 -05:00
Martin Koistinen 863dc524e4 Use live page's url if available 2015-11-17 01:07:40 -05:00
Iacopo Spalletti cad66b335d Merge pull request #4723 from yakky/merge/4716
Fixing run migrations when = True
2015-11-17 05:54:24 +01:00
Martin Koistinen 400a5e8a1e Merge pull request #4717 from yakky/feature/treebeard
Fix treebeard issues
2015-11-16 21:55:18 -05:00
Christian Strappazzon ad736afd73 Fixing run migrations in a fresh install django-cms when CMS_PERMISSION = CMS_RAW_ID_USERS = True 2015-11-16 22:45:22 +01:00
Iacopo Spalletti edf6d6f310 Update changelogs 2015-11-16 22:21:00 +01:00
Iacopo Spalletti 6d037d1e0a Merge pull request #4702 from yakky/feature/staticfiles
use staticfiles instead of static
2015-11-13 19:04:42 +01:00
Iacopo Spalletti 70261b5d6d use staticfiles instead of static 2015-11-13 08:10:45 +01:00
Iacopo Spalletti 24224bbe16 Change migration dependency 2015-11-11 23:03:13 +01:00
Iacopo Spalletti c29bb785ae Improve tests 2015-11-11 21:48:29 +01:00
Iacopo Spalletti a1082d4460 Fix delete 2015-11-11 21:32:53 +01:00
Iacopo Spalletti 63d518cfc2 Merge pull request #4643 from yakky/merge/4641
Merge 4641 in 3.1.x
2015-11-01 17:04:55 +01:00
Iacopo Spalletti b04c13800d Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD 2015-11-01 15:39:36 +01:00
Iacopo Spalletti ab0c0d20b7 Merge pull request #4641 from yakky/feature/fix_dates_test
Fix dates test
2015-11-01 15:21:48 +01:00
Iacopo Spalletti ac38a667ab Use only dates for Django 1.4 2015-11-01 13:18:20 +01:00
Iacopo Spalletti c74b507aef Set explicit TZ for test 2015-11-01 10:09:23 +01:00
Iacopo Spalletti 49f52642b0 Remove prints 2015-11-01 10:09:10 +01:00
Iacopo Spalletti 051b659f43 Merge pull request #4638 from yakky/merge/4637
Update toolbar.rst
2015-11-01 09:12:28 +01:00
xie wei 221ebecccb Update toolbar.rst
Fixed spelling
2015-10-31 11:53:48 +01:00
Iacopo Spalletti 209cb7867a Merge pull request #4590 from yakky/merge/3.0.x_16
Merge/3.0.x 16
2015-10-15 05:32:31 +02:00
Iacopo Spalletti f97342a8de Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD 2015-10-14 08:46:35 +02:00
Iacopo Spalletti c47ec74fde Merge pull request #4583 from yakky/merge/4452
Merge #4452
2015-10-13 22:47:06 +02:00
Iacopo Spalletti 89a84ec573 Fix django debug toolbar test dependency 2015-10-13 19:52:25 +02:00
Venelin Stoykov fef0afab61 Raise 404 instead of returing it
Fixes #4451
2015-10-13 18:19:22 +02:00
Iacopo Spalletti 6658dfdb4f Merge pull request #4529 from yakky/feature/test_django19
Add python 3.5 to support matrix
2015-10-03 17:49:55 +02:00
Iacopo Spalletti ac8f28fcb1 Add Django 1.9 to support matrix 2015-09-26 09:40:33 +02:00
Iacopo Spalletti 9b00f57d4e Merge pull request #4493 from yakky/merge/3.0.16-pre
Forwardport from 3.0.x
2015-09-24 20:41:06 +01:00
Iacopo Spalletti 68c4059b3b Merge remote-tracking branch 'upstream/support/3.0.x' into merge/3.0.16-pre 2015-09-24 17:49:41 +02:00
Iacopo Spalletti 2ebee013bb Merge pull request #4498 from yakky/feature/reldocs_3016
Prepare draft release notes for 3.0.16
2015-09-24 16:47:14 +01:00
Iacopo Spalletti 0eac11c9e5 Add release draft release notes 3.1.4 2015-09-24 13:22:53 +02:00
Iacopo Spalletti c860332416 Merge branch 'feature/reldocs_3016' into merge/3.0.16-pre
Conflicts:
	CHANGELOG.txt
	docs/upgrade/index.rst
2015-09-24 13:19:08 +02:00
Iacopo Spalletti 7fa8c6eddf Prepare draft release notes for 3.0.16 2015-09-24 13:15:40 +02:00
Iacopo Spalletti ac65fcdf82 Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD
Conflicts:
	cms/tests/frontend.py
2015-09-24 09:44:10 +02:00
Iacopo Spalletti 088a3e3947 Merge pull request #4472 from yakky/feature/fix_structure_migration
Fix use structure migration
2015-09-24 08:30:05 +01:00
Iacopo Spalletti 8ab83d455f Merge pull request #4489 from yakky/feature/disable_fe_test
Skip FE test on Django 1.7
2015-09-24 08:29:53 +01:00
Iacopo Spalletti 8b1e41ca57 Skip FE test on Django 1.7 2015-09-23 19:25:08 +02:00
Iacopo Spalletti 052a3dc2e7 Remove unicode_literals 2015-09-23 17:43:22 +02:00
Iacopo Spalletti 6b1096cffa Use warnings instead of print [ci skip] 2015-09-23 15:57:57 +02:00
Iacopo Spalletti be884f93fa Merge pull request #4486 from yakky/merge/4334
Merge #4485 in support 3.0.x
2015-09-23 14:53:30 +01:00
Iacopo Spalletti 19fc0e7d87 Merge pull request #4483 from yakky/merge/4458
Merge #4458
2015-09-23 08:14:42 +01:00
Angelo Dini de65142029 fixes issue #4334 2015-09-23 08:50:58 +02:00
Iacopo Spalletti ecaf740fe0 Catch any exception in 0010_migrate_use_structure 2015-09-23 08:26:15 +02:00
Iacopo Spalletti 6d2c9a5f93 Merge remote-tracking branch 'upstream/support/3.0.x' into merge/4458
Conflicts:
	cms/templates/cms/toolbar/plugin.html
2015-09-22 14:22:21 +02:00
Iacopo Spalletti 5c7f0bd0b8 Fix migration glitches 2015-09-21 16:39:01 +02:00
Iacopo Spalletti 3ba27f1196 Fix stupid blunders 2015-09-21 16:38:56 +02:00
Iacopo Spalletti ac20f11f71 Fix migration 2015-09-21 16:38:48 +02:00
Iacopo Spalletti f54050b492 Merge pull request #4467 from vxsx/bugfix/spaceless-support-3.0.x
bugfix spaceless  3.0.x
2015-09-21 15:19:29 +01:00
Vadim Sikora 025ea301e1 fix tests
Conflicts:
	cms/tests/toolbar.py
2015-09-21 10:01:18 +02:00
Vadim Sikora 80e3332a5c remove spaceless from user content
Conflicts:
	cms/templates/cms/toolbar/plugin.html
2015-09-21 09:59:57 +02:00
Martin Koistinen 5ab35027a7 Merge pull request #4457 from mkoistinen/mkoistinen/fix_fix_tree
Fix fix tree
2015-09-17 08:43:37 -04:00
Martin Koistinen 97841b9820 Remove unused code 2015-09-16 16:49:38 -04:00
Martin Koistinen a07432c3d7 Fixes #4456 2015-09-16 16:44:24 -04:00
Martin Koistinen d531308db7 Updated test 2015-09-16 16:33:08 -04:00
Martin Koistinen d259a3f2c9 PEP8/whitespace/linelength only 2015-09-16 16:06:20 -04:00
Martin Koistinen 0bec2e4dfb Test asserting the problem. 2015-09-16 16:06:06 -04:00
Iacopo Spalletti 9283515050 Merge pull request #4446 from yakky/feature/django19_compat2
Suppress django 1.9 warning
2015-09-12 19:20:53 +02:00
Iacopo Spalletti c431e76d4d Remove url from future 2015-09-12 15:42:51 +02:00
Venelin Stoykov a438614571 Fix RemovedInDjango19Warning: django.utils.importlib
Import `django.utils.importlib` only where it is needed (for Django 1.6 only). This will remove the warning:

    RemovedInDjango19Warning: django.utils.importlib will be removed in Django 1.9.
2015-09-12 15:42:51 +02:00
Iacopo Spalletti ad59e92a45 Remove request.REQUEST 2015-09-12 15:42:51 +02:00
Jared Proffitt 13c112c904 Fixing more RemovedInDjango19Warnings 2015-09-12 15:42:51 +02:00
Iacopo Spalletti aa76055ad4 Merge pull request #4445 from yakky/merge/migrations_detect
Forwardport migrations detect
2015-09-12 15:41:42 +02:00
Iacopo Spalletti f3e1d7815e Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD
Conflicts:
	cms/__init__.py
	cms/test_utils/cli.py
2015-09-12 14:36:31 +02:00
Iacopo Spalletti 11a3a08120 Merge pull request #4431 from yakky/feature/detect_migrations
detect plugin migrations layout in tests
2015-09-11 22:29:38 +02:00
Iacopo Spalletti b38bfd7315 detect plugin migrations layout in tests 2015-09-09 08:40:13 +02:00
Iacopo Spalletti 6fec11c8a7 Merge pull request #4415 from JayDeeDee/bugfix-4407
bugfix for issue #4407
2015-09-08 12:42:43 +02:00
Jana Deutschlaender f6210664c6 remove / add white spaces as requested, use .on instead of .bind, eliminate > 0 check 2015-09-07 13:15:52 +02:00
Jana Deutschlaender 7c8ab4b974 bugfix for branch support/3.1.x Issue #4407 (Using scroll bar of plugin menu in Firefox & IE moves plugins) 2015-09-03 16:40:22 +02:00
Iacopo Spalletti deb219fc05 Bump development version 2015-09-01 15:38:33 +02:00
Iacopo Spalletti 26d3af5ccc Bump version 2015-09-01 15:36:48 +02:00
Iacopo Spalletti de4a27144c Bump development version 2015-09-01 14:44:48 +02:00
Iacopo Spalletti 032e5e201e Bump version 2015-09-01 09:32:28 +02:00
Iacopo Spalletti 16320c0063 Merge pull request #4405 from yakky/changelog_313
Changelog 3.1.3
2015-08-31 13:12:51 +02:00
Iacopo Spalletti 2de88b7ebd Merge remote-tracking branch 'upstream/support/3.0.x' into changelog_313
Conflicts:
	docs/upgrade/index.rst
2015-08-31 09:26:00 +02:00
Iacopo Spalletti 1a015c834c Merge pull request #4403 from yakky/changelog_3015
Add 3.0.15 changelog
2015-08-31 09:25:16 +02:00
Iacopo Spalletti 1281fdd074 Add 3.0.15 changelog 2015-08-30 22:24:32 +02:00
Iacopo Spalletti 384dd26fff Add 3.1.3 changelog 2015-08-30 22:24:11 +02:00
Iacopo Spalletti f758a46292 Merge pull request #4399 from yakky/merge/4398
Merge #4398
2015-08-30 00:25:02 +02:00
Iacopo Spalletti 641b1f5b4d Forward port #4398 2015-08-29 18:22:42 +02:00
Iacopo Spalletti e4b728f952 Merge pull request #4398 from yakky/feature/cache_version
Cast to int cache version
2015-08-29 18:20:35 +02:00
Iacopo Spalletti ffeeaf8497 Cast to int cache version 2015-08-29 16:21:09 +02:00
Iacopo Spalletti 33db2e0e07 Merge pull request #4396 from yakky/merge/3.0.15-2
Merge support 3.0.x
2015-08-29 16:14:40 +02:00
Iacopo Spalletti c105dab42e Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD 2015-08-29 13:23:01 +02:00
Iacopo Spalletti fc65ab06e9 Merge pull request #4393 from yakky/fix/template_inheritance
Fix template inheritance
2015-08-29 13:19:33 +02:00
Iacopo Spalletti b962fee6eb Merge pull request #4395 from yakky/fix/4368
Fix language chooser template
2015-08-29 13:18:20 +02:00
Iacopo Spalletti 2f7864eab4 Fix language chooser template 2015-08-29 10:52:14 +02:00
Iacopo Spalletti e63911cd07 Add test for template inheritance 2015-08-29 10:20:08 +02:00
Iacopo Spalletti f1f2bf8d1e Fix xframe options inheritance 2015-08-29 10:07:41 +02:00
Iacopo Spalletti a97d0e6fc5 Add tests for xframe option inheritance 2015-08-29 10:07:12 +02:00
Iacopo Spalletti a9080bf4c6 Fix template inheritance order 2015-08-29 08:52:56 +02:00
Iacopo Spalletti ab24d1b4f4 Merge pull request #4386 from yakky/feature/fix_18_requests
Fix getting request in _show_placeholder_for_page on Django 1.8
2015-08-27 09:42:36 +02:00
Iacopo Spalletti a379f700b4 Fix getting request in _show_placeholder_for_page on Django 1.8 2015-08-27 08:36:03 +02:00
Jonas Obrist 51df78a7d0 Merge pull request #4363 from yakky/feature/fix_page_ancestors_order
Fix Page.get_cached_ancestors order
2015-08-18 15:21:50 +02:00
Iacopo Spalletti 42c19ccc14 Merge pull request #4366 from yakky/merge/4273
Merge #4273
2015-08-18 15:16:44 +02:00
Iacopo Spalletti 819923978e Merge pull request #4364 from yakky/feature/plugin_datamigrations_doc
Add documentation for plugins datamigration
2015-08-18 08:31:05 +02:00
Iacopo Spalletti 9337096004 Remove uselesss test 2015-08-17 18:25:06 +02:00
Iacopo Spalletti 0fd4ea3e4e Partially revert previous commit. Fix applied to the consumer of the method, to let the get_cached_ancestors behave like get_ancestors 2015-08-17 18:24:56 +02:00
Iacopo Spalletti d40d58f744 Add documentation for plugins datamigration 2015-08-16 08:14:30 +02:00
Iacopo Spalletti f0928cf71b Merge pull request #4362 from yakky/feature/update_test_requirements
Update test requirements
2015-08-15 14:36:30 +02:00
Iacopo Spalletti db80429033 Merge pull request #4361 from yakky/feature/fix_4038
Really fix #4038
2015-08-15 13:13:50 +02:00
Iacopo Spalletti 641c9984ad Update test requirements 2015-08-15 12:39:20 +02:00
Iacopo Spalletti 95c8b8cd11 Fix Page.get_cached_ancestors order: treebeard has the opposite default ordering of mptt 2015-08-15 12:30:08 +02:00
Iacopo Spalletti 1ad9f7f98c Really fix #4038 2015-08-15 11:28:23 +02:00
Martin Koistinen 5eed528c76 Merge pull request #4353 from divio/mkoistinen/issue_4352
Updates documentation section
2015-08-12 13:01:17 -04:00
Martin Koistinen 3cfd30b14a Double backticks 2015-08-12 12:29:09 -04:00
Martin Koistinen 22cb25f03d Remove dodgy line =) 2015-08-12 12:23:12 -04:00
Martin Koistinen 3a0684c87c Further corrections 2015-08-12 11:26:46 -04:00
Martin Koistinen 493dc087c0 Remove commas from lists 2015-08-12 11:22:49 -04:00
Martin Koistinen 1c6535c30b Updates documentation section 2015-08-12 11:20:00 -04:00
Iacopo Spalletti 07fbdc6385 Fix #4273 migration. Fix 1.6 migration 2015-08-10 22:23:35 +02:00
ikudryavtsev 6c6ec2787c fix get User model in 0010 migration 2015-08-10 22:23:28 +02:00
Iacopo Spalletti a95f0fc33e Merge pull request #4346 from yakky/merge/3.0.15
Merge back support 3.0
2015-08-10 19:12:01 +02:00
Iacopo Spalletti 92bb6c846a Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD
Conflicts:
	cms/admin/placeholderadmin.py
	cms/utils/page_resolver.py
	setup.py
	test_requirements/django-1.4.txt
	test_requirements/django-1.5.txt
2015-08-09 22:08:03 +02:00
Iacopo Spalletti 151e78b28b Merge pull request #4308 from yakky/merge/4301
Only attempt to delete cache keys if there are some to be deleted
2015-07-29 23:40:49 +02:00
Iacopo Spalletti 5c0e561ad8 Merge pull request #4325 from gigaroby/fix/migrationdependency
Fix issue preventing migrations to run on a new database (django 1.8)
2015-07-29 23:39:52 +02:00
Roberto Bampi 2299c6ba4d fix issue with migrations on a new database 2015-07-29 11:37:20 +02:00
Tom Wardill c0becc9749 Only attempt to delete cache keys if there are some to be deleted 2015-07-24 01:09:42 +02:00
Iacopo Spalletti 24656251cb Merge pull request #4299 from divio/mkoistinen/fix_4282
Don't try to modify an immutable QueryDict object.
2015-07-22 07:38:20 +02:00
Martin Koistinen b25a5f210d Consolidated some imports 2015-07-21 22:13:23 -04:00
Martin Koistinen b047429ce0 Don't try to modify an immutable QueryDict 2015-07-21 22:09:12 -04:00
Martin Koistinen 1ba08f0f39 Merge pull request #4284 from yakky/feature/fix_expired_ancestors
Fix reachability of pages with expired ancestors
2015-07-21 13:19:52 -04:00
Martin Koistinen 9461b8af65 Merge pull request #4283 from yakky/feature/fix_page_extension_copy
Fix extensions copy when using duplicate page/create page type
2015-07-21 13:18:33 -04:00
Iacopo Spalletti db4866b822 Merge pull request #4295 from josjevv/hotfix/cache-bytes-int-error
make sure version returned is an int
2015-07-21 08:23:10 +02:00
Iacopo Spalletti ee4a5ef3b5 Merge pull request #4296 from yakky/feature/setup_fix_4263
Declare Django 1.6.9 dependency in setup.py
2015-07-21 08:22:44 +02:00
Iacopo Spalletti 2591925556 django CMS 3.1 and up requires at least Django 1.6.9 due to the use of six.with_metaclass 2015-07-21 07:01:38 +02:00
Jos van Velzen e8166aa806 make sure version returned is an int 2015-07-20 22:46:29 +02:00
Iacopo Spalletti fee6304d76 Merge pull request #4288 from yakky/feature/fix_pagefield
Fix error in PageField for Django 1.8
2015-07-19 10:06:36 +02:00
Iacopo Spalletti 8397ac6e38 Merge pull request #4264 from yakky/feature/treebeard_fix
Page Treebeard fixes
2015-07-19 09:43:09 +02:00
Iacopo Spalletti 40607f6d09 Fix error in PageField for Django 1.8 2015-07-19 08:11:06 +02:00
Iacopo Spalletti 2f58a588a5 Merge pull request #4287 from yakky/feature/pin_text_plugin
Pin djangocms-text-ckeditor version for older djangos
2015-07-18 23:07:56 +02:00
Iacopo Spalletti 420a0b3d8d Ping djangocms-text-ckeditor version for older djangos 2015-07-18 18:46:44 +02:00
Iacopo Spalletti 415b9e9a65 Merge pull request #4286 from yakky/feature/setupy
Add Django versions to classifiers
2015-07-18 16:54:52 +02:00
Iacopo Spalletti 61b805e5fe Add Django versions to classifiers 2015-07-18 16:40:00 +02:00
Iacopo Spalletti b1a758b650 Fix reachability of pages with expired ancestors 2015-07-18 10:45:45 +02:00
Iacopo Spalletti 01f0698861 Fix extensions copy when using duplicate page/create page type 2015-07-17 23:52:20 +02:00
Iacopo Spalletti b98b1d8317 Merge pull request #4279 from yakky/merge/3.0.x
Merge 3.0.x branch
2015-07-17 11:27:05 +02:00
Iacopo Spalletti f2c046306a Add migrations 2015-07-17 08:17:44 +02:00
Iacopo Spalletti d9ea5f6a74 Merge remote-tracking branch 'upstream/support/3.0.x' into merge/3.0.x
Conflicts:
	cms/__init__.py
	cms/menu.py
	cms/models/pagemodel.py
	cms/static/cms/js/modules/cms.modal.js
	cms/tests/frontend.py
	cms/tests/multilingual.py
	setup.py
2015-07-16 20:03:08 +02:00
Iacopo Spalletti 1cb8f0d5a1 Merge pull request #4277 from yakky/feature/remove_page
Remove page from menu items for performance reason.
2015-07-16 19:43:16 +02:00
Iacopo Spalletti 977111b064 Remove page from menu items for performance reason. Fix #4276 2015-07-16 10:25:44 +02:00
Iacopo Spalletti c0ad45f3f4 Merge pull request #4261 from yakky/feature/fix_4214
[WiP] Fix support for unpublished language pages
2015-07-15 00:23:38 +02:00
Iacopo Spalletti 0bf0fbd043 Merge pull request #4255 from yakky/feature/19_deprecations
Remove deprecations
2015-07-14 23:17:22 +02:00
Iacopo Spalletti a06f6f937a Do not use MP_NodeQuerysSet Titles 2015-07-13 23:40:02 +02:00
Iacopo Spalletti dfe70328bc Add test for #4102 2015-07-13 23:24:25 +02:00
Iacopo Spalletti 164b6c2d9c Fix queryset 2015-07-13 22:59:30 +02:00
Iacopo Spalletti 9e10378c99 Remove unpublished pages from menu 2015-07-13 08:36:34 +02:00
Iacopo Spalletti 5313d52a52 Fix support for unpublished language pages 2015-07-12 23:37:34 +02:00
Iacopo Spalletti b86a461c57 Merge pull request #4257 from yakky/feature/merge_4248
Merge 4248
2015-07-12 22:18:28 +02:00
Iacopo Spalletti c5b11d6f50 Merge pull request #4258 from yakky/feature/remove_scssc
Exclude scssc from manifest
2015-07-12 22:17:59 +02:00
Iacopo Spalletti d045d66f3a Exclude scssc from manifest 2015-07-12 10:13:39 +02:00
Iacopo Spalletti 27045ad2ab Merge branch 'feature/merge_4190' into HEAD 2015-07-12 09:28:51 +02:00
Basile LEGAL a66fe0de69 Corrects Iframe doesn't hide 2015-07-12 09:24:57 +02:00
Basile LEGAL 3ac57c8588 Corrects South migration error 2015-07-12 09:24:56 +02:00
Basile LEGAL cbcd9bdba7 corrects syntax + adds migrations 2015-07-12 09:24:56 +02:00
Basile LEGAL 5f0a43688d Fix #4029 - first point of the issue + test 2015-07-12 09:24:31 +02:00
Iacopo Spalletti b7866d7b0c Merge branch 'feature/merge_4229' into HEAD 2015-07-12 09:03:02 +02:00
Iacopo Spalletti 43caae661b Code cleanup 2015-07-12 09:02:02 +02:00
Iacopo Spalletti e4c1837540 Fix redirect when deleting a page 2015-07-12 09:02:02 +02:00
Hans Andersen 2251a9553b Removed unnecessary escape 2015-07-12 08:59:46 +02:00
Hans Andersen f6a3e260c1 Added parentheses for multi-line condition 2015-07-12 08:59:46 +02:00
Hans Andersen 746e24afdb Fixed check for template instance in Django 1.8.x 2015-07-12 08:59:46 +02:00
Iacopo Spalletti 1ed5688d99 Merge pull request #4256 from yakky/feature/relax_html5lib
Relax html5lib versions
2015-07-12 08:57:37 +02:00
Iacopo Spalletti b868f2beeb Relax html5lib versions 2015-07-12 00:34:53 +02:00
Iacopo Spalletti d55d649f15 Tentative fix for #4102 2015-07-12 00:15:44 +02:00
Iacopo Spalletti bacd85ddec Remove some Django 1.9 deprecations 2015-07-11 23:18:19 +02:00
Iacopo Spalletti fb8caabb9a Merge pull request #4232 from yakky/feature/1.8_migration
Fix PageUser migration in Django 1.8
2015-07-04 14:45:39 +02:00
Iacopo Spalletti 2c5aa37e08 Exclude PageUser manager from migrations 2015-07-04 10:16:15 +02:00
Iacopo Spalletti 8814936910 Merge pull request #4233 from yakky/feature/fix_coveralls
Fix coveralls
2015-07-03 20:55:34 +02:00
Iacopo Spalletti d98baa8728 Fix coveralls 2015-07-03 12:07:46 +02:00
Iacopo Spalletti 0fb44504fa Add missing migration 2015-07-03 09:30:45 +02:00
Iacopo Spalletti 4fc4a53bc4 Bump version 2015-07-03 09:04:03 +02:00
Iacopo Spalletti 6260e46b97 Update changelog 2015-07-03 09:04:03 +02:00
Iacopo Spalletti 86b0fa2497 Update translations 2015-07-02 21:11:53 +02:00
Iacopo Spalletti cc09ab7093 Merge pull request #4227 from yakky/fix/docs
Fix supported django version
2015-07-01 23:03:23 +02:00
Iacopo Spalletti 144c5ccd02 Fix supported django version 2015-07-01 20:13:09 +02:00
Iacopo Spalletti 0f820a6371 Merge pull request #4224 from yakky/fix/311-regressions
Fix 3.1.1 regressions
2015-07-01 16:42:01 +02:00
Iacopo Spalletti 11eb1d50c0 Correctly clear placeholder cache. Fix #4223 2015-07-01 06:10:00 +02:00
Iacopo Spalletti 17aa538084 Add test for placeholder cache regression (#4223) 2015-07-01 06:10:00 +02:00
Iacopo Spalletti bee5d2e7b5 Move back get_site_choices, get_page_choices, update_site_and_page_choices to cms.forms 2015-07-01 05:11:24 +02:00
Iacopo Spalletti 7faad47330 Fix readme formatting 2015-06-28 11:34:39 +02:00
Iacopo Spalletti dae85be57a Bump development version 2015-06-27 23:52:58 +02:00
Iacopo Spalletti f81b6b8fd1 Bump development version 2015-06-27 23:52:11 +02:00
Iacopo Spalletti 8d8b5acc57 Bump version 2015-06-27 23:28:53 +02:00
Iacopo Spalletti 1c9c1976de Merge branch 'release/3.1.1' into HEAD 2015-06-27 23:02:54 +02:00
Iacopo Spalletti ec8dbdb5e2 Update authors file 2015-06-27 22:58:22 +02:00
Iacopo Spalletti 57773ecf31 Fix test 2015-06-27 22:58:22 +02:00
Iacopo Spalletti a9e5c8cb4b Remove debug 2015-06-27 22:23:37 +02:00
Iacopo Spalletti d5696e455c Merge branch 'changelog_311' into HEAD 2015-06-27 22:19:41 +02:00
Iacopo Spalletti 120bcc8b38 Merge branch 'release/3.0.14' into HEAD
Conflicts:
	CHANGELOG.txt
	cms/admin/pageadmin.py
	cms/locale/zh_CN.GB2312/LC_MESSAGES/django.mo
	cms/locale/zh_CN.GB2312/LC_MESSAGES/django.po
	cms/locale/zh_CN.GB2312/LC_MESSAGES/djangojs.mo
	cms/locale/zh_CN.GB2312/LC_MESSAGES/djangojs.po
	docs/upgrade/index.rst
2015-06-27 22:15:05 +02:00
Iacopo Spalletti c3056443f3 Merge pull request #4216 from yakky/feature/refactor_cache
Fix cache invalidation
2015-06-27 21:18:06 +02:00
Iacopo Spalletti 22ca030dbc Remove prints 2015-06-27 17:02:48 +02:00
Iacopo Spalletti 9dfa4935c8 Update changelog 2015-06-27 16:43:11 +02:00
Iacopo Spalletti 68cddda069 Add test 2015-06-27 16:24:02 +02:00
Iacopo Spalletti bcc4f24d43 Refactor cache infrastructure 2015-06-27 15:58:29 +02:00
Iacopo Spalletti 2205f5ce7f Merge pull request #4205 from vxsx/feature/editorconfig
Editorconfig
2015-06-23 23:39:56 +02:00
Vadim Sikora 245d326794 add editorconfig 2015-06-23 10:19:53 +02:00
Vadim Sikora d39d7a97a6 do not ignore editorconfig 2015-06-23 10:16:49 +02:00
Iacopo Spalletti 9fcf104e0c Merge pull request #4200 from vxsx/bugfix/submenu-shift-tab
make shift tab work correctly in submenu
2015-06-17 11:46:17 +02:00
Vadim Sikora 0bfd80683e make shift tab work correctly in submenu 2015-06-17 09:19:02 +02:00
Iacopo Spalletti 4418d0427f Merge pull request #4198 from yakky/fix/get_language_from_request
Fix get_language_from_request if POST and GET exists
2015-06-16 09:13:23 +02:00
Iacopo Spalletti ff409a1d37 Merge pull request #4199 from yakky/fix/console_log
Remove console.log
2015-06-16 08:46:05 +02:00
Iacopo Spalletti 24970104fa Remove console.log 2015-06-16 08:31:08 +02:00
Iacopo Spalletti fa855f0871 Fix get_language_from_request if POST and GET exists 2015-06-16 07:55:15 +02:00
Iacopo Spalletti f4e897e5dc Merge pull request #4196 from vxsx/hotfix/frontend-contributing
Bump version of djangoCMS in contributing docs
2015-06-15 18:35:58 +02:00
Vadim Sikora c0f8b5c689 Bump version of djangoCMS in contributing docs
since we did not update frontend code to use spaces yet
2015-06-15 17:51:46 +02:00
Iacopo Spalletti 47f9cd3eb9 Updates 2015-06-13 12:10:22 +02:00
Iacopo Spalletti f8d4753010 Merge pull request #4192 from yakky/merge/4056
Merge/4056
2015-06-13 12:04:01 +02:00
Iacopo Spalletti 86627ee1a6 Merge pull request #4191 from yakky/feature/cleanup_migrations
Remove leftovers migration directory
2015-06-13 12:03:50 +02:00
Iacopo Spalletti 40018ce71b Fix order import 2015-06-12 19:49:46 +02:00
Paolo Leggio 23e49331fe codestyle clean-up 2015-06-12 19:44:07 +02:00
Paolo Leggio 73365dd578 hides the toolbar for pages out of django-cms 2015-06-12 19:43:54 +02:00
Iacopo Spalletti 9b35daf6cd Merge pull request #4065 from astagi/feature/openclosecascade
Open and close collapsible trees using alt key
2015-06-12 19:36:53 +02:00
Iacopo Spalletti d62e525a3c Merge pull request #4165 from yakky/feature/test_improving
[WIP] Add tests
2015-06-12 19:36:39 +02:00
Iacopo Spalletti d1aacad4b7 Remove leftovers migration directory 2015-06-12 19:08:10 +02:00
Andrea Stagi 65ddcc3c17 Use SHIFT key to open and close collapsible trees 2015-06-11 16:52:57 +02:00
Iacopo Spalletti 769a86c0c7 Merge pull request #4188 from donce/patch-1
updated menu.py
2015-06-11 15:11:09 +02:00
Donatas Kučinskas aa8f429fd6 Update menu.py 2015-06-11 15:32:37 +03:00
Iacopo Spalletti 29e98f6d59 update changelog for 3.1.1 2015-06-11 06:22:39 +02:00
Iacopo Spalletti cd9ea163ce Merge pull request #4174 from yakky/remerge_3014
Merge back support/3.0.x
2015-06-10 18:00:35 +02:00
Iacopo Spalletti f6325850ad Merge pull request #4183 from FinalAngel/develop
Fix icon positioning on sideframe
2015-06-10 10:19:29 +02:00
Angelo Dini 8add9b4f9f fix icon positioning 2015-06-10 09:57:37 +02:00
Iacopo Spalletti e909c0bf23 Merge remote-tracking branch 'upstream/support/3.0.x' into remerge_3014
Conflicts:
	cms/tests/menu.py
2015-06-10 08:10:37 +02:00
Iacopo Spalletti 6143101396 Merge pull request #4182 from yakky/feature/update_copyright
Update year.
2015-06-10 08:02:33 +02:00
Sam Manzi befae376a3 Update year. 2015-06-10 01:24:04 +02:00
Iacopo Spalletti a5f39fe22c Merge pull request #4180 from driesdesmet/patch-2
missing import in code example, documentation
2015-06-10 01:08:05 +02:00
Iacopo Spalletti 4ca3cefd10 Merge pull request #4177 from driesdesmet/patch-1
small typo fix
2015-06-10 01:07:49 +02:00
Iacopo Spalletti ff99deef3c Merge pull request #4181 from jmelett/develop
Cleanup README.rst
2015-06-10 01:07:32 +02:00
Iacopo Spalletti 95471a450b Merge pull request #4178 from FinalAngel/develop
Structure board fixes
2015-06-10 01:07:10 +02:00
Joseph Melettukunnel 7beaac0b1c Cleanup README.rst 2015-06-09 21:19:53 +02:00
Dries Desmet 604c5c1c32 [missing import in code example, documentation 2015-06-09 21:02:47 +02:00
Angelo Dini 715e221152 fix scrolling bound issue 2015-06-09 18:49:42 +02:00
Angelo Dini 0a58c6b069 fix overlapping expanded elements 2015-06-09 18:49:36 +02:00
Dries Desmet 40f4476275 small typo fix 2015-06-09 18:09:30 +02:00
Tom Berger c0b338d8b0 Break the line. 2015-06-09 14:34:29 +02:00
Lionardo Mendonça 05d1150a09 Merge pull request #4172 from divio/feature/update-readme
add a commercial support section to readme
2015-06-09 14:15:02 +02:00
Lio Mendonca 612c825f19 correct link 2015-06-09 14:11:25 +02:00
Iacopo Spalletti 4ad7c32e2a Merge remote-tracking branch 'upstream/support/3.0.x' into c
Conflicts:
	CHANGELOG.txt
	cms/admin/change_list.py
	cms/cms_toolbar.py
	cms/menu.py
	cms/templatetags/cms_tags.py
	cms/test_utils/project/sampleapp/menu.py
	cms/test_utils/project/sampleapp/urls.py
	cms/test_utils/project/sampleapp/views.py
	cms/tests/apphooks.py
	cms/tests/menu.py
	cms/tests/multilingual.py
	cms/tests/placeholder.py
	cms/tests/toolbar.py
	cms/utils/plugins.py
	menus/menu_pool.py
	menus/templatetags/menu_tags.py
	setup.py
	test_requirements/django-1.4.txt
	test_requirements/django-1.5.txt
	test_requirements/requirements_base.txt
2015-06-08 21:13:58 +02:00
Iacopo Spalletti 65281b414c Merge pull request #4167 from yakky/feature/fix_position
Fix setting position attribute when copying plugins
2015-06-08 19:31:19 +02:00
Iacopo Spalletti 9b161e82e7 Merge pull request #4085 from yakky/feature/django_18
Django 1.8 support
2015-06-08 19:30:30 +02:00
Iacopo Spalletti ae5ae68552 Merge remote-tracking branch 'upstream/develop' into feature/django_18_reb
Conflicts:
	cms/tests/page.py
2015-06-08 14:19:25 +02:00
Lio Mendonca a82dbc62b9 add a commercial support section to readme 2015-06-08 13:52:24 +02:00
Iacopo Spalletti 7a6761bfbd Fix Django 1.6 migration 2015-06-08 00:25:39 +02:00
Iacopo Spalletti ad70c54f2c Format migration for Django 1.7 2015-06-07 23:40:31 +02:00
Iacopo Spalletti 20e48199a8 Fix failure in Django 1.7/1.6 2015-06-07 23:20:09 +02:00
Iacopo Spalletti c7b8727a84 Test fixes for new TEMPLATES settings 2015-06-07 23:01:59 +02:00
Iacopo Spalletti 71dcf4252f Comply with Django checks warning 2015-06-07 23:00:07 +02:00
Iacopo Spalletti d08f2fc9f5 Merge pull request #11 from vad/feature/django_18
Django < 1.9 in setup.py
2015-06-07 18:53:15 +02:00
Iacopo Spalletti b6646a5ad5 Merge pull request #4125 from divio/issues/toolbar_save_as_draft
Use "Save as draft"
2015-06-07 18:52:16 +02:00
Iacopo Spalletti dbf42eff1c Merge pull request #4162 from yakky/feature/fix_plugin_breadcrumbs
Fix #4141 - plugin breadcumbs order
2015-06-07 18:13:09 +02:00
Iacopo Spalletti af5cbde4ff Merge pull request #4163 from yakky/feature/cast_watch_models
Fix #4135 - Cast watch_models to list
2015-06-07 18:12:56 +02:00
Iacopo Spalletti 13ebbd0377 Merge pull request #4166 from yakky/feature/fix_toolbar_items
Fix toolbar multiple populate
2015-06-07 18:12:19 +02:00
Iacopo Spalletti bf7a45e807 Fix toolbar multiple populate 2015-06-07 14:08:40 +02:00
Iacopo Spalletti 49dc8791bc Fix setting position attribute when copying plugins 2015-06-07 13:50:05 +02:00
Iacopo Spalletti e02cd73519 Fix #4135 - Cast watch_models to list 2015-06-07 10:46:34 +02:00
Iacopo Spalletti acf78456ca Fix #4141 - plugin breadcumbs order 2015-06-07 10:36:44 +02:00
Iacopo Spalletti 761260ab17 Merge pull request #4157 from nikolas/patch-2
Fix typos in install instructions
2015-06-05 23:26:54 +02:00
nikolas 1b4b74240a Fix typos in install instructions 2015-06-05 14:15:02 -04:00
Iacopo Spalletti bed6474037 Merge pull request #4149 from yakky/tutorial_fix_2
Fix minor missing pieces in the tutorial
2015-06-05 16:07:08 +02:00
Iacopo Spalletti dc80fb25df Merge pull request #4148 from FinalAngel/develop
Docs: adds missing import
2015-06-04 15:09:31 +02:00
Iacopo Spalletti 753ede9406 Fix minor missing pieces in the tutorial 2015-06-04 15:08:01 +02:00
Angelo Dini 58ac9a7628 add missing import 2015-06-04 11:26:30 +01:00
Iacopo Spalletti cde84d2b60 Merge pull request #4146 from yakky/tutorial_tests
Tutorial tests
2015-06-04 10:20:48 +02:00
Iacopo Spalletti 5e414985c6 Add information on how to submit the proposed code 2015-06-04 10:20:31 +02:00
Iacopo Spalletti 5dbbd15ae1 First draft of the tests tutorial 2015-06-04 10:20:31 +02:00
Iacopo Spalletti 20dd9f6182 Merge pull request #4145 from stefanfoulis/feature/namespaced-apphooks-tutorial
tutorial about namespaced apphooks
2015-06-04 10:19:43 +02:00
Stefan Foulis 7c8bda91db add tutorial about namespaced apphooks 2015-06-04 08:12:39 +01:00
Iacopo Spalletti 5c52e5e8eb Merge pull request #4139 from stefanw/disable-toolbar-setting
Add setting to disable toolbar for anonymous users
2015-06-02 09:08:22 +02:00
Stefan Wehrmeyer 9aa11aebbf Add setting to disable toolbar for anonymous users
This adds the setting CMS_TOOLBAR_ANONYMOUS_ON defaulting to True which
maintains the current behaviour. If set to False, anonymous users (like
non-staff logged in users) will not see the CMS toolbar when ?edit is
appended to a URL. Fixes #4134.
2015-06-02 00:50:28 +02:00
Iacopo Spalletti f6277b127c Merge pull request #4136 from yakky/tutorial_fix
Minor tutorial fixes
2015-06-01 19:39:12 +02:00
Iacopo Spalletti 9de54969af Minor tutorial fixes 2015-05-31 15:53:11 +02:00
Iacopo Spalletti a0816fc4cf Merge pull request #4132 from stefanfoulis/feature/tutorial-django-1.7-compat
update tutorial for Django 1.7 (and django CMS 3.1)
2015-05-31 10:52:12 +02:00
Stefan Foulis 3c7c44fa7b convert tutorial to Django 1.7 and aldryn-newsblog 2015-05-31 00:39:12 +01:00
Davide Setti 9a0bc9610a - fixed test settings in django 1.8
- fixed misleading error message in settings validation in django 1.8
2015-05-29 21:18:31 +02:00
Davide Setti dec8596d4f added support for Django 1.8 settings.TEMPLATES in settings validation 2015-05-28 18:15:34 +02:00
Davide Setti f3c070059f Django < 1.9 in setup.py 2015-05-28 17:56:04 +02:00
Martin Koistinen c0f4a63c04 Use "Save as draft" 2015-05-26 16:13:15 +03:00
Iacopo Spalletti 5af564879b Merge pull request #4110 from yakky/feature/fix_languages
Fix languages
2015-05-14 00:11:03 +02:00
Iacopo Spalletti 9cc59028f9 Add tests for #4031 and to check language in toolbar links 2015-05-13 21:18:01 +02:00
Iacopo Spalletti 64d362c881 Fix language redirection 2015-05-13 21:17:24 +02:00
Iacopo Spalletti f5b2203582 Merge pull request #4031 from stefanw/activate-reverse-language
Always force language when reversing page model URLs
2015-05-13 21:16:56 +02:00
Iacopo Spalletti 2c73268add Fix develop.py on Django 1.8 2015-05-09 23:25:21 +02:00
Iacopo Spalletti 0e183e66ab Merge pull request #4097 from maqnouch/patch-1
Fix typos
2015-05-07 09:16:06 +02:00
AQNOUCH Mohammed 57de3b4612 Fix typos 2015-05-07 01:39:14 +01:00
Iacopo Spalletti 3da4284956 Merge pull request #4086 from yakky/feature/copy_site
Add copy site command
2015-05-06 23:22:59 +02:00
Iacopo Spalletti 82c57fffda Merge pull request #4096 from doctormo/develop
Allow the migrate_use_structure migration to work with django 1.7
2015-05-06 23:09:08 +02:00
Iacopo Spalletti 9a2d9cda7e Merge pull request #4054 from astagi/feature/dragbaropenclose
Restore previous status of dragbars
2015-05-06 13:10:18 +02:00
Iacopo Spalletti 6be397b10f Merge pull request #4090 from timgraham/fix-flash
Revert whitespace cleanup on flash player to fix it.
2015-05-05 22:18:59 +02:00
Martin Owens aea4b348a4 Allow the migrate_use_structure migration to work with django 1.7 ContentTypes 2015-05-05 15:49:21 -04:00
Iacopo Spalletti 5addc5acca Fix ecluded builds from matrix 2015-05-05 21:44:37 +02:00
Iacopo Spalletti 6b2baa3ec1 Use migrations during migrations commands 2015-05-05 21:44:37 +02:00
Iacopo Spalletti f3344e281d Initial migrations for testing applications 2015-05-05 21:44:37 +02:00
Iacopo Spalletti fb17ad2475 mysqlclient connector 2015-05-05 21:44:37 +02:00
Iacopo Spalletti 1ce8fd6269 Fix support for customuserapp.User 2015-05-05 21:44:37 +02:00
Iacopo Spalletti 6cdf89e476 Fix RenderingTestCase 2015-05-05 21:44:37 +02:00
Iacopo Spalletti cdb1482e53 Set last_login 2015-05-05 21:44:36 +02:00
Iacopo Spalletti dbb65ca38b Test xvfb support 2015-05-05 21:44:36 +02:00
Iacopo Spalletti 95782b39ff Fix deprecations 2015-05-05 21:44:36 +02:00
Iacopo Spalletti 99a9a5b3da Add support for not using migrations during tests/server on Django 1.7+ 2015-05-05 21:44:36 +02:00
Iacopo Spalletti c126f29b2e Fix menu templatetags 2015-05-05 21:44:36 +02:00
Iacopo Spalletti bddd0baf6d Disable selenium tests 2015-05-05 21:44:36 +02:00
Iacopo Spalletti 6201552f28 Use latest stable Django 1.8 2015-05-05 21:44:36 +02:00
Iacopo Spalletti def0814961 More context fixes 2015-05-05 21:44:35 +02:00
Iacopo Spalletti 88a2ff7d23 No python 3 for mysql 2015-05-05 21:44:35 +02:00
Iacopo Spalletti 935da20766 Fix NoI18nTest 2015-05-05 21:44:35 +02:00
Iacopo Spalletti 286920a27c More context fixes 2015-05-05 21:44:35 +02:00
Iacopo Spalletti 6b7636900b Fix hidden backward incompatibilities 2015-05-05 21:44:35 +02:00
Iacopo Spalletti ce530eb72b Fix context issues 2015-05-05 21:44:35 +02:00
Iacopo Spalletti 3b7215ca01 Cleanups 2015-05-05 21:44:35 +02:00
Iacopo Spalletti 33016beee9 Fix check tests 2015-05-05 21:44:35 +02:00
Iacopo Spalletti 5cf7aa2a93 More fixed tests 2015-05-05 21:44:35 +02:00
Iacopo Spalletti a266be0c84 Fix obsolete test 2015-05-05 21:44:34 +02:00
Iacopo Spalletti 77efda00ba Minor cleanup 2015-05-05 21:44:34 +02:00
Iacopo Spalletti 8005ead5db Fix jsonify_request 2015-05-05 21:44:34 +02:00
Iacopo Spalletti d9a184051d Use get_permission_codename to get permission codes 2015-05-05 21:44:34 +02:00
Iacopo Spalletti 32041dd26d Fix test 2015-05-05 21:44:34 +02:00
Iacopo Spalletti 8b5ee08ee1 Minor fixes 2015-05-05 21:44:34 +02:00
Iacopo Spalletti ee585da1eb render ... render everywhere ...
Conflicts:
	cms/test_utils/project/placeholderapp/views.py
2015-05-05 21:44:34 +02:00
Iacopo Spalletti ab38e40e41 Add Django 1.8 to the matrix 2015-05-05 21:44:34 +02:00
Iacopo Spalletti 06c0c2c6b0 Update requirements 2015-05-05 21:44:33 +02:00
Iacopo Spalletti bdd9315546 Restore 1.6 compatibility 2015-05-05 21:44:07 +02:00
Mattia Larentis 18982da2e4 fixed test_show_placeholder_for_page_placeholder_does_not_exist 2015-05-05 21:44:07 +02:00
Mattia Larentis aff8cded2c fixed EditModelTemplateTagTest.test_add_tag: just another context issue
Conflicts:
	cms/test_utils/project/placeholderapp/views.py
2015-05-05 21:44:07 +02:00
Mattia Larentis ce5455f337 fixed test_empty_placeholder_in_correct_language and test_remove_plugin_requires_post 2015-05-05 21:44:07 +02:00
Mattia Larentis de9c6b2f78 fixed test_delete_translation: in django1.8, get_deleted_objects returns a different set of data 2015-05-05 21:44:06 +02:00
Mattia Larentis f368fe48e6 fixed test_editpage_contentsize: HttpResponse.charset is public in Django 1.8 2015-05-05 21:44:06 +02:00
Davide Setti 2435771ba5 fixed a bug with Django 1.8: TemplatesConfig.test_custom_templates_loading is accessing Template.name, which is a private attribute 2015-05-05 21:44:06 +02:00
Luis Diego Garcia f291ffa84d Fix #4023: Update language middleware for Django 1.8. 2015-05-05 21:44:06 +02:00
Iacopo Spalletti 83ecb2ffcc Initial compatibility effort 2015-05-05 21:44:06 +02:00
Iacopo Spalletti beff81da41 Rewrite migration dependencies 2015-05-05 21:44:06 +02:00
Iacopo Spalletti 84319aa7e1 Add *proper* docs 2015-05-05 21:43:23 +02:00
Iacopo Spalletti 253a293b72 More robust version of the test 2015-05-05 21:43:23 +02:00
Iacopo Spalletti c8b6319d5f Add tests for copy-site 2015-05-05 21:43:23 +02:00
Iacopo Spalletti 587037fee9 Add docs 2015-05-05 21:43:23 +02:00
Iacopo Spalletti 7157f9d082 Use arguments not options 2015-05-05 21:43:23 +02:00
Peter J. Farrell 54fcc484bc Create copy_site.py 2015-05-05 21:43:23 +02:00
Peter J. Farrell 087101ef69 Update cms.py 2015-05-05 21:43:23 +02:00
Iacopo Spalletti 8ddfe80697 Merge pull request #4094 from astagi/feature/shieldsio
Use shields.io badges
2015-05-05 14:57:31 +02:00
Andrea Stagi 7473c15265 Use shields.io badges 2015-05-05 08:30:04 +02:00
Iacopo Spalletti c00be11990 Merge pull request #4087 from yakky/htmllib
Pin html5lib version
2015-05-04 23:13:45 +02:00
Tim Graham 9a8a9ed46e Revert whitespace cleanup on flash player to fix it. 2015-05-04 10:07:02 -04:00
Iacopo Spalletti 350ca83642 Merge pull request #4088 from timgraham/perm-test
Add test for anonymous permissions bug (#4082).
2015-05-04 09:35:50 +02:00
Tim Graham 8a7ccafd33 Add test for anonymous permissions bug (#4082). 2015-05-03 20:20:04 -04:00
Iacopo Spalletti cd73105f53 Merge pull request #4075 from northben/patch-1
Update custom_plugins.rst
2015-05-03 23:15:47 +02:00
Ben Northway 092bb5b407 Update custom_plugins.rst
Add reminder for INSTALLED_APPS, clarify where to place example code. For newbies like me. :)
2015-05-03 23:14:26 +02:00
Iacopo Spalletti 9f727e29d9 Merge pull request #4076 from timgraham/view-restrictions
Fixed public page not appearing in menus.
2015-05-03 22:50:45 +02:00
Iacopo Spalletti bf21d65c15 Pin html5lib version 2015-05-03 22:42:40 +02:00
Iacopo Spalletti 02c2ab4623 Merge pull request #4073 from dirtycoder/develop
Add xvfb option to develop.py docs, fix issue #3790
2015-05-01 10:48:09 +02:00
Martin Koistinen 8314a7d2a2 Added notification webhook 2015-04-30 02:30:15 +03:00
Martin Koistinen 7fd87659e2 Add code climate badge 2015-04-29 18:10:23 +03:00
Tim Graham 0b22ced669 Fixed public page not appearing in menus. 2015-04-28 21:08:41 -04:00
João Luiz Lorencetti 2b767aaebf Add xvfb option to develop.py docs, fix issue #3790 2015-04-25 15:31:05 -03:00
Daniele Procida fcbf173cff Merge pull request #4067 from piquadrat/feature/release-notes-3.1-fixes
fixed some typos, fixed link to treebeard docs, added links to apphooks-config and blueprint
2015-04-21 14:43:03 +01:00
Benjamin Wohlwend b8a3578ce0 fixed some typos, fixed link to treebeard docs, added links to apphooks-config and blueprint
Google will close down googlecode soon, hence the update to the treebeard docs. This
it the URL that the github repository refers to as well.
2015-04-21 15:36:48 +02:00
Andrea Stagi 03b520cd7f Open and close collapsible trees using alt key 2015-04-20 19:36:09 +02:00
Iacopo Spalletti 880f1255f8 Bump development version 2015-04-20 14:18:21 +02:00
Iacopo Spalletti 9dccaa4e66 Bump version 2015-04-20 14:16:52 +02:00
Iacopo Spalletti ee2ed40158 Merge remote-tracking branch 'upstream/develop' into release/3.1 2015-04-20 14:16:33 +02:00
Iacopo Spalletti 82709f3aa7 Merge pull request #4062 from yakky/feature/release_notes
Update release notes
2015-04-20 13:02:53 +02:00
Iacopo Spalletti c032114859 Update release notes 2015-04-20 11:59:50 +02:00
Iacopo Spalletti d90276193e Merge pull request #4061 from evildmp/contributiondocs
Adds more detail in contribution docs
2015-04-20 11:38:38 +02:00
evildmp 18746f198d Adds more detail in contribution docs 2015-04-20 09:06:41 +01:00
Iacopo Spalletti 2a86a21084 Merge remote-tracking branch 'upstream/develop' into HEAD 2015-04-20 01:53:39 +02:00
Iacopo Spalletti bfd5c416b4 Merge pull request #4059 from yakky/feature/update_readme
Update README
2015-04-20 01:51:45 +02:00
Iacopo Spalletti 361e7e086a Update README 2015-04-20 01:35:08 +02:00
Iacopo Spalletti c43910f686 Merge pull request #4053 from vad/fix/long-usernames-with-custom-user-model
Added support for long usernames with custom usermodels. Fixes #3938
2015-04-19 19:03:29 +02:00
Davide Setti d9a5238571 EmailUser.email has max_length=300 now, to fix #3938 2015-04-19 17:48:35 +02:00
Daniele Procida e1319ed1c4 Merge pull request #4057 from evildmp/mrosati84-develop
Merge #4055, closes #4046, thanks Matteo Rosati
2015-04-19 15:27:03 +01:00
evildmp 40f5b1b7b5 Minor changes to Save/Publish docs 2015-04-19 15:14:38 +01:00
Andrea Stagi ca9872284d Restore previous status of dragbars 2015-04-19 15:38:21 +02:00
Iacopo Spalletti 3e25fa5352 Fix migration path 2015-04-19 15:23:52 +02:00
Davide Setti 739e1a411c Added support for long usernames with custom usermodels. Fixes #3938 2015-04-19 15:23:11 +02:00
Iacopo Spalletti e251624c0b Merge pull request #4052 from yakky/feature/fix_migration_path
Fix migration path
2015-04-19 15:21:02 +02:00
Matteo Rosati 0e37211a5d fix issue #4046, update toolbar documentation 2015-04-19 15:15:50 +02:00
Iacopo Spalletti 9898b8b5ba Merge pull request #4049 from mrosati84/develop
fix issue #3426, menu visibility constants refactoring
2015-04-19 14:21:51 +02:00
Iacopo Spalletti 7d85e571fc Merge pull request #4051 from fmarco/feature/issue-4047
Change unsaved plugins to empty plugins in help and strings inside delet...
2015-04-19 14:21:18 +02:00
Iacopo Spalletti 66eb23a0f0 Fix migration path 2015-04-19 13:16:17 +02:00
marco federighi 48d1833ba7 Change unsaved plugins to empty plugins in help and strings inside delete_orphaned_plugins 2015-04-19 12:26:38 +02:00
Matteo Rosati 2f86b1ac39 fix issue #3426, menu visibility constants refactoring 2015-04-19 11:41:13 +02:00
Iacopo Spalletti 2f0b297433 Fix formatting issues in permissions.rst 2015-04-18 13:50:34 +02:00
Iacopo Spalletti d6b864f086 Merge pull request #4044 from mikko-ahlroth-vincit/patch-1
Fixed list numbering in permissions.rst
2015-04-18 13:49:03 +02:00
Iacopo Spalletti c6be1dbee6 Merge pull request #4043 from datafyit/develop
Update outdated custom_plugins.rst
2015-04-17 18:28:54 +02:00
Žan Anderle 4bd1012cb8 Update custom_plugins.rst
Fix the wrong template path
2015-04-17 16:30:37 +02:00
Mikko Ahlroth d0521ba109 Fixed list numbering in permissions.rst
List was previously shown with all elements concatenated into a paragraph.
2015-04-17 15:48:34 +03:00
Iacopo Spalletti e106371bcb Merge pull request #4040 from yakky/feature/migration
Fix transaction handling in migration
2015-04-17 12:08:51 +02:00
Žan Anderle cd91d957bd Update custom_plugins.rst
Plugin admin form sits in ``admin/cms/page/change_form.html`` and not in ``admin/cms/page/plugin_change_form.html`
2015-04-17 10:37:26 +02:00
Iacopo Spalletti d123c7d8c8 Fix transaction handling in migration 2015-04-16 23:05:51 +02:00
Patrick Lauber 64b55d4a06 Update .travis.yml
removed my email for travis notifications
2015-04-16 16:25:28 +02:00
Iacopo Spalletti 6b361ccb03 Merge pull request #4009 from yakky/feature/fix_tree_position
Add position rebuild to CMSPlugin.fix_tree
2015-04-16 10:17:08 +02:00
Iacopo Spalletti b5d1286480 Merge pull request #4012 from yakky/feature/port_3999
Complete #3999 merge to develop
2015-04-16 10:16:58 +02:00
Iacopo Spalletti 453342b5c3 Merge pull request #4034 from yakky/remerge_3013
Forwardport 3.0.13
2015-04-16 10:16:42 +02:00
Iacopo Spalletti 8be6e6f1cc Merge remote-tracking branch 'upstream/develop' into HEAD
Conflicts:
	cms/__init__.py
	cms/admin/pageadmin.py
	cms/locale/en/LC_MESSAGES/django.mo
	cms/locale/en/LC_MESSAGES/django.po
	cms/static/cms/js/modules/cms.structureboard.js
	cms/test_utils/project/placeholderapp/cms_toolbar.py
	cms/tests/apphooks.py
	docs/upgrade/index.rst
	setup.py
	test_requirements/requirements_base.txt
2015-04-16 08:21:19 +02:00
Iacopo Spalletti 587b2fc921 Merge pull request #4035 from josjevv/correct-upgrade-docs
correct fix mptt command in upgrade docs
2015-04-15 21:16:49 +02:00
Jos van Velzen 50b2997b6e Update 3.1.rst
correct fix-mptt command
2015-04-15 21:00:24 +02:00
Iacopo Spalletti 349cae3b95 Merge pull request #4033 from FinalAngel/develop
let's get rid of the longclick
2015-04-15 19:03:00 +02:00
Martin Koistinen c5e30ea9e7 Post release bump 2015-04-15 19:26:09 +03:00
Martin Koistinen 66495b7b78 Merge branch 'release/3.0.13'
# Conflicts:
#	cms/__init__.py
2015-04-15 19:21:29 +03:00
FinalAngel 401654988b let's get rid of the longclick 2015-04-15 17:36:21 +02:00
Stefan Wehrmeyer 824adaf58d Always force language when reversing page model URLs 2015-04-15 16:58:56 +02:00
Iacopo Spalletti 048ec9e7a5 Merge pull request #4028 from FinalAngel/develop
fix preventScroll js issue
2015-04-15 14:39:53 +02:00
FinalAngel 3875084426 fix preventScroll js issue 2015-04-15 14:19:14 +02:00
Iacopo Spalletti 9028b73711 Merge pull request #4011 from yakky/feature/fix_4010
Fix Django 1.7 documentation
2015-04-14 15:22:27 +02:00
Iacopo Spalletti ee7e422fd2 Merge pull request #4015 from julienp/patch-1
Fix typo in context processor names
2015-04-14 12:15:02 +02:00
Julien Poissonnier 091c69f667 Update 3.1.rst 2015-04-14 10:47:45 +02:00
Julien Poissonnier 418455ab37 Fix typo in context processor names 2015-04-14 10:28:18 +02:00
Iacopo Spalletti 7940cdfe98 Complete #3999 merge to develop 2015-04-12 21:13:53 +02:00
Iacopo Spalletti a6ac78ce5f Fix Django 1.7 documentation 2015-04-12 20:24:04 +02:00
Iacopo Spalletti b028d6ff72 Add position rebuild to CMSPlugin.fix_tree 2015-04-12 00:27:13 +02:00
Iacopo Spalletti c3f3af4965 Pin Django version 2015-04-11 22:31:56 +02:00
Iacopo Spalletti 4ba6a1fbab Bump development version 2015-04-11 19:53:37 +02:00
Iacopo Spalletti b469298864 Update locales 2015-04-11 19:53:23 +02:00
Iacopo Spalletti 90a6ef437b Update documentation 2015-04-11 19:49:32 +02:00
Iacopo Spalletti ccff3fe240 Merge pull request #3985 from yakky/feature/31_upgrade_guide
[WiP] Add migration guide to 3.1
2015-04-11 19:45:30 +02:00
Iacopo Spalletti 6e364c98f8 Merge pull request #4008 from yakky/feature/remerge_3013
Remerge current support
2015-04-11 16:23:58 +02:00
Iacopo Spalletti 1de02028a8 Merge remote-tracking branch 'upstream/develop' into HEAD 2015-04-11 01:07:12 +02:00
Iacopo Spalletti dcb9221200 Merge pull request #3996 from yakky/feature/language_fallback_default
Reverse language_fallback default value
2015-04-10 11:14:18 +02:00
Iacopo Spalletti 3edcbe4eb6 Fix python 3 issues 2015-04-09 21:32:51 +02:00
Iacopo Spalletti d03f413d93 Change tests to take the new default into account 2015-04-09 21:25:04 +02:00
Iacopo Spalletti 1a0ae09122 Change documentation regarding 2015-04-09 21:25:04 +02:00
Iacopo Spalletti 941226ab9f Reverse language_fallback default value 2015-04-09 21:25:04 +02:00
Iacopo Spalletti 2a73ad4e0a Merge pull request #3995 from yakky/feature/revert_3943
temporary reverting #3943 for proper fix
2015-04-08 01:27:25 +02:00
Iacopo Spalletti 20fb703965 Merge pull request #3994 from evildmp/issue-3519
Fixes #3519 -- removes out-of-date images, improves text
2015-04-08 00:44:18 +02:00
Iacopo Spalletti afc14eb0bd temporary reverting #3943 for proper fix 2015-04-08 00:03:46 +02:00
evildmp 21a7e55b3d Some small changes to the upgrade notes. 2015-04-07 22:41:36 +02:00
Iacopo Spalletti 1b235edd62 Merge pull request #3980 from FinalAngel/develop
Frontend Fixes
2015-04-07 22:22:51 +02:00
evildmp 79cf7e6252 Fixes #3519 -- removes out-of-date images, improves text 2015-04-07 21:20:44 +01:00
Iacopo Spalletti 5056fa2127 Merge pull request #3988 from stefanw/patch-1
Fix UnboundLocalError in cms_tags
2015-04-07 21:46:57 +02:00
Iacopo Spalletti 80f00cf5d9 Reword django CMS 3.1 upgrade guide 2015-04-07 21:39:50 +02:00
Iacopo Spalletti 0db0931928 Merge pull request #3991 from yakky/feature/update_po
Update source PO files
2015-04-07 16:26:12 +02:00
FinalAngel cdbaf3875f fix issue 2015-04-07 14:17:41 +02:00
FinalAngel 9e81e2be6d Merge branch 'develop' of github.com:divio/django-cms into develop 2015-04-07 14:16:49 +02:00
Iacopo Spalletti 7108273f0d Update source PO files 2015-04-07 14:12:49 +02:00
Stefan Wehrmeyer 68021670ad Fix UnboundLocalError in cms_tags 2015-04-07 12:37:06 +02:00
Iacopo Spalletti 85f17ca304 Add removal of compatible plugin table names 2015-04-06 00:07:16 +02:00
Iacopo Spalletti 828574545f Add migration guide to 3.1 2015-04-05 18:31:39 +02:00
Iacopo Spalletti cf1d718657 Merge pull request #3984 from yakky/feature/post_template_addons_31
Add post_template_render_addons to toolbar
2015-04-05 18:10:33 +02:00
Iacopo Spalletti 838a69a57f Merge pull request #3943 from samluescher/develop
Fix #3942
2015-04-05 17:35:31 +02:00
Iacopo Spalletti 408431e416 Add can_change_page to cms.api 2015-04-04 17:16:33 +02:00
Iacopo Spalletti 78430308e2 Add post_template_render_addons 2015-04-04 17:16:33 +02:00
Iacopo Spalletti 503fbedf71 Merge pull request #3982 from yakky/feature/delete_plugin_button
Add delete plugin button to plugin modals
2015-04-04 17:15:43 +02:00
Martin Koistinen ab88ea73bd Merge pull request #3835 from febsn/develop
hide all submit-rows in cms.modal.js
2015-04-04 16:24:22 +03:00
Iacopo Spalletti 0a300c1a28 Fix import 2015-04-04 00:39:26 +02:00
Iacopo Spalletti 8c5d4a57e3 Fix inclusions 2015-04-03 23:48:49 +02:00
Iacopo Spalletti 34a1b4ec49 Add delete button to plugin form 2015-04-03 23:12:03 +02:00
FinalAngel f6225338f7 fix required for blueprint 2015-04-03 17:56:11 +02:00
FinalAngel 4de70c5a24 remove API call 2015-04-03 12:38:26 +02:00
FinalAngel b53eb4b841 ensure preventScroll is removed 2015-04-03 12:37:34 +02:00
FinalAngel ecbdb91fa7 fix typo 2015-04-03 12:30:26 +02:00
FinalAngel 0877f8bb31 allow longclick in content mode 2015-04-03 12:28:28 +02:00
FinalAngel 0e3f1cc640 remove longclick supporting css 2015-04-03 10:40:37 +02:00
FinalAngel c16e47a6f3 additional longclick removals 2015-04-03 10:39:02 +02:00
FinalAngel daba5978ca fixes #3561 2015-04-03 10:26:19 +02:00
FinalAngel baf9c8b844 disable prevent events for now #3347 2015-04-03 10:21:08 +02:00
FinalAngel dc98c0111b remove not used code 2015-04-03 10:20:16 +02:00
FinalAngel ea53c48be4 button needs to have the action class 2015-04-03 10:18:34 +02:00
FinalAngel f11d8e5a4e ensure that there is no transition set on the cms 2015-04-03 10:15:48 +02:00
FinalAngel 3516431e80 remove longclick 2015-04-03 10:12:15 +02:00
FinalAngel 9bec69a92f Merge branch 'develop' of github.com:divio/django-cms into develop 2015-04-03 09:50:41 +02:00
Iacopo Spalletti 38955c35a6 Merge pull request #3976 from vxsx/bugfix/modal-content-cutoff
Add transformZ hack to modal to fix cutoff content
2015-04-02 20:12:51 +02:00
Vadim Sikora 28529ec644 Add transformZ hack to modal to fix cutoff content
related to #3972
2015-04-02 10:22:02 +02:00
Iacopo Spalletti 04c2634a42 Bump development version 2015-03-26 20:09:59 +01:00
Iacopo Spalletti ad977eb4d5 Merge pull request #3963 from evildmp/release-notes
Work in progress, release notes for 3.1
2015-03-25 19:59:36 +01:00
Iacopo Spalletti 895e9bf767 Merge pull request #3968 from jbazik/fix_site_id2
Silence check when SITE_ID is an integer-valued object.
2015-03-25 19:58:25 +01:00
John Bazik d193acf6b8 Silence check when SITE_ID is an integer-valued object. 2015-03-23 17:40:50 -04:00
Iacopo Spalletti 33dda4ef77 Inclusion cleanup 2015-03-22 12:07:03 +01:00
Iacopo Spalletti 1011af41bc Merge branch 'jbazik-fix_site_id' into HEAD 2015-03-21 18:00:50 +01:00
Iacopo Spalletti 3ab5ee3f58 Merge branch 'fix_site_id' of https://github.com/jbazik/django-cms into jbazik-fix_site_id 2015-03-21 18:00:30 +01:00
evildmp d75b8599c6 fix-mptt note 2015-03-20 16:59:40 +00:00
evildmp 1afbee8665 More changes 2015-03-20 16:22:36 +00:00
John Bazik cbaf921fe6 Allow SITE_ID to be an integer-valued object. 2015-03-18 18:17:18 -04:00
evildmp acad6d1134 Work in progress, release notes for 3.1 2015-03-18 16:55:31 +00:00
Iacopo Spalletti dca734a084 Merge pull request #3901 from yakky/feature/toolbar_api_revision
Toolbar API update
2015-03-13 14:29:31 +01:00
Iacopo Spalletti 7c506235ee Amed docs 2015-03-13 12:49:38 +01:00
Samuel Luescher 8884b0b7fa Fix #3942 2015-03-12 20:10:47 +01:00
Iacopo Spalletti 8f4f797854 Add test for get_draft_url / get_public_url in Django models 2015-03-11 08:29:23 +01:00
Iacopo Spalletti 715df571ad Add test for get_draft_url / get_public_url 2015-03-11 08:29:22 +01:00
Iacopo Spalletti 84ff134ecc More doc editing 2015-03-11 08:29:22 +01:00
Iacopo Spalletti ef088ee595 Use get_object_draft_url / get_object_public_url for mode switcher 2015-03-11 08:29:22 +01:00
Iacopo Spalletti f4268fa249 Implement get_public_url / get_draft_url for page 2015-03-11 08:27:48 +01:00
Iacopo Spalletti f4e40fada9 Add get_object_draft_url / get_object_public_url to toolbar 2015-03-11 08:27:48 +01:00
Iacopo Spalletti ec92c03503 Add documentation 2015-03-11 08:27:48 +01:00
Iacopo Spalletti 05a896dfad Add system plugin flag to AliasPlugin and PlaceholderPlugin 2015-03-11 08:27:48 +01:00
Iacopo Spalletti 698fb92d3d Fix merge 2015-03-11 08:27:48 +01:00
Iacopo Spalletti aa5e185a27 Update coverage configuration 2015-03-11 08:27:47 +01:00
Iacopo Spalletti 92b899afac Avoid calling BasicToolbar.populate() multiple times 2015-03-11 08:27:47 +01:00
Iacopo Spalletti 09f5eb8085 Request must be updated on the toolbar in the templatetag to ensure that updated information is passed (e.g.: user login status) 2015-03-11 08:27:47 +01:00
Iacopo Spalletti 3c220d079f Fix clipboard initialization 2015-03-11 08:27:47 +01:00
Iacopo Spalletti 28b0c0396a Fix system plugins 2015-03-11 08:27:47 +01:00
Iacopo Spalletti 9df3804f53 Fix toolbar 2015-03-11 08:27:47 +01:00
Iacopo Spalletti 3885d307fd Move addons rendering 2015-03-11 08:27:47 +01:00
Iacopo Spalletti bf633a2230 Fix tests 2015-03-11 08:27:47 +01:00
Iacopo Spalletti 63794daf6d Fix system plugins 2015-03-11 08:27:47 +01:00
Iacopo Spalletti db5b36db5b Fix tests 2015-03-11 08:27:47 +01:00
Iacopo Spalletti 902375d0a5 Addons templates 2015-03-11 08:27:46 +01:00
Iacopo Spalletti 5af4623d46 System plugins 2015-03-11 08:27:46 +01:00
Iacopo Spalletti b374c57bb7 Toolbar addons 2015-03-11 08:27:46 +01:00
Iacopo Spalletti cc1a9fbd42 Merge pull request #3868 from yakky/future/toolbar_refactoring
Live/Draft renaming
2015-03-11 08:20:29 +01:00
Iacopo Spalletti e8186e250d Merge pull request #3933 from yakky/merge/3765
doc: plugin: text_editor_button_icon method
2015-03-08 10:40:43 +01:00
Iacopo Spalletti e388bc0b89 Add a note about supported text ckeditor 2015-03-08 09:27:32 +01:00
Olivier Le Brouster 57ad31b43d doc: plugin: text_editor_button_icon method 2015-03-08 00:15:58 +01:00
Iacopo Spalletti 95a5926441 Merge pull request #3927 from yakky/merge/3.0.11
Merge 3.0.12 back
2015-03-06 14:18:45 +01:00
Iacopo Spalletti 8a09f92cd7 Merge pull request #3666 from aptivate/add_structureboard_events
Send custom events when the structureboard is shown and hidden.
2015-03-05 08:09:54 +01:00
Iacopo Spalletti 4ef6c1319d Merge branch 'feature/fix_docs_3011' into merge/3.0.11 2015-03-05 07:52:02 +01:00
Iacopo Spalletti 1d009e0a67 Merge remote-tracking branch 'upstream/support/3.0.x' into merge/3.0.11 2015-03-05 07:51:06 +01:00
Martin Koistinen 90203d9c5f Post release bump 2015-03-04 20:55:47 -05:00
Martin Koistinen 29ffc00ef3 Merge branch 'support/3.0.x'
Conflicts:
	cms/__init__.py
2015-03-04 20:54:55 -05:00
Iacopo Spalletti 9baceceeda Merge remote-tracking branch 'upstream/develop' into HEAD 2015-03-05 00:14:04 +01:00
Martin Koistinen 02dbc076b3 Version bump to 3.0.11.post0 2015-03-04 15:53:46 -05:00
Iacopo Spalletti 63a35cff4e Merge pull request #3915 from astagi/feature/flatpins
Use style flat for pypi pins
2015-03-02 22:25:15 +01:00
Andrea Stagi 99a914c08e Use style flat for pypi pins 2015-03-02 19:01:24 +01:00
Iacopo Spalletti 1ead1d5346 Merge pull request #3912 from pgcd/allow-disabling-toolbar
Allow disabling toolbar
2015-03-01 21:41:13 +01:00
pgcd f733029884 Rebase on develop branch; adds minimal documentation for new setting CMS_TOOLBAR_URL__DISABLE and for new menu item.
references #3909
2015-03-01 15:13:44 +01:00
pgcd f2eb1bb0f0 Merge branch 'develop' into allow-disabling-toolbar
Conflicts:
	cms/tests/toolbar.py
2015-03-01 14:42:22 +01:00
pgcd dcec8d5b51 Merge branch 'allow-disabling-toolbar' of https://github.com/pgcd/django-cms into allow-disabling-toolbar 2015-03-01 13:05:00 +01:00
pgcd 3f4997d44f Adds menu item to disable toolbar - it might be nice to have some kind of warning to let the user know how to re-enable it.
references #3909
2015-03-01 13:02:19 +01:00
pgcd 101027c71a Adds menu item to disable toolbar - it might be nice to have some kind of warning to let the user know how to re-enable it.
references #3909
2015-03-01 12:47:28 +01:00
pgcd 848df1d853 Allow complete deactivation of frontend editing
references #3909
2015-03-01 12:12:10 +01:00
Iacopo Spalletti c52ce48cbc Merge pull request #3907 from yakky/feature/optional_south
Mark south as optional dependency
2015-03-01 10:15:51 +01:00
Iacopo Spalletti d9e712f0b5 Mark south as optional dependency 2015-03-01 10:15:27 +01:00
Iacopo Spalletti 27a1acab75 Merge pull request #3834 from yakky/feature/merge_1558
Merge #1558
2015-03-01 08:34:08 +01:00
Iacopo Spalletti f8d579c792 Test page tree filters 2015-02-28 11:28:31 +01:00
Iacopo Spalletti 4b06326764 Readd transifed configuration 2015-02-26 06:07:41 +01:00
Martin Koistinen 85aaf28288 Merge pull request #3881 from pevar/master
Empty All in placeholder remove plugins from all the localized version of the page
2015-02-25 10:56:05 -05:00
Claudio Bartolini 78ad9b91aa pyflake fix : Placeholder "Empty all" functionality now takes care of the current page language 2015-02-25 09:32:14 +01:00
Claudio Bartolini abe19e990b Added Test for : Placeholder "Empty all" functionality now takes care of the current page language 2015-02-24 12:45:19 +01:00
Iacopo Spalletti 1e50eb9353 Update the changelog 2015-02-24 07:25:29 +01:00
Iacopo Spalletti fd0834a9df Fix for custom user model 2015-02-24 07:25:29 +01:00
Iacopo Spalletti d52e6e86bd Fix code 2015-02-24 07:25:29 +01:00
Iacopo Spalletti 6323d78295 Porting tests of #1558 to develop. Original code by @adaptivelogic 2015-02-24 07:25:29 +01:00
Iacopo Spalletti 2839478e71 Porting code of #1558 to develop. Original code by @adaptivelogic 2015-02-24 07:25:29 +01:00
Iacopo Spalletti 4d19f46568 Merge pull request #3900 from yakky/feature/reorder_plugins
Move plugin reordering code to a function
2015-02-24 07:14:34 +01:00
Iacopo Spalletti 12acfe294c Add docstring 2015-02-23 23:37:58 +01:00
Iacopo Spalletti aec6687ff5 Move plugin reordering code to a function 2015-02-23 23:00:38 +01:00
Iacopo Spalletti c8f06b5e5f Merge pull request #3871 from yakky/feature/plugin_action_urls
Implement models based attribute for add/edit/move/delete_url
2015-02-23 21:32:46 +01:00
Iacopo Spalletti 3ecf871a5f Merge pull request #3886 from jrief/SafeJSONEncoder_default
Non serializable objects shall be handled by `default()` function
2015-02-23 08:47:20 +01:00
Iacopo Spalletti 59e5356cb7 Merge pull request #3855 from donce/publisher_publish
Logic of publisher_publish command moved to cms.api
2015-02-22 19:19:36 +01:00
Iacopo Spalletti 5f24b02c9e Merge pull request #3785 from peterfarrell/issue_3782
Fixes Issue #3782
2015-02-22 19:01:31 +01:00
Iacopo Spalletti 3a907afe58 Merge pull request #3893 from yakky/feature/fix_use_structure
Better use_structure migration
2015-02-22 18:13:53 +01:00
Iacopo Spalletti d3d1f37f0f Better use_structure migration 2015-02-21 20:02:30 +01:00
Iacopo Spalletti c10ee157ee Code cleanup 2015-02-21 18:01:35 +01:00
Iacopo Spalletti 1ab0c4f1ad Fix test_markup_plugin_template test 2015-02-21 18:01:35 +01:00
Iacopo Spalletti 757d836a26 Implement custom url for copy_plugins action 2015-02-21 18:01:35 +01:00
Iacopo Spalletti 9bd94b5c80 Add test for custom plugin admin urls 2015-02-21 18:01:35 +01:00
Iacopo Spalletti e3c088a9cd Add documentation for add/edit/move/delete_url properties 2015-02-21 18:01:10 +01:00
Iacopo Spalletti d6e160e589 Implement models based attribute for add/edit/move/delete_url 2015-02-21 18:01:10 +01:00
Iacopo Spalletti 0b0b4bb436 Merge pull request #3768 from yakky/feature/render_placeholder_uncached
Add render_uncached_placeholder templatetag
2015-02-21 17:51:16 +01:00
Iacopo Spalletti 3f3a96336c Merge pull request #3867 from yakky/future/reversion_31
Mini reversion refactoring
2015-02-21 17:31:54 +01:00
Iacopo Spalletti 19b5badaa7 Merge pull request #3869 from yakky/feature/structure_mode_permission
Structure mode permission
2015-02-21 17:31:45 +01:00
Iacopo Spalletti d423a0bd7d Merge pull request #3870 from yakky/feature/ajax_add
Implement ajax_add action
2015-02-21 17:31:36 +01:00
Iacopo Spalletti f1e7a084ee Add tests for PluginMenuItem custom action 2015-02-21 09:18:31 +01:00
Iacopo Spalletti f74d431cf2 Add docstring for PluginMenuItem 2015-02-21 09:18:31 +01:00
Iacopo Spalletti 588c41832a Implement ajax_add action 2015-02-21 09:18:31 +01:00
Iacopo Spalletti 4560601126 Merge pull request #3848 from addgene/mw/fix-publish-user
Fix #3845
Set Page.changed_by correctly in cms.api.publish_page()
2015-02-21 08:42:54 +01:00
Iacopo Spalletti 2eaf0bda32 Fix typo 2015-02-21 08:36:36 +01:00
Iacopo Spalletti cdce902077 Add documentation for render_uncached_placeholder 2015-02-21 08:34:33 +01:00
Carlo Ascani 5be0b74691 Remove empty lines 2015-02-21 08:34:33 +01:00
Carlo Ascani 18eb8acd10 Add render_uncached_placeholder tests 2015-02-21 08:34:18 +01:00
Carlo Ascani 7ce981054c Rename render_placeholder_uncached to render_uncached_placeholder 2015-02-21 08:33:07 +01:00
Iacopo Spalletti b16c2449d3 Add render_placeholder_uncached templatetag 2015-02-21 08:33:07 +01:00
Iacopo Spalletti b620d7b0a5 Fix merge error after rebase 2015-02-21 08:29:30 +01:00
Iacopo Spalletti 878f09e09e Wording change 2015-02-21 08:29:15 +01:00
Iacopo Spalletti efaeeb0749 Add use_structure permission data migration 2015-02-21 08:29:15 +01:00
Iacopo Spalletti f2a040b63d change doc wording according to @mkoistinen comments 2015-02-21 08:29:15 +01:00
Iacopo Spalletti 87ba58aa73 fix typo 2015-02-21 08:29:15 +01:00
Iacopo Spalletti 013b2edf08 Update tests 2015-02-21 08:29:15 +01:00
Iacopo Spalletti 434a2ad6c4 Structure mode permissions doc 2015-02-21 08:29:15 +01:00
Iacopo Spalletti b46380a007 Add use_structure permission. Show Structure / Content button only if the user has the use_structure permission 2015-02-21 08:29:15 +01:00
Martin Koistinen 64c179a7eb Merge pull request #3883 from mkoistinen/mkoistinen-feature/fix_plugin_tutorial
Include `cache = False` in the 'simplest plugin' example.
2015-02-20 17:19:33 -05:00
Iacopo Spalletti a5dae7d827 Merge pull request #3875 from mkoistinen/mkoistinen-feature/render_model_add_block
Add render_model_add_block tag
2015-02-20 22:19:49 +01:00
Iacopo Spalletti 42cad70dbd Merge pull request #3879 from yakky/feature/develop_migrate
Add migrate arguments to develop.py server
2015-02-20 22:19:11 +01:00
Donatas 714436fce6 Fixed publisher_publish documentation 2015-02-19 21:03:40 +02:00
Martin Koistinen 2f6a1e39fd Include cache = False in the 'simplest plugin' example.
... and provide description of this property.
2015-02-18 19:07:59 -05:00
Donatas cfa1500c55 publisher_publish command made as cms subcommand 2015-02-18 20:23:23 +02:00
Claudio Bartolini d04a3eb4b1 Placeholder "Empty all" functionality now takes care of the current page language 2015-02-18 16:59:41 +01:00
Claudio Bartolini 13842766b5 Merge pull request #2 from divio/master
Master Update from original
2015-02-18 16:32:48 +01:00
Iacopo Spalletti 37790f5d4a Add docs for migrate option 2015-02-18 08:15:22 +01:00
Iacopo Spalletti 80a1309a76 Add application-name migration-number to develop.py to control migrate command 2015-02-18 07:26:16 +01:00
Peter J. Farrell 4318dbee28 Added column to unique_together to match migration 2015-02-17 16:41:28 -06:00
Donatas cefaec7697 Added api.publish_pages documentation, moved this function to another place 2015-02-18 00:22:35 +02:00
Donatas edeeedd695 api.publish_pages receives site instead of site_id 2015-02-18 00:14:33 +02:00
Donatas f7435f9f34 Removed unused import and old comments 2015-02-17 23:27:40 +02:00
Donatas 631222f3d2 Logic of publisher_publish command moved to cms.api 2015-02-17 23:27:40 +02:00
peterfarrell 539c78eb1f - Merge migrations 2015-02-16 18:30:50 -06:00
peterfarrell 2ba883d885 - Merge 2015-02-16 18:09:35 -06:00
peterfarrell 81285e42f8 Merge remote-tracking branch 'origin/issue_3782' into issue_3782 2015-02-16 17:42:58 -06:00
peterfarrell 1a8fd910da Merge remote-tracking branch 'upstream/develop' into develop
Conflicts:
	cms/admin/pageadmin.py
	cms/admin/placeholderadmin.py
2015-02-16 17:38:05 -06:00
peterfarrell 1c5eb7bcbf Test to see if adding site fixes app-hook copy page issue 2015-02-16 17:17:19 -06:00
peterfarrell fe46361a98 Test to see if adding site fixes app-hook copy page issue 2015-02-16 17:17:19 -06:00
peterfarrell 0839781833 Test to see if adding site fixes app-hook copy page issue 2015-02-16 17:17:19 -06:00
Martin Koistinen b7ab3a1cca Remove stray text 2015-02-16 09:07:11 -05:00
Martin Koistinen 71a12072cc Re-implement docs for render_model_add_block after reverting changes to docs 2015-02-16 09:04:47 -05:00
Martin Koistinen 3c4a1cf9fb Revert "Add docs for new tag"
This reverts commit 026b0cb602.
2015-02-16 09:01:53 -05:00
Martin Koistinen 0a4cdce648 Add tests for render_model_add and render_model_add_block 2015-02-16 00:56:12 -05:00
Martin Koistinen 026b0cb602 Add docs for new tag 2015-02-16 00:09:57 -05:00
Iacopo Spalletti eff8c00345 Merge pull request #3876 from yakky/feature/update_setup
Update setup requirements
2015-02-15 12:26:42 +01:00
Iacopo Spalletti 3864d6effc Merge pull request #3872 from yakky/merge_3010
Merge 3.0.10 back
2015-02-15 07:00:40 +01:00
Iacopo Spalletti 5fccc7dbbc Update test dependencies 2015-02-15 06:23:55 +01:00
Iacopo Spalletti 673d525f32 Remove outdated test dependencies from setup.py. 2015-02-15 06:23:48 +01:00
Martin Koistinen 7725f10b70 Add render_model_add_block tag 2015-02-14 21:23:56 -05:00
Iacopo Spalletti ea423ff43a Merge remote-tracking branch 'upstream/develop' into merge_3010 2015-02-14 22:52:11 +01:00
Iacopo Spalletti 4a75faec8d Merge pull request #3838 from yakky/feature/remove_width
Remove deprecated argument
2015-02-14 18:11:27 +01:00
Iacopo Spalletti f56f661ba2 Fix page object reload
Conflicts:
	cms/models/pagemodel.py
2015-02-14 18:03:14 +01:00
Carlo Ascani afe960491a Toolbar refactoring 2015-02-14 16:16:39 +01:00
Iacopo Spalletti f3ca16c181 Return the reverted page in Page._apply_revision 2015-02-14 16:06:42 +01:00
Iacopo Spalletti 82cf5629d9 Drop request from Page.undo / Page.redo 2015-02-14 16:06:42 +01:00
Iacopo Spalletti a61fddd83f Reversion refactoring 2015-02-14 16:06:27 +01:00
Martin Koistinen 7fe76e57ee Merge pull request #3819 from jsma/patch-3818
Prevents login form from redirecting to logout.
2015-02-13 13:45:31 -05:00
Morgan Wahl 611567445a FIxing test. 2015-02-12 07:53:13 -05:00
Morgan Wahl 7396751787 Using correct API for getting a username for a user. 2015-02-12 07:52:22 -05:00
Iacopo Spalletti 560767fa54 Merge pull request #3830 from timgraham/user_model_label
Removed user_model_label from utils.compat.dj
2015-02-11 13:38:32 +01:00
Iacopo Spalletti 706d026eac Merge pull request #3840 from yakky/feature/testapp_migrations
Add south migrations for test applications
2015-02-11 07:36:08 +01:00
Iacopo Spalletti 6119ebe449 Merge pull request #3837 from yakky/feature/title_redirect_length
Make Title.redirect 2048-chars long
2015-02-11 06:51:47 +01:00
Iacopo Spalletti f4d1974751 Merge pull request #3829 from yakky/feature/fix_copy_page
Fix Page.copy_page by filtering pages on site in Page.get_descendants() ...
2015-02-11 06:51:18 +01:00
Iacopo Spalletti 4c5c205edc Add south migrations for test applications 2015-02-11 06:35:06 +01:00
Morgan Wahl a789783f4b Bugfixes for EmailUser. 2015-02-10 14:48:54 -05:00
Morgan Wahl f9191ecf26 Updated cms.api.publish_page() to set changed_by attribute correctly. 2015-02-10 12:52:30 -05:00
Morgan Wahl 9a2113e907 Added current_user contextmanager to cms.utils.permissions 2015-02-10 12:51:43 -05:00
Morgan Wahl 27be973b02 Fixed logging in pagemodel.py. 2015-02-10 12:51:15 -05:00
Morgan Wahl d682bc38f7 Added test for cms.api.publish_page(). 2015-02-10 12:50:47 -05:00
Iacopo Spalletti 8f6440b7e2 Remove deprecated argument 2015-02-08 21:52:23 +01:00
Iacopo Spalletti 1b15aae7b9 Make Title.redirect 2048-chars long 2015-02-08 21:49:59 +01:00
Tim Graham 8f4a97fae6 Removed user_model_label from utils.compat.dj. 2015-02-08 12:33:44 -05:00
febsn f92532d791 hide all submit-rows in cms.modal.js
As buttons are added to the CMS interface, all submit-rows provided by the changeform should be hidden, not only the first one (e.g. when save-on-top is active)
2015-02-08 14:40:30 +01:00
Iacopo Spalletti f0f6420c98 Merge pull request #3831 from yakky/feature/cleanup_mptt
Cleanup CMSPlugin.save.
2015-02-08 09:49:22 +01:00
Iacopo Spalletti 9f7e199906 Merge pull request #3832 from yakky/feature/fix_changelog
Fix Changelog
2015-02-08 01:39:42 +01:00
Iacopo Spalletti 51ba30f54f Fix Changelog 2015-02-08 01:38:25 +01:00
Iacopo Spalletti b28a782647 Cleanup CMSPlugin.save. Fix #3711 2015-02-08 01:24:42 +01:00
Iacopo Spalletti 686fc39e22 Merge pull request #3826 from yakky/feature/fix_page_move
Fix page move
2015-02-08 01:08:28 +01:00
Iacopo Spalletti e0ce35d20a Merge pull request #3828 from yakky/feature/refactoring_circular_imports
Refactor code to avoid circular imports
2015-02-08 01:08:03 +01:00
Iacopo Spalletti e3e153d1ac Merge pull request #5 from jsma/feature/fix_page_move
Refactored additional tree modification calls
2015-02-08 01:07:52 +01:00
Iacopo Spalletti 63d66f3cae Fix Page.copy_page by filtering pages on site in Page.get_descendants() and do not move the copied page if target is None 2015-02-08 00:58:43 +01:00
Iacopo Spalletti c94780fd96 Merge pull request #3827 from timgraham/flake8
Fixed some flake8 warnings
2015-02-08 00:49:59 +01:00
John-Scott Atlakson 531b1cb19e Refactored additional tree modification calls
Treebeard returns the created objects in add_*() calls. By using these returns values consistently, we can save unnecessary db hits since calling `reload()` in some cases is no longer needed. We also get the benefit of knowing the object has the appropriate and latest path/depth/numChild values from treebeard to avoid hard to debug tree corruption errors.

Refs #3820 and refs #3826
2015-02-07 18:09:19 -05:00
Iacopo Spalletti 95d7e5b3bf Refactor code to avoid circular imports 2015-02-07 18:42:42 +01:00
Tim Graham 5ada7d1ecb Fixed E121 flake8 warnings. 2015-02-07 12:26:51 -05:00
Tim Graham 5ed840d0a0 Fixed F841 flake8 warnings. 2015-02-07 12:26:45 -05:00
Tim Graham 66c84693b7 Fixed W601 flake8 warnings. 2015-02-07 12:21:17 -05:00
Iacopo Spalletti a19923b682 Merge pull request #3792 from timgraham/user-cleanup
Cleaned up some compatibility shims for old Django versions.
2015-02-07 17:39:31 +01:00
Tim Graham f653ecf650 Removed deprecated method on CMSToolbarLoginForm. 2015-02-07 10:40:02 -05:00
Tim Graham 0646a091bf Removed unused code: _AssertNumQueriesContext 2015-02-07 10:40:02 -05:00
Tim Graham 6234fc7383 Removed unused cms/test_utils/util/urls.py 2015-02-07 10:40:02 -05:00
Tim Graham d8f2f37041 Removed cms.test_utils.util.request_factory 2015-02-07 10:40:02 -05:00
Tim Graham 8ada716f66 Replaced cms.utils.compat.urls with django.utils.six. 2015-02-07 10:40:02 -05:00
Tim Graham 5f8ce6af30 Removed more fallbacks for old versions of Django. 2015-02-07 10:40:02 -05:00
Tim Graham fb6da2cb9a Removed usage of django.conf.urls.patterns().
This function is deprecated in Django 1.8 and isn't necessary.
2015-02-07 10:40:02 -05:00
Tim Graham 3b09eece17 Removed cms/utils/compat/metaclasses.py in favor of six. 2015-02-07 10:40:02 -05:00
Tim Graham f19980e8f9 Removed i18nurls.i18n fallback imports (from Django 1.3 support) 2015-02-07 10:40:02 -05:00
Tim Graham 3c85094ff8 Removed cms.utils.transaction. 2015-02-07 10:40:01 -05:00
Tim Graham ddbe67a8db Used force_text/python_2_unicode_compatible from Django. 2015-02-07 10:40:01 -05:00
Tim Graham 9cbb2bd3b5 Cleaned up some user compatibility shims for old Django versions. 2015-02-07 10:40:01 -05:00
Tim Graham 53f5d573ef Removed stray usage of SettingsOverride which is now gone. 2015-02-07 10:40:01 -05:00
Iacopo Spalletti e127953593 Merge pull request #3797 from timgraham/liveservertestcase
Used StaticLiveServerTestCase on Django 1.7+.
2015-02-07 15:55:36 +01:00
Iacopo Spalletti 71892221f8 Merge pull request #3825 from yakky/feature/plugin_order_publish
Merge #3661
2015-02-07 15:55:21 +01:00
Iacopo Spalletti deca37a7db Add test for #3820 2015-02-07 14:23:38 +01:00
Iacopo Spalletti e1462e3d02 Change Page.move, CMSPlugin.move to return the updated instance to reload tree data after move 2015-02-07 10:45:08 +01:00
Iacopo Spalletti eee4107a9f Cleanup 2015-02-07 09:10:08 +01:00
Iacopo Spalletti 605680535f Fix typo in test 2015-02-07 08:49:27 +01:00
Iacopo Spalletti 6137ab3051 Reworked fix 2015-02-04 23:47:32 +01:00
John-Scott Atlakson 07e4420558 Added test case to finish #3637 2015-02-04 23:43:26 +01:00
John-Scott Atlakson 41bc68394c Fixed plugin ordering for live plugins.
Refs #3637

When publishing a page, the draft plugins are copied to new 'live' versions of themselves. The code was incorrectly overwriting the position of the plugins. This change means the position remains identical to the position of the draft plugin, which is the only correct value.
2015-02-04 23:43:26 +01:00
John-Scott Atlakson 5796a7732b Prevents login form from redirecting to logout.
Refs #3818
2015-02-04 11:42:01 -05:00
Tim Graham 60abf4f4e9 Replaced custom settings override classes with Django's. 2015-01-27 09:08:12 -05:00
Tim Graham bf123ccd18 Fixed selenium tests on Django 1.7. 2015-01-27 07:52:04 -05:00
Tim Graham cc5ece1958 Used StaticLiveServerTestCase on Django 1.7+.
This class is equivalent to LiveServerTestCase on Django 1.6.
2015-01-27 07:51:18 -05:00
Jonas Obrist 379e120659 Merge pull request #3803 from timgraham/whitespace
Removed trailing whitespace and blank lines.
2015-01-27 21:50:46 +09:00
Tim Graham 3c4ad7c5f8 Removed trailing whitespace and blank lines. 2015-01-26 22:25:21 -05:00
Iacopo Spalletti 0dbb961f84 Merge pull request #3791 from timgraham/treebeard-3.0
Updated to treebeard 3.0.
2015-01-22 21:12:55 +01:00
Iacopo Spalletti 584a37b2c4 Merge pull request #3789 from timgraham/admin-fields
Silenced deprecation warnings on admin forms.
2015-01-22 19:45:02 +01:00
Tim Graham 1e811ed447 Updated to treebeard 3.0. 2015-01-22 13:04:14 -05:00
Tim Graham bd881f9e41 Silenced deprecation warnings on admin forms. 2015-01-22 12:43:12 -05:00
peterfarrell e68806eb66 Test to see if adding site fixes app-hook copy page issue 2015-01-21 01:47:34 -06:00
peterfarrell 963da14e55 Test to see if adding site fixes app-hook copy page issue 2015-01-21 01:42:51 -06:00
peterfarrell 25134276ce Test to see if adding site fixes app-hook copy page issue 2015-01-21 01:39:39 -06:00
peterfarrell e313fb4846 Test to see if adding site fixes app-hook copy page issue 2015-01-21 00:59:51 -06:00
Iacopo Spalletti 9e7e3f3f4c Merge pull request #3780 from yakky/feature/installer_docs
Change installer docs
2015-01-20 21:57:36 +01:00
Iacopo Spalletti b48c483ac3 Reword the warning 2015-01-20 14:31:03 +01:00
Iacopo Spalletti 0308569c22 Change installer docs 2015-01-20 12:16:22 +01:00
Iacopo Spalletti d6b7906864 Merge pull request #3693 from timgraham/get_foo_permission
Removed usage of deprecated meta permission methods.
2015-01-16 18:09:20 +01:00
Iacopo Spalletti d6f0dc4c00 Merge pull request #3695 from timgraham/DJANGO_1_4
Removed DJANGO_1_4 workarounds.
2015-01-16 18:09:08 +01:00
Tim Graham 67ed61fc80 Removed DJANGO_1_5 workarounds. 2015-01-15 18:48:14 -05:00
Tim Graham 2f6778b514 Removed DJANGO_1_4 workarounds. 2015-01-15 18:48:10 -05:00
Tim Graham 03759a4b77 Removed usage of deprecated meta permission methods. 2015-01-15 17:38:53 -05:00
Iacopo Spalletti 2ef8998a69 Merge pull request #3668 from evildmp/mergeintodevelop
Documentation on the code & project management process
2015-01-15 22:40:28 +01:00
Iacopo Spalletti 3acb583b3d Merge pull request #3694 from timgraham/root_query_set
Renamed deprecated root_query_set to root_queryset.
2015-01-15 22:40:06 +01:00
Iacopo Spalletti c704ee9e2f Merge pull request #3696 from timgraham/XViewMiddleware
Removed XViewMiddleware.
2015-01-15 22:39:31 +01:00
Iacopo Spalletti e0d7fda618 Merge pull request #3754 from yakky/remerge_3
Sync develop with support/3.0.x
2015-01-15 22:39:03 +01:00
Iacopo Spalletti 89a95b7393 sync django 1.7 migrations 2015-01-13 00:40:33 +01:00
Iacopo Spalletti 3a2f192e01 Add south migrations for test app 2015-01-12 22:49:49 +01:00
Iacopo Spalletti 7db2b259c2 Merge remote-tracking branch 'upstream/support/3.0.x' into HEAD
Conflicts:
	CHANGELOG.txt
	cms/__init__.py
	cms/extensions/admin.py
	cms/locale/en/LC_MESSAGES/django.po
	cms/locale/en/LC_MESSAGES/djangojs.po
	cms/migrations_django/0001_initial.py
	cms/tests/admin.py
	cms/utils/copy_plugins.py
	docs/upgrade/index.rst
	setup.py
2015-01-12 21:36:46 +01:00
Tim Graham 85e42b988e Removed XViewMiddleware.
Its an admindocs thing and shouldn't matter for most people.
2014-12-19 19:51:17 -05:00
Tim Graham de0feb5e4f Renamed deprecated root_query_set to root_queryset. 2014-12-19 18:35:51 -05:00
Stefan Foulis cb836a668b clearer error message when treebeard is not setup 2014-12-19 12:41:12 +01:00
FinalAngel db2266b226 Merge branch 'develop' of github.com:divio/django-cms into develop 2014-12-17 09:21:35 +01:00
Iacopo Spalletti dabf832a10 Merge pull request #3595 from mkoistinen/Add_RenderPluginBlock
Add new template tag render_plugin_block
2014-12-15 21:56:27 +01:00
Iacopo Spalletti 3ecf9cafb0 Merge pull request #3669 from yakky/merge/3534
Merge #3534
2014-12-11 12:22:19 +01:00
Iacopo Spalletti 176eced3ac Remove uneeded import 2014-12-11 07:24:13 +01:00
Iacopo Spalletti 960a3a419e Merge branch 'bradmwalker-develop' into develop 2014-12-10 23:07:58 +01:00
Iacopo Spalletti f5b2581d56 Fix merge 2014-12-10 23:07:30 +01:00
evildmp 6a7882c08b Documentation on the code & project management process
Describes a workflow for tickets - issues and pull requests - on
GitHub. This workflow uses a system of labels that help provide
key at-a-glance information about the state of any ticket.

In particular, the system is intended to provide unambiguous
information about a ticket's:

* status: a ticket's health and what stage the ticket is at in
the workflow
* needs: what next actions are required to move it forward

The existing labels on GitHub have been renamed and regrouped to
conform to this system.
2014-12-10 22:12:02 +01:00
Chris Wilson 817a3f7665 Send custom events when the structureboard is shown and hidden.
This allows websites to adapt by changing page styles for example, so that
all placeholders are visible. This is useful for rotators and other features
that hide parts of the page or place them offscreen.
2014-12-10 16:07:55 +00:00
Iacopo Spalletti 5378787aeb Merge pull request #3650 from timgraham/model_name
Replaced deprecated _meta.module_name with model_name.
2014-12-07 00:36:09 +01:00
Tim Graham b635256ff0 Replaced deprecated _meta.module_name with model_name. 2014-12-06 08:36:45 -05:00
Iacopo Spalletti d0b78a929e Merge pull request #3570 from yakky/feature/remove_deprecations
Remove deprecated methods / function
2014-12-01 18:40:32 +01:00
Iacopo Spalletti 2e0e2368e7 Remove unused import 2014-12-01 09:58:44 +01:00
Iacopo Spalletti 6299d0b349 Code cleanup 2014-12-01 09:45:29 +01:00
Iacopo Spalletti db176ba5eb Fix query count, imports 2014-12-01 09:45:29 +01:00
Iacopo Spalletti 6542278b06 Remove deprecated methods / function 2014-12-01 09:44:23 +01:00
Iacopo Spalletti 71f000d4db Merge pull request #3612 from timgraham/queryset
Renamed deprecated queryset methods.
2014-12-01 09:41:44 +01:00
Iacopo Spalletti f2a08daffb Merge pull request #3623 from yakky/merge_307
Forward port changes in 3.0.7
2014-12-01 09:41:24 +01:00
Iacopo Spalletti 6f862a10f9 Merge pull request #3624 from yakky/coverage
Fix coverage configuration
2014-11-28 12:22:35 +01:00
Iacopo Spalletti b07f117109 Fix coverage configuration 2014-11-28 08:36:19 +01:00
Iacopo Spalletti 46b858d37b Fix docs links 2014-11-28 07:13:17 +01:00
Iacopo Spalletti 83f5574fd6 Merge branch 'merge_307' into develop
Conflicts:
	CHANGELOG.txt
	cms/locale/en/LC_MESSAGES/django.po
	cms/locale/en/LC_MESSAGES/djangojs.po
	docs/how_to/integrate.rst
	docs/how_to/placeholders.rst
	docs/upgrade/index.rst
2014-11-27 22:38:09 +01:00
Tim Graham afc212e56e Renamed deprecated queryset methods. 2014-11-25 13:05:19 -05:00
Iacopo Spalletti 176eee5afd Merge pull request #3610 from mikek/fix-placeholderadmin-permission-check
Fix placeholderadmin permission check
2014-11-25 08:30:57 +00:00
Martin Koistinen a6b11c912a Move template into /cms/toolbar/, update path 2014-11-24 17:03:29 +02:00
Martin Koistinen 18db9633ce Use InclusionTag to simplify… everything
Thanks for the push, @yakky
2014-11-24 16:59:17 +02:00
mikek 17b563198f Fix placeholderadmin permission check 2014-11-24 15:16:24 +02:00
Iacopo Spalletti 0783d9666d Merge pull request #3579 from evildmp/merge-support
Bring develop up-to-date with support
2014-11-21 11:49:07 +00:00
Martin Koistinen c987183200 Just return, no need for an intermediate local... 2014-11-19 20:44:07 +02:00
Martin Koistinen 9f0fc1ebb5 Add explicit arguments in docs 2014-11-19 20:43:52 +02:00
Martin Koistinen eb59c2d76c Edits per code review 2014-11-19 19:54:02 +02:00
Martin Koistinen 956adf84f7 typos/edits to docs text. 2014-11-19 18:55:44 +02:00
Martin Koistinen 3ff61e49fc Add template tag and documentation 2014-11-19 18:50:38 +02:00
Daniele Procida b8ae69b432 Updated note warning that this is the develop branch 2014-11-11 22:13:39 +00:00
evildmp f6c7a19da1 Merge remote-tracking branch 'upstream/support/3.0.x' into merge-support
Conflicts:
	docs/upgrade/index.rst
2014-11-11 21:50:50 +00:00
FinalAngel 0443e13269 Merge branch 'develop' of github.com:divio/django-cms into develop 2014-11-11 15:47:53 +01:00
Martin Koistinen e3325762fa Merge pull request #3571 from evildmp/rebasebranch
Documentation restructure
2014-11-10 01:23:24 +02:00
evildmp 04009db72c Added back /user docs with TODOs. 2014-11-09 23:17:17 +00:00
evildmp 94ba53c50f Fix typo 2014-11-09 23:17:17 +00:00
evildmp c5ef3951e3 Update release notes for 3.0.6 2014-11-09 23:17:17 +00:00
evildmp 93c7786311 More documentation moves to appropriate sections
* a lot of material has been moved from /topics to /reference and
  /how_to
* redundant sections (particularly navigation placeholders) removed
* /user section removed from index for now
2014-11-09 23:17:17 +00:00
evildmp e405a3997b More work on restructuring 2014-11-09 23:17:17 +00:00
evildmp 953f4f8823 Restructuring of how_to and topic sections 2014-11-09 23:17:17 +00:00
evildmp bcc85aecdb Merged django CMS tutorial into docs.
Merged the django CMS tutorial from
https://github.com/divio/django-cms-tutorial. The tutorial was originally
created by Kim Thoenen https://github.com/chive/.
2014-11-09 23:17:17 +00:00
evildmp e0e5bf2ee2 A wholesale restructuring of the documentation.
The existing content (some of which will have to be reworked to fit better) is
now in the following main sections:

* Getting started (introduction): step-by-step tutorials and guides to
  get you up and running
* How-to guides (how_to): guides covering more advanced development
* Key topics (topics): explanations of key parts of the system
* Reference (reference): technical reference for APIs, key models and
  so on
* Development & community (contributing)
* Using django CMS (user): guides for using rather than setting up or
  developing for the CMS
* Release notes & upgrade information (upgrade)
2014-11-09 23:17:16 +00:00
John-Scott Atlakson 91cd32361e First approach at a proper overview in the docs
Added a stub for editing basics doc that is focused on non-technical audiences.
Added to the 'how to contribute' to explain how to set up local environment for testing documentation changes.
2014-11-09 23:12:22 +00:00
evildmp 550e521703 Added branch policy documentation 2014-11-09 23:12:22 +00:00
evildmp ce2752038f line wrap 2014-11-09 23:09:50 +00:00
evildmp 4485569908 publishing docs 2014-11-09 23:09:50 +00:00
Iacopo Spalletti ea7a6edd6f Merge pull request #3552 from evildmp/contributing
note on branches
2014-11-08 13:18:34 +01:00
Brad Walker ac0c6b80c6 cms.utils.copy_plugins.copy_plugins_to(): reworked, new code reuse
Now returns the list of new plugins, rather than new and old plugins zipped.
Behavior was retained, since the return value was only used once, in a len().
If the recipient wants the previous result, they can rezip the result and the
submitted parameter. This allowed the reuse of copy_plugins_to() and
encapsulated the mutating old_parent_cache parameter.

cms.utils.placeholder.MLNGPlaceholderActions.copy():
now reuses copy_plugins_to()
2014-11-07 19:30:55 -07:00
Brad Walker b1f1b59326 cms.utils.plugins: builtins and std library refactors
import iterative filter/filterfalse

requires_reload(): any()
downcast_plugins(): list comp

assign_plugins():
Moved invariant toolbar conditionals to top level. Pulled plugin placeholder_id
check loop into an all() inside a new disjoint_placeholders filter. The
build_plugin_tree query near the end was simplified since it can now accept an
iterable.

create_default_plugins():
    _create_default_plugins():
New recursive auxillary function that provides the core logic common to both
previous create_default_plugins functions. Nesting the function allows
parameter simplification since request and lang stay constant. The add_plugin()
call now provides parent plugins as the target keyword, simplifying the logic
and halving the save() method calls.
The continue statements inside the core placeholders loop were transformed into
declarative filters/generator expressions feeding the core placeholders
iteration.

create_default_children_plugins():
merged into create_default_plugins as a nested auxillary function

build_plugin_tree():
Reworked to do a groupby query and documentation added. Now also accepts an
iterable. Python3 requires partitioning roots and nonroots to sort on the
parent_id attribute. Sorting the nonroots allows grouping and guarantees the
children tuples are sorted.
2014-11-07 19:30:55 -07:00
Brad Walker 6d6c749f8d cms.models.pluginmodel: builtin refactors
CMSPlugin:
.__reduce__(): list comp
.get_translatable_content(): now filters using generators/filter
Simplified predicate collecting the fields (one isinstance, removed "and f")
.set_translatable_content(): all()

various infix ix/else and shortcut 'or' replacements
2014-11-07 19:30:55 -07:00
Brad Walker b94bde5576 menus.*: comprehensions, infix if/else, shortcut or
MenuPool.get_menus_by_attribute():
The value parameter shouldn't be None so the hasattr() call was dropped.
2014-11-07 19:30:55 -07:00
Brad Walker 9063c50e3c cms.utils.django_load: iterator and sum() refactors
import iterative map and filter

iterload(): filter()
iterload_objects(): map()
get_subclasses(): recursive sum(..., [])

Added DjangoLoadTestCase to cover iterload() and verify signatures
2014-11-07 19:30:54 -07:00
Brad Walker 617dfcb8e3 ToolbarPool.get_watch_models: sum() refactor 2014-11-07 19:30:54 -07:00
Brad Walker ae46fe9a84 cms.utils.i18n: builtins refactors
get_language_list, get_language_tuple, and get_public_languages: list comps
get_language_dict: dict(get_language_tuple)
is_language_prefix_patterns_used: any()
2014-11-07 19:30:54 -07:00
Brad Walker d19bf94aa0 cms.utils.urlutils refactors
levelize_path(): list comp
prepend slash explicitly, not relying on join of empty string
splitting all slashes and filtering empty strings also converts paths with
consecutive slashes

urljoin():
The conditionals became simpler because '/'.join(stripped) never could have
started or ended with a slash
2014-11-07 19:30:54 -07:00
Brad Walker 844b13761a cms.plugin_pool: use sorted, attrgetter and set()
PluginPool.get_all_plugins(): sorted and attrgetter
The force_unicode in the lambdas shouldn't be necessary. If strings are all the
same type, unicode or not, the sorting should be equivalent. If the strings had
mixed types the sorting comparison should coerce the byte strings to unicode.

PluginPool.get_text_enabled_plugins(): set()
Use set() to collect unique plugins; Django ORM objects are hashed on primary
key. Sort result to retain order of get_all_plugins().
2014-11-07 19:30:54 -07:00
Iacopo Spalletti f0b5d641b6 Merge pull request #3556 from evildmp/merge-support-into-develop
Merge support into develop
2014-11-07 22:38:48 +01:00
Jonas Obrist cae3cfec19 Merge pull request #3546 from yakky/feature/rename_migrations
Fix some mptt->mt migration issues
2014-11-06 20:09:29 +09:00
Iacopo Spalletti 46377ba223 Merge pull request #3564 from Medvezhopok/develop
fix for https://github.com/divio/django-cms/issues/3563
Fix #3563
2014-11-06 12:07:03 +01:00
unknown 16b4e1823e fix for https://github.com/divio/django-cms/issues/3563 2014-11-06 14:58:57 +06:00
Iacopo Spalletti ea40f9b401 Fix wording 2014-11-05 20:26:44 +01:00
Iacopo Spalletti 44aa44cc7b Fix path migrations on 1.6- 2014-11-05 20:26:35 +01:00
Patrick Lauber 07d84f5d67 Merge pull request #3559 from jgoettsch/develop
Fixes #3558. CMSSitemaps now work correctly with multiple sites.
2014-11-05 20:26:33 +01:00
Iacopo Spalletti a86da508c6 Rename migrations to a standard layout 2014-11-05 20:26:07 +01:00
Jonas Obrist ac3bc6a1f7 Merge pull request #3525 from yakky/feature/drop_1.5
Drop support for Django 1.4 / 1.5
2014-11-06 01:33:31 +09:00
Jonas Obrist 81dfdd2957 Merge pull request #3526 from evildmp/technical-board
Development of django CMS
2014-11-06 01:26:11 +09:00
Daniele Procida f9cfd54e88 Updated historical note 2014-11-05 13:17:59 +00:00
Jeffrey Goettsch a4ebb68e00 Fixes #3558. CMSSitemaps now work correctly with multiple sites. 2014-11-04 16:25:23 -08:00
evildmp 1712e27deb merged support/3.0.x into develop 2014-11-04 15:00:27 +00:00
evildmp b507064f0f note on branches 2014-11-04 11:53:57 +00:00
Patrick Lauber 6c3cdfccbe updated locales 2014-11-03 20:08:36 +01:00
Patrick Lauber 5e7b033e95 Merge pull request #3540 from jsma/typos
Fixed "Basic Infos" => "Basic Settings"
2014-11-03 19:56:10 +01:00
Brad Walker 1e1033f739 ToolbarMiddleware.process_response: conditional refactor
Changed loop into a 'not all()' call and replaced "found" bool with combined clauses
2014-10-31 23:30:10 -06:00
John-Scott Atlakson 5497a89840 Fixed "Basic Infos" => "Basic Settings"
This is more consistent with "Advanced Settings". The plural form "Infos" does not read well for native English speakers (it would never be pluralized as "Basic Informations").
2014-10-30 12:18:22 -04:00
Iacopo Spalletti fb6ec1eeaf Merge pull request #3537 from jsma/migrations-fix2
Fix migrations for MP_Tree
2014-10-30 05:07:29 +01:00
John-Scott Atlakson b997f92217 Added migration to make Page.path unique after the data migration 2014-10-28 12:02:11 -04:00
John-Scott Atlakson f3a9723412 Fix migrations for MP_Tree
The migration mistakenly adds MP_Tree path field as unique before creating the field.
2014-10-27 14:53:17 -04:00
Martin Koistinen 2fa7c67818 Replace reference to mptt with treebeard 2014-10-26 17:06:39 +02:00
Iacopo Spalletti aca3c77ad9 Merge pull request #3528 from vstoykov/logger-warnings
Use Logger.warning instead of Logger.warn
2014-10-24 22:51:31 +02:00
Iacopo Spalletti 6a2b44af70 Merge pull request #3531 from yakky/feature/fix_migration_name
Fix migrations name
2014-10-24 22:49:50 +02:00
Iacopo Spalletti dc57e9167d Merge pull request #3530 from yakky/feature/drop_mptt_docs
Drop reference to django mptt
2014-10-24 09:30:20 +02:00
Iacopo Spalletti 6d11366974 Fix migrations name 2014-10-24 07:11:17 +02:00
Iacopo Spalletti 9e799da1b4 Restore django-mptt in docs, removed elsewhere 2014-10-24 06:29:36 +02:00
Iacopo Spalletti f74293f285 Drop reference to django mptt 2014-10-24 06:27:51 +02:00
Venelin Stoykov a0339f97e6 Use Logger.warning instead of Logger.warn
Logger.warn is deprecated
https://docs.python.org/3/library/logging.html#logging.Logger.warning
2014-10-22 15:36:07 +03:00
Iacopo Spalletti 344a62654c Merge pull request #3524 from yakky/feature/3_1_docs
Add empty 3.1 documentation files
2014-10-18 14:58:30 +02:00
Iacopo Spalletti 5cf7ce9d62 Merge pull request #3523 from yakky/feature/fix_develop_migrations
Fix makemigration for django 1.6-
2014-10-18 14:58:19 +02:00
Iacopo Spalletti 42674c2c40 Add dropped support to release notes 2014-10-18 11:46:46 +02:00
Iacopo Spalletti 23eae2a648 Drop Django 1.4 and 1.5 official support 2014-10-18 11:45:07 +02:00
Iacopo Spalletti 1e1059cd79 Add empty 3.1 documentation files 2014-10-18 11:44:19 +02:00
Iacopo Spalletti 8219212310 Fix makemigration for django 1.6- 2014-10-17 22:24:13 +02:00
Iacopo Spalletti 531af988dc Merge pull request #3508 from yakky/feature/doc_coverage
Declare new testing policy
2014-10-17 21:38:55 +02:00
Iacopo Spalletti 64f1f337d5 Merge pull request #3500 from jsma/pagefield-fix
Fixed PageField to work with Django 1.7
2014-10-15 19:21:19 +02:00
Iacopo Spalletti 8a909ee469 Merge pull request #3462 from digi604/coverage
increase coverage with testing
2014-10-15 19:21:06 +02:00
Iacopo Spalletti c6b8b6cd96 Merge pull request #3458 from digi604/treebeard
switch from MPTT to MP
2014-10-15 19:20:53 +02:00
Martin Koistinen 3df86e1554 Temporary notice...
... to warn people to switch to the Support 3.0.x branch.
2014-10-15 20:16:57 +03:00
Patrick Lauber a0b4ade529 remove exception handling 2014-10-15 13:34:09 +02:00
Patrick Lauber 7d5dee5d9a migrations for sampleapp 2014-10-15 13:33:21 +02:00
Patrick Lauber 7814d39c26 removed last mptt references and docs 2014-10-15 11:56:41 +02:00
Iacopo Spalletti e1bc682233 Reword 2014-10-15 11:44:41 +02:00
Patrick Lauber e13147bc1e Merge pull request #3509 from furiousdave/develop
Fix show_menu_below_id with ids outside of softroot. #3504
2014-10-13 10:31:52 +02:00
Iacopo Spalletti 30102630bd Merge pull request #3512 from yakky/feature/migrations_verbose_name_31
Use gettext in migrations verbose name to avoid spurous migrations
2014-10-11 09:57:10 +02:00
Iacopo Spalletti f2fdcb9814 Merge pull request #3507 from yakky/feature/306_release_notes_31
Fix 3.0.6 release notes
2014-10-11 08:03:41 +02:00
Iacopo Spalletti 962e7ea829 Use gettext in migrations verbose name to avoid spurous migrations 2014-10-11 08:02:46 +02:00
furiousdave a149035d27 Updated the navigation doc regarding show_menu_below_id with soft roots 2014-10-09 14:16:07 -05:00
furiousdave f4fc235fd5 Added show_menu_below_id soft_root test 2014-10-09 13:49:13 -05:00
Iacopo Spalletti 52732a6e56 Rephrasing 2014-10-09 19:08:10 +02:00
furiousdave afd69f8c8e Added root_id exemption to SoftRootCutter conditional 2014-10-09 11:39:51 -05:00
Iacopo Spalletti 87ce512bcb Fix 3.0.6 release notes 2014-10-09 00:40:55 +02:00
Iacopo Spalletti 31c0bcfbcd Declare new testing policy 2014-10-09 00:38:10 +02:00
Iacopo Spalletti 7da03d9a3d Merge pull request #3499 from jsma/patch-1
Added warning in docs for Twitter plugins
2014-10-08 23:56:52 +02:00
Iacopo Spalletti 1c16db5142 Merge pull request #3503 from yakky/feature/fix_toolbar_api_31
Fix simplified page extension toolbar API
2014-10-08 16:16:57 +02:00
Iacopo Spalletti 52197058ab Fix simplified page extension toolbar API 2014-10-08 16:16:32 +02:00
Iacopo Spalletti eb581ddd9f Bump development version 2014-10-08 07:28:34 +02:00
John-Scott Atlakson 223c669b8a limit_choices_to is not a valid kwarg for forms.MultiValueField 2014-10-08 01:03:26 -04:00
John-Scott Atlakson fd92a19983 Fixed PageField to work with Django 1.7
When migrations call ForeignKey.deconstruct, it manipulates the `to` argument in kwargs.
Changed this to use `to` in kwargs instead of hard coding so migrations work.
2014-10-07 20:49:25 -04:00
John-Scott Atlakson b60e3d3f27 Added warning in docs for Twitter plugins
They are not currently compatible with Django 1.7
2014-10-07 18:17:53 -04:00
Patrick Lauber 6595261618 Merge branch 'treebeard' into coverage 2014-10-07 17:14:08 +02:00
Patrick Lauber 9d18957071 conflict changed back 2014-10-07 17:13:42 +02:00
Patrick Lauber 156ce289d8 Merge branch 'treebeard' into coverage 2014-10-06 16:56:36 +02:00
Patrick Lauber 2c3a9163bd Merge branch 'develop' into treebeard
Conflicts:
	cms/menu.py
2014-10-06 16:56:21 +02:00
Patrick Lauber a383227338 fix indent 2014-10-02 17:50:41 +02:00
Patrick Lauber 81dad76461 Merge branch 'treebeard' into coverage
Conflicts:
	cms/models/pagemodel.py
	cms/tests/page.py
2014-10-02 17:41:14 +02:00
Patrick Lauber 5079c29bcb fix plugin move to root 2014-10-02 16:24:42 +02:00
Patrick Lauber 948728de8a cleanup 2014-10-02 15:24:23 +02:00
Patrick Lauber f4817756ec add tests for plugin add bug 2014-10-02 15:18:39 +02:00
Patrick Lauber 9a51ec09f9 fixed an ancestor method bug 2014-10-02 14:01:55 +02:00
Patrick Lauber 3b1eda8b73 fix copy page into istself 2014-10-02 13:55:27 +02:00
Patrick Lauber 7e26623838 fixed a dict.keys() error 2014-10-01 16:34:10 +02:00
Patrick Lauber 6286234571 make sure the fallback settings are correct 2014-10-01 14:38:19 +02:00
Patrick Lauber fa867d0347 fix model_name in page extensions 2014-10-01 14:16:48 +02:00
Patrick Lauber 01e835a317 disawble coverage for compatibility code 2014-10-01 12:03:14 +02:00
Patrick Lauber 73649c0f5a fix some bugs and increase coverage 2014-10-01 11:43:46 +02:00
Patrick Lauber 921f1066b5 removed unused code 2014-10-01 11:04:10 +02:00
Patrick Lauber 38cc676149 fix response code 2014-10-01 11:00:18 +02:00
Patrick Lauber 6185f04dbc fix static placeholder tests 2014-10-01 10:53:04 +02:00
Patrick Lauber 84218bf5f3 fix extension test imports 2014-10-01 10:40:06 +02:00
Patrick Lauber 240ddde9b5 toolbar extension tests 2014-10-01 10:32:02 +02:00
Patrick Lauber 01c9ec7e54 fix p3k unicode bug, removed some stuff from coverage 2014-10-01 09:45:19 +02:00
Patrick Lauber d3dae607d4 widget and page admin coverage increase 2014-09-30 17:35:51 +02:00
Patrick Lauber 40cc5ec7fe fix 2014-09-30 14:25:58 +02:00
Patrick Lauber 8e84857ecb increase coverage of pagemodel 2014-09-30 14:15:32 +02:00
Patrick Lauber 3e7b96017c fix tests 2014-09-30 09:41:29 +02:00
Patrick Lauber fa3b04f78e fix test failures printing 2014-09-29 17:53:17 +02:00
Patrick Lauber 3774f9e1b2 Merge branch 'treebeard' into coverage 2014-09-29 17:35:52 +02:00
Patrick Lauber 73ed0de28f migrations fix 2014-09-29 17:35:38 +02:00
Patrick Lauber ca20d18b6c Merge branch 'treebeard' into coverage 2014-09-29 10:27:02 +02:00
Patrick Lauber 086e3b2566 renamed migrations 2014-09-29 10:26:37 +02:00
Patrick Lauber 604b549a77 Merge branch 'develop' into treebeard 2014-09-29 10:23:32 +02:00
Patrick Lauber db97171f10 missing email field for tests 2014-09-29 10:15:25 +02:00
Patrick Lauber 1256484959 trace failuers 2014-09-26 14:21:25 +02:00
Patrick Lauber b64ff60062 increase coverage of admin forms 2014-09-26 13:31:03 +02:00
Patrick Lauber 50de783f34 further coverage increase 2014-09-25 18:04:07 +02:00
Patrick Lauber 347c9c9d34 byteio instead of stringIO 2014-09-25 10:33:09 +02:00
Patrick Lauber f64686c47c test fix-tree command 2014-09-24 17:55:23 +02:00
Patrick Lauber 5ba1ba9bbc remove migration_django from coverage 2014-09-24 17:30:22 +02:00
Patrick Lauber 00c2121796 removed unused functions 2014-09-24 17:27:21 +02:00
Patrick Lauber bb53c4247c fix 2014-09-24 17:00:06 +02:00
Patrick Lauber a41e9ab189 cleanup 2014-09-24 16:00:15 +02:00
Patrick Lauber a3519a8ad7 test exception in alais creation 2014-09-24 15:32:39 +02:00
Patrick Lauber 0861cd3c3d test alias render method 2014-09-24 15:29:00 +02:00
Patrick Lauber 2437562612 test set_translatable_content 2014-09-24 15:21:30 +02:00
Patrick Lauber d1ad218320 cleanup and 2 new tests 2014-09-24 15:12:14 +02:00
Patrick Lauber 41bb007818 Merge branch 'treebeard' into coverage 2014-09-24 14:56:38 +02:00
Patrick Lauber f662f8c675 pickling support for plugins restored 2014-09-24 14:56:18 +02:00
Patrick Lauber dbe96d79b3 pyflakes fixes 2014-09-24 11:26:00 +02:00
Patrick Lauber ec61b6efa2 fix 2014-09-24 11:21:20 +02:00
Patrick Lauber 9e5523f58e migrations and django 1.7 migrations fixed or added 2014-09-24 11:11:53 +02:00
Patrick Lauber bc2a15ae96 Merge branch 'treebeard_migrations' into treebeard 2014-09-24 11:05:06 +02:00
Patrick Lauber 6eb03c2bc6 django 1.7 initial migrations 2014-09-24 11:04:37 +02:00
Patrick Lauber b3217e779e setup.py fix 2014-09-23 17:17:00 +02:00
Patrick Lauber 1fa9b18510 message on backwards migration 2014-09-23 16:55:11 +02:00
Patrick Lauber 3d2e0b8f1f pyflakes fix 2014-09-23 16:37:21 +02:00
Patrick Lauber c7f42395e9 fix sitemap 2014-09-23 16:36:04 +02:00
Patrick Lauber 272a11d847 fixed migrations and reworked fix-mptt command for mp 2014-09-23 16:32:59 +02:00
Patrick Lauber 305b3f5d12 first stab on a migration 2014-09-23 15:36:16 +02:00
Patrick Lauber 81d9cee407 missing import 2014-09-23 14:54:39 +02:00
Patrick Lauber eab0644c96 fixed some reversion bugs 2014-09-23 14:53:27 +02:00
Patrick Lauber 41d5ab2111 Merge branch 'develop' into treebeard 2014-09-23 11:40:07 +02:00
Patrick Lauber 4c6cea68f7 migration from between 2014-09-18 17:29:32 +02:00
Patrick Lauber b52033d0cc removed some print statements 2014-09-18 17:08:18 +02:00
Patrick Lauber 85adb19632 deleted some leftover templates 2014-09-18 16:14:22 +02:00
Patrick Lauber 6f38d84ca7 fixed all tests \o/ 2014-09-18 16:07:14 +02:00
Patrick Lauber ec1fc4dddf fixed more bugs 2014-09-17 15:34:41 +02:00
Patrick Lauber 7150d111dd fixed all non query number related tests 2014-09-17 11:27:26 +02:00
Patrick Lauber 5249fa07d7 Merge branch 'develop' into treebeard 2014-09-16 17:58:17 +02:00
Patrick Lauber cdb8ab9d86 and other test fixed 2014-09-16 17:57:12 +02:00
Patrick Lauber e83c0c919b fixed a lot of tests again 2014-09-16 10:41:35 +02:00
Patrick Lauber 54e13745a7 reducing the test failures... how could have mptt ever have functioned? 2014-09-11 17:34:05 +02:00
FinalAngel 7feabe77ff Merge branch 'develop' of github.com:divio/django-cms into develop 2014-09-04 19:42:48 +02:00
Patrick Lauber a220425353 removed some more mptt stuff 2014-09-03 13:21:55 +02:00
Patrick Lauber 5cb0d95c55 first tests passing 2014-09-02 16:21:43 +02:00
Patrick Lauber ee92d2a415 first lines for MP 2014-08-27 15:45:45 +02:00
FinalAngel 90b2c8a05f adds better animation delay to expanded class 2014-04-22 11:36:47 +02:00
842 changed files with 108623 additions and 56730 deletions
+2 -2
View File
@@ -5,11 +5,11 @@ source =
branch = False
omit =
cms/migrations/*
cms/migrations_django/*
cms/south_migrations/*
cms/tests/*
cms/test_utils/*
menus/migrations/*
menus/migrations_django/*
menus/south_migrations/*
docs/*
env/*
env*
+17
View File
@@ -0,0 +1,17 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.{scss,js,html}]
indent_style = tab
[*.rst]
max_line_length = 80
+2 -2
View File
@@ -38,5 +38,5 @@ include/
lib/
man/
share/
.editorconfig
cms/static/cms/compass_app_log.txt
!.editorconfig
cms/static/cms/compass_app_log.txt
+125 -41
View File
@@ -1,6 +1,7 @@
language: python
python:
- 3.5
- 3.4
- 3.3
- 2.7
@@ -10,25 +11,23 @@ sudo: false
env:
global:
- SAUCE_USERNAME=digi604
- secure: NWiSBCHFB6LbTMget2qLIdqZlx0zeu3j+Y7Lsqb8kuYXyT2IUBGFVedcGWuGv/9Mzypb80EQWtVTokA3/3QIbesqr29uG95pMPHiYWLdnTO6UHcLMcNXiSzhBGdRDZ40iHSVv2dDHs4GNwGOH5+UCA0z3j7SWmChuFbNXh+Vsqw=
matrix:
- DJANGO=1.4 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- DJANGO=1.4 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- DJANGO=1.4 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1
- DJANGO=1.5 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- DJANGO=1.5 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- DJANGO=1.5 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- DJANGO=1.5 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- DJANGO=1.6 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- DJANGO=1.6 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
- DJANGO=1.7 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- DJANGO=1.7 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- DJANGO=1.7 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- DJANGO=1.7 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
- DJANGO=1.8 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- DJANGO=1.8 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- DJANGO=1.8 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- DJANGO=1.8 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- DJANGO=1.8 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
- DJANGO=1.9 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
before_script:
- sh -c "if [ '$DATABASE_URL' = 'postgres://postgres@127.0.0.1/djangocms_test' ];
@@ -39,30 +38,41 @@ before_script:
-e 'create database IF NOT EXISTS djangocms_test CHARACTER SET utf8 COLLATE utf8_general_ci;';
fi"
before_install:
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
install:
- pip install -q -r "test_requirements/django-$DJANGO.txt"
- if [ $DATABASE_URL == 'postgres://postgres@127.0.0.1/djangocms_test' ]; then pip
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install 'xvfbwrapper<0.2.7'; else pip install xvfbwrapper; fi
- if [[ $DATABASE_URL == 'postgres://postgres@127.0.0.1/djangocms_test' ]]; then pip
install -q psycopg2 ; fi
- if [ $DATABASE_URL == 'mysql://root@127.0.0.1/djangocms_test' ]; then pip install
-q mysql-python ; fi
- if [[ $DATABASE_URL == 'mysql://root@127.0.0.1/djangocms_test' ]]; then pip install
-q mysqlclient ; fi
script: coverage run --rcfile=.coverage.rc develop.py test --migrate
script: coverage run --rcfile=.coverage.rc develop.py test --migrate --xvfb
after_success: coveralls --config_file=.coverage.rc --coveralls_yaml=.coveralls.yml
after_success: coveralls --config_file=.coverage.rc
notifications:
email:
recipients:
- digi@treepy.com
on_success: never
on_failure: always
irc:
- irc.freenode.org#django-cms
- irc.freenode.org#django-cms-sprint
webhooks:
- http://addons.us-iad-rs.aldryn.io/en/travis-endpoint/
matrix:
exclude:
- python: 2.6
env: DJANGO=1.6 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 2.6
env: DJANGO=1.6 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 2.6
env: DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- python: 2.6
env: DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 2.6
env: DJANGO=1.7 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 2.6
@@ -72,34 +82,108 @@ matrix:
- python: 2.6
env: DJANGO=1.7 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 3.3
env: DJANGO=1.4 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 3.3
env: DJANGO=1.4 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.5 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.6 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.7 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.4 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1
- python: 2.6
env: DJANGO=1.8 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 2.6
env: DJANGO=1.8 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 2.6
env: DJANGO=1.8 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- python: 2.6
env: DJANGO=1.8 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 2.6
env: DJANGO=1.8 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
- python: 3.4
env: DJANGO=1.4 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 3.4
env: DJANGO=1.4 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.4
env: DJANGO=1.5 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.4
- python: 2.7
env: DJANGO=1.6 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 2.7
env: DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- python: 2.7
env: DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 2.7
env: DJANGO=1.7 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 2.7
env: DJANGO=1.7 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.6 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 3.3
env: DJANGO=1.6 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.4
- python: 3.3
env: DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 3.3
env: DJANGO=1.7 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 3.3
env: DJANGO=1.7 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.4
env: DJANGO=1.4 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1
- python: 3.3
env: DJANGO=1.7 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.8 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 3.3
env: DJANGO=1.8 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.8 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.8 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 3.5
env: DJANGO=1.6 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 3.5
env: DJANGO=1.6 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.5
env: DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.5
env: DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 3.5
env: DJANGO=1.6 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
- python: 3.5
env: DJANGO=1.7 DATABASE_URL='sqlite://localhost/:memory:' SELENIUM=0
- python: 3.5
env: DJANGO=1.7 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.5
env: DJANGO=1.7 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.5
env: DJANGO=1.7 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='emailuserapp.EmailUser'
- python: 2.6
env: DJANGO=1.9 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
- python: 2.7
env: DJANGO=1.9 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
- python: 3.3
env: DJANGO=1.9 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
- python: 3.5
env: DJANGO=1.9 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
allow_failures:
- python: 2.7
env: DJANGO=1.7 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 2.7
env: DJANGO=1.8 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.6 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.7 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.3
env: DJANGO=1.8 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.4
env: DJANGO=1.6 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.4
env: DJANGO=1.7 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.4
env: DJANGO=1.8 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.5
env: DJANGO=1.8 DATABASE_URL='mysql://root@127.0.0.1/djangocms_test' SELENIUM=0
- python: 3.4
env: DJANGO=1.9 DATABASE_URL='postgres://postgres@127.0.0.1/djangocms_test' SELENIUM=1 AUTH_USER_MODEL='customuserapp.User'
fast_finish: true
+48 -42
View File
@@ -20,7 +20,7 @@ Current and previous core designers:
* Christian Bertschy
Contributors (based on gitlog) (450):
Contributors (based on gitlog) (456 authors):
* A. Bram Neijt
* aaloy
@@ -30,7 +30,6 @@ Contributors (based on gitlog) (450):
* aball
* Adi Sieker
* Admin Adminaras
* Adrián Ribao
* Adrián Ribao Martínez
* Alberto Paro
* Ales Kocjancic
@@ -41,7 +40,6 @@ Contributors (based on gitlog) (450):
* Alex Marandon
* Alexandre Leray
* Alexey Subbotin
* Aleš Kocjančič
* Alvin Mites
* Anatoly Ivanov
* Andi Albrecht
@@ -49,13 +47,12 @@ Contributors (based on gitlog) (450):
* Andrea Stagi
* Andrei Avram
* Andrei Fokau
* Andrew Cassidy
* Andrew Schoen
* Angelo Dini
* angular_circle
* Antoine Catton
* Anton Parkhomenko
* Antoni Aloy López
* AQNOUCH Mohammed
* Arcady Usov
* Arne Gellhaus
* Arne Schauf
@@ -63,13 +60,12 @@ Contributors (based on gitlog) (450):
* Arthur Debert
* Artis Avotins
* Aymeric Augustin
* Bashar Al-Abdulhadi
* Batiste Bieler
* Basile LEGAL
* behrooz
* Behrooz Nobakht
* Belegnar
* Ben Northway
* Ben Stähli
* Beni Wohlwend
* Benjamin
* Benjamin Liles
* Benjamin Wohlwend
@@ -83,13 +79,14 @@ Contributors (based on gitlog) (450):
* Bjorn Sandberg
* Bob Karreman
* Bouke Haarsma
* Brad Walker
* Braden MacDonald
* Brian Schott
* brightwhitefox
* Calvin Cheng
* Carlo Ascani
* Carlos de Paula
* casio
* Catalin Dragomirescu
* centralniak
* Chanita Siridechkun
* Charlie Denton
@@ -102,14 +99,14 @@ Contributors (based on gitlog) (450):
* Chris Jones
* Chris Wesseling
* Chris Wilson
* Christian Bertschy
* Christian Strappazzon
* Christof Hagedorn
* Christopher Grebs
* Christos Kopanos
* cip
* Claudio Bartolini
* Colin Wirz
* Conrado Buhrer
* Conrado Bührer
* Corey Farwell
* Craig de Stigter
* Craig Ricciuto
@@ -132,6 +129,7 @@ Contributors (based on gitlog) (450):
* David Lam
* David Lee
* David Thompson
* Davide Setti
* derek73
* deshack
* digi604
@@ -142,13 +140,14 @@ Contributors (based on gitlog) (450):
* Donatas
* Donatas Kučinskas
* Douwe van der Meij
* Dries Desmet
* dstufft
* Dylann CORDEL
* DylannCordel
* DZ
* eged
* Egor V. Nazarkin
* Ekrem Seren
* Ekrem SEREN
* Elias Probst
* Eric Amador
* Eric Eldredge
@@ -156,14 +155,13 @@ Contributors (based on gitlog) (450):
* ericr
* Erik Allik
* Erlend Dalen
* Eugen MechanisM
* Eugene MechanisM
* Evandro Miquelito
* Evgeny Demchenko
* evildmp
* F. Gabriel Gosselin
* f4nt
* fcurella
* febsn
* Filip Kazimierczak
* FinalAngel
* fivethreeo
@@ -179,28 +177,25 @@ Contributors (based on gitlog) (450):
* gentleShark
* Geoffrey Hing
* George Marshall
* Gerard Świdersk
* Gerard Świderski
* Germano Gabbianelli
* Germano Gabbianellii
* Gilles Lenfant
* Gleb Chipiga
* Gregory Klupar
* guandalino
* Hamish Downer
* Hans Andersen
* hedberg
* henning
* Henning Spran
* Henning Sprang
* Herbert Poul
* hjkelly
* homebrew79
* Horst Gutmann
* hysia
* Iacopo Spalletti
* Ian Lewis
* ikudryavtsev
* indexofire
* Ionel Cristian Maries
* Ionel Maries Cristian
* Ivan Vershigora
* Iván Raskovsky
@@ -212,19 +207,21 @@ Contributors (based on gitlog) (450):
* Jameel Al-Aziz
* James Richards
* James Rutherford
* Jana Deutschlaender
* Jannis Leidel
* Janusz Harkot
* Jared Proffitt
* Jason Brown
* Jason Davies
* Jason Jenkins
* Jason Robinson
* Jason Zylks
* Javi Nievas
* Jeffrey Goettsch
* JensDiemer
* Jeroen Noten
* Jessica Tallon
* Jimmy Lam
* Johannes Bornhold
* John Bazik
* John-Scott Atlakson
* Jon Prindiville
* Jonas Obrist
@@ -232,32 +229,33 @@ Contributors (based on gitlog) (450):
* Jonathan Stoppani
* jordanjambazov
* Jorge Vargas
* Jorge Vargas (elpargo)
* Jos van Velzen
* Joseph Bergantine
* Joseph Melettukunnel
* Josh Kalderimis
* Josh Schneier
* João Luiz Lorencetti
* Julien Poissonnier
* Kalle Bronsen
* kar1m
* kater169
* kblomqvis
* kblomqvist
* Kegan Holtzhausen
* Keryn Knight
* Kevin Richardson
* Kim Blomqvist
* Kim Thoenen
* kochin
* Kristian Øllegaard
* Krzysztof Bandurski
* kunitoki
* Lars Smit
* Lars van de Kerkhof
* limpbrains :P
* Lio Mendonca
* Lionardo Mendonça
* littlepea
* lovmat
* Lucas Vogelsang
* Lucio Asnaghi
* lug
* Luis Diego Garcia
* Luke Crooks
* Luke Plant
* m000
@@ -267,19 +265,21 @@ Contributors (based on gitlog) (450):
* Manuel Schmidt
* Marc-Olivier Titeux
* Marco Bonetti
* marco federighi
* Marco Paolini
* Marco Rimoldi
* marcor
* Marijn Goedegebure
* Mark Rogers
* Markus Holtermann
* Markus Zapke-Gründemann
* Markus Zapke-Gründemann
* Marti Raudsepp
* Martin
* Martin Bommeli
* Martin Bambas
* Martin Brochhaus
* Martin Koistinen
* Martin Kosír
* Martin Owens
* Martin Pajuste
* martinkosir
* Matas Dailyda
@@ -287,6 +287,8 @@ Contributors (based on gitlog) (450):
* Mateusz Marzantowicz
* mathijs
* Matt Chisholm
* Matteo Rosati
* Mattia Larentis
* Max Shkurygin
* Maxim Bodyansky
* Maxime Haineault
@@ -300,6 +302,7 @@ Contributors (based on gitlog) (450):
* Mike Dory
* Mike Johnson
* mikek
* Mikko Ahlroth
* Milo Price
* Mitar
* Mokys
@@ -312,7 +315,6 @@ Contributors (based on gitlog) (450):
* Nelson Brochado
* neoprolog
* Nick Jones
* Nickolay V. Shmyrev
* nikolas
* nsh
* o-zander
@@ -324,7 +326,7 @@ Contributors (based on gitlog) (450):
* Oyvind Saltvik
* padelt
* Pankrat
* Paolo
* Paolo Leggio
* Pascal Mouret
* pascal.beyeler
* Patrick Arminio
@@ -341,19 +343,20 @@ Contributors (based on gitlog) (450):
* pcicman
* Pedro Gracia
* Pete Loggie
* Peter Ciciman
* Peter Farrell
* Peter J. Farrell
* Peter Landry
* Peter-Paul van Gemerden
* peterfarrell
* Petteri
* pgcd
* Philipp Bosch
* philomat
* phuihock
* Pigletto
* Piotr Jakimiak
* Piotr Kilczuk
* piquadrat
* poweredbypenguins
* Pratik Vyas
* pumalo
* Rafal Radulski
* raidsan
@@ -373,7 +376,7 @@ Contributors (based on gitlog) (450):
* Robert Feldbinder
* Robert Pogorzelski
* Roberto
* Roberto Lopez
* Roberto Bampi
* Robin Lewis
* robint
* Rodolfo Carvalho
@@ -381,11 +384,12 @@ Contributors (based on gitlog) (450):
* root
* rtpm
* Russ Ferriday
* Sam Manzi
* Samuel Lahti
* Samuel Luescher
* Samuel Lüscher
* sbussetti
* Schoen
* Scott Barnham
* scottbarnham
* sealibora
* Sean Bleier
@@ -407,18 +411,18 @@ Contributors (based on gitlog) (450):
* ssteinerX
* Stavros Korokithakis
* Stefan Foulis
* Stefan T. Oertel
* Stefan Wehrmeyer
* stefanfoulis
* Stefano Brentegani
* Stefano Crosta
* Stefano Morandi
* Steffen Jasper
* Stephan
* Stephan Hepper
* Stephan Herzog
* Stephan Jaekel
* Stephen Muss
* Stephen Watkin
* Steve R. Jones
* Steve Steiner
* Steven Laroche
* Sylvain Fankhauser
@@ -428,7 +432,6 @@ Contributors (based on gitlog) (450):
* Thomas Parslow
* Thomas Remmert
* Thomas Woolford
* Tibor Balogh
* Tim Anderegg
* Tim Davies
* Tim Graham
@@ -437,19 +440,20 @@ Contributors (based on gitlog) (450):
* tiret
* Tobias von Klipstein
* Tom
* Tom Berger
* Tom de Simone
* Tom S
* Tom V
* Tom Wardill
* Ulrich Petri
* unknown
* User
* Vasil Vangelovski
* Vadim Sikora
* Venelin Stoykov
* Viktor Nagy
* Viliam Segeda
* Vinit (Vermicelli on IRC)
* vinit kumar
* Vitor Figueiro
* Vladimir Bolshakov
* Vladyslav
* vvangelovski
@@ -459,6 +463,7 @@ Contributors (based on gitlog) (450):
* wildermesser
* Xavier Fernandez
* Xavier Ordoquy
* xie wei
* xray7224
* Yann Malet
* yann.malet@gmail.com
@@ -471,4 +476,5 @@ Contributors (based on gitlog) (450):
* zundoya
* Óscar M. Lage
* Øyvind Saltvik
* Антон Евжаков
* Žan Anderle
* Антон Евжаков
+157 -2
View File
@@ -292,7 +292,7 @@ Please see Install/2.4 release notes *before* attempting to upgrade to version 2
- Added list of retired core developers
- Added branch policy documentaion
=== 3.0.8 (2015-01-11) ===
==== 3.0.8 (2015-01-11) ===
- Add require_parent option to CMS_PLACEHOLDER_CONF
- Fix django-mptt version depenency to be PEP440 compatible
- Fix some Django 1.4 compatibility issues
@@ -306,7 +306,7 @@ Please see Install/2.4 release notes *before* attempting to upgrade to version 2
- Documentation fixes
- Minor code cleanups
=== 3.0.9 (2015-01-11) ===
==== 3.0.9 (2015-01-11) ===
- Revert a change that caused a regression in toolbar login
- Fix an error in a translated phrase
- Fix error when moving items in the page tree
@@ -381,3 +381,158 @@ Please see Install/2.4 release notes *before* attempting to upgrade to version 2
- Pin South version to 1.0.2
- Pin Html5lib version to 0.999 until a current bug is fixed
- Fix language chooser template
=== 3.0.15 (2015-09-01) ===
- Relax html5lib versions
- Fix redirect when deleting a page
- Correct South migration error
- Correct validation on numeric fields in modal popups
- Exclude scssc from manifest
- Remove unpublished pages from menu
- Remove page from menu items for performance reason
- Fix reachability of pages with expired ancestors
- Don't try to modify an immutable QueryDict
- Only attempt to delete cache keys if there are some to be deleted
- Update documentation section
- Fix language chooser template
- Cast to int cache version
- Fix extensions copy when using duplicate page/create page type
=== 3.0.16 (2015-11-24) ===
- Fix JS error when using PageSelectWidget
- Fix whitespace markup issues in draft mode
- Detect plugin migrations layout in tests
=== 3.0.17 (unreleased) ===
- Fix ExtensionToolbar when language is removed but titles still exists…
- Fix PageSelectWidget JS syntax
- Fix cache settings
=== 3.1 (2015-04-20) ===
- Remove django-mptt in favor of django-treebeard
- Remove compatibility with Django 1.4 / 1.5
- General code cleanup
- Simplify loading of view restrictions in the menu
- South is not marked as optional; to use south on Django 1.6 install django-cms[south]
- Add system_plugin attribute to CMSPluginBase that allow the plugin to override any configured restriction
- Change placeholder language fallback default to True
- Remove plugin table naming compatibility layer
- Remove deprecated cms.context_processors.media context processor
- Add templatetag render_plugin_block
- Add templatetag render_model_add_block
- Add "Structure mode" permission
=== 3.1.1 (2015-06-27) ===
- Add Django 1.8 support
- Tutorial updates and improvements
- Fix issue with causes menu classes to be duplicated in advanced settings
- Fix issue with breadcrumbs not showing
- Fix issues with show_menu templatetags
- Minor documentation fixes
- Revert whitespace cleanup on flash player to fix it
- Correctly restore previous status of dragbars
- Add copy_site command
- Fix an issue related to "Empty all" Placeholder feature
- Fix plugin sorting in py3
- Fix language-related issues when retrieving page URL
- Add setting to disable toolbar for anonymous users
- Fix search results number and items alignment in page changelist
- Preserve information regarding the current view when applying the CMS decorator
- Fix errors with toolbar population
- Fix error with watch_models type
- Fix error with plugin breadcrumbs order
- Change the label "Save and close" to "Save as draft"
- Fix X-Frame-Options on top-level pages
- Fix order of which application urls are injected into urlpatterns
- Fix delete non existing page language
- Fix language fallback for nested plugins
- Fix render_model template tag doesn't show correct change list
- Fix Scanning for placeholders fails on include tags with a variable as an argument
- Fix handling of plugin position attribute
- Fix for some structureboard issues
- Add setting to hide toolbar when a URL is not handled by django CMS
- Add editorconfig configuration
- Make shift tab work correctly in submenu
- Fix get_language_from_request if POST and GET exists
- Fix an error in placeholder cache
- Fix language chooser template
=== 3.1.2 (2015-07-02) ===
- Fix placeholder cache invalidation under some circumstances
- Update translations
=== 3.1.3 (2015-09-01) ===
- Add missing migration
- Exclude PageUser manager from migrations
- Fix check for template instance in Django 1.8.x
- Fix error in PageField for Django 1.8
- Fix some Page tree bugs
- Declare Django 1.6.9 dependency in setup.py
- Make sure cache version returned is an int
- Fix issue preventing migrations to run on a new database (django 1.8)
- Fix get User model in 0010 migration
- Fix support for unpublished language pages
- Add documentation for plugins datamigration
- Fix getting request in _show_placeholder_for_page on Django 1.8
- Fix template inheritance order
- Fix xframe options inheritance order
- Fix placeholder inheritance order
- Fix language chooser template
- Relax html5lib versions
- Fix redirect when deleting a page
- Correct South migration error
- Correct validation on numeric fields in modal popups
- Exclude scssc from manifest
- Remove unpublished pages from menu
- Remove page from menu items for performance reason
- Fix reachability of pages with expired ancestors
- Don't try to modify an immutable QueryDict
- Only attempt to delete cache keys if there are some to be deleted
- Update documentation section
- Fix language chooser template
- Cast to int cache version
- Fix extensions copy when using duplicate page/create page type
=== 3.1.4 (2015-11-24) ===
- Fix use structure migration
- Fix fix_tree command
- Remove some warning for Django 1.9
- Fix using scroll bar of plugin menu in Firefox & IE moves plugins
- Fix JS error when using PageSelectWidget
- Fix whitespace markup issues in draft mode
- Detect plugin migrations layout in tests
- Fix some treebeard corruption issues
=== 3.1.5 (2016-01-29) ===
- Fixed a tree corruption when pasting a nested plugin under another plugin.
- Improve CMSPluginBase.render documentation
- Fix CMSEditableObject context generation which generates to errors with django-classy-tags 0.7.1
- Fix error in toolbar when LocaleMiddleware is not used
- Move templates validation in app.ready
- Fix ExtensionToolbar when language is removed but titles still exists
- Fix pages menu missing on fresh install 3.1
- Fix incorrect language on placeholder text for redirect field
- Fix PageSelectWidget JS syntax
- Fix redirect when disabling toolbar
- Fix CMS_TOOLBAR_HIDE causes 'WSGIRequest' object has no attribute 'toolbar'
=== 3.1.6 (unreleased) ===
- Fix cache settings
- Fix user lookup for view restrictions/page permissions when using raw id field
- Fixes an issue relating to uninstalling a namespaced application
- Adds "Can change page" permission
- Addresses security vulnerabilities in the `render_model` template tag that
could lead to escalation of privileges or other security issues.
- Addresses a security vulnerability in the cms' usage of the messages framework
- Fixes security vulnerabilities in custom FormFields that could lead to
escalation of privileges or other security issues.
+2 -1
View File
@@ -9,4 +9,5 @@ recursive-include cms/plugins *
recursive-include menus/templates *
recursive-include stacks/templates *
recursive-include docs *
recursive-exclude * *.pyc
recursive-exclude * *.pyc
recursive-exclude * *.scssc
+30 -9
View File
@@ -3,18 +3,30 @@ django CMS
##########
.. image:: https://travis-ci.org/divio/django-cms.svg?branch=support%2F3.0.x
:target: http://travis-ci.org/divio/django-cms
.. image:: https://pypip.in/v/django-cms/badge.svg
.. image:: https://img.shields.io/pypi/v/django-cms.svg
:target: https://pypi.python.org/pypi/django-cms/
.. image:: https://pypip.in/d/django-cms/badge.svg
.. image:: https://img.shields.io/pypi/dm/django-cms.svg
:target: https://pypi.python.org/pypi/django-cms/
.. image:: https://pypip.in/wheel/django-cms/badge.svg
.. image:: https://img.shields.io/badge/wheel-yes-green.svg
:target: https://pypi.python.org/pypi/django-cms/
.. image:: https://pypip.in/license/django-cms/badge.svg
.. image:: https://img.shields.io/pypi/l/django-cms.svg
:target: https://pypi.python.org/pypi/django-cms/
.. image:: https://codeclimate.com/github/divio/django-cms/badges/gpa.svg
:target: https://codeclimate.com/github/divio/django-cms
:alt: Code Climate
Open source enterprise content management system based on the django framework.
.. ATTENTION:: To propose features, always open pull requests on the **develop** branch.
It's the branch for features that will go into the next django CMS feature release.
For fixes for 3.0.x releases, please work on **support/3.0.x** which contains
the next patch release for 3.0.x series.
The **master** branch is the current stable release, the one released on PyPI.
Changes based on **master** will not be accepted.
********
Features
********
@@ -37,11 +49,11 @@ You can define editable areas, called placeholders, in your templates which you
with many different so called CMS content plugins.
A list of all the plugins can be found here:
`3rd party plugins <http://www.djangopackages.com/grids/g/django-cms/>`_
`3rd party plugins <http://www.djangopackages.com/grids/g/django-cms/>`_
Should you be unable to find a suitable plugin for you needs, writing your own is very simple.
More information on `our website <http://www.django-cms.org>`_.
More information on `our website <http://www.django-cms.org>`_.
*************
Documentation
@@ -66,8 +78,10 @@ You can use the `django CMS installer <https://github.com/nephila/djangocms-inst
$ virtualenv env
$ source env/bin/activate
(env) $ pip install djangocms-installer
(env) $ mkdir myproject && cd myproject
(env) $ djangocms -p . my_demo
(env) $ cd my_demo
(env) $ python manage.py
************
Getting Help
@@ -76,13 +90,20 @@ Getting Help
Please head over to our IRC channel, #django-cms, on irc.freenode.net or write
to our `mailing list <https://groups.google.com/forum/#!forum/django-cms>`_.
******************
Commercial support
******************
This project is backed by `Divio <https://divio.ch>`_. If you need help
implementing or hosting django CMS, please contact us: sales@divio.ch.
*******
Credits
*******
* Includes icons from `FamFamFam <http://www.famfamfam.com>`_.
* Python tree engine powered by
`django-mptt <https://github.com/django-mptt/django-mptt>`_.
`django-treebeard <https://tabo.pe/projects/django-treebeard/>`_.
* Javascript tree in admin uses `jsTree <http://www.jstree.com>`_.
* Many thanks to the
`over 250 contributors <https://github.com/divio/django-cms/blob/master/AUTHORS>`_
+2 -1
View File
@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
__version__ = '3.0.14'
__version__ = '3.1.6'
default_app_config = 'cms.apps.CMSConfig'
+30 -34
View File
@@ -2,13 +2,12 @@
import bisect
from cms.models import Title, Page, EmptyTitle
from cms.utils import get_language_list
from cms.utils.compat import DJANGO_1_5
from cms.utils.conf import get_cms_setting
from cms.utils.permissions import get_user_sites_queryset
from cms.utils.permissions import get_user_sites_queryset, load_view_restrictions
from django.contrib.admin.views.main import ChangeList, ALL_VAR, IS_POPUP_VAR, \
ORDER_TYPE_VAR, ORDER_VAR, SEARCH_VAR
from django.contrib.sites.models import Site
import django
COPY_VAR = "copy"
@@ -20,7 +19,7 @@ def cache_tree_children(queryset):
item, which would otherwise (if '_cached_children' is not set) cause a
database query.
The queryset must be ordered by 'lft', or the function will put the children
The queryset must be ordered by 'path', or the function will put the children
in the wrong order.
"""
parents_dict = {}
@@ -46,12 +45,13 @@ class CMSChangeList(ChangeList):
real_queryset = False
def __init__(self, request, *args, **kwargs):
from cms.utils.plugins import current_site
from cms.utils.helpers import current_site
self._current_site = current_site(request)
super(CMSChangeList, self).__init__(request, *args, **kwargs)
try:
self.queryset = self.get_query_set(request)
except:
self.queryset = self.get_queryset(request)
except: # pragma: no cover
raise
self.get_results(request)
@@ -59,33 +59,26 @@ class CMSChangeList(ChangeList):
request.session['cms_admin_site'] = self._current_site.pk
self.set_sites(request)
def get_query_set(self, request=None):
def get_queryset(self, request):
if COPY_VAR in self.params:
del self.params[COPY_VAR]
if 'language' in self.params:
del self.params['language']
if 'page_id' in self.params:
del self.params['page_id']
if django.VERSION[1] > 3:
qs = super(CMSChangeList, self).get_query_set(request).drafts()
else:
qs = super(CMSChangeList, self).get_query_set().drafts()
if request:
site = self.current_site()
permissions = Page.permissions.get_change_id_list(request.user, site)
if permissions != Page.permissions.GRANT_ALL:
qs = qs.filter(pk__in=permissions)
# root_query_set is a read-only property in Django 1.6
# and will be removed in Django 1.8.
queryset_attr = 'root_query_set' if DJANGO_1_5 else 'root_queryset'
setattr(self, queryset_attr, self.root_query_set.filter(pk__in=permissions))
self.real_queryset = True
qs = qs.filter(site=self._current_site)
qs = super(CMSChangeList, self).get_queryset(request).drafts()
site = self.current_site()
permissions = Page.permissions.get_change_id_list(request.user, site)
if permissions != Page.permissions.GRANT_ALL:
qs = qs.filter(pk__in=permissions)
self.root_queryset = self.root_queryset.filter(pk__in=permissions)
self.real_queryset = True
qs = qs.filter(site=self._current_site)
return qs
def is_filtered(self):
from cms.utils.plugins import SITE_VAR
lookup_params = self.params.copy() # a dictionary of the query string
from cms.utils.helpers import SITE_VAR
lookup_params = self.params.copy() # a dictionary of the query string
for i in (ALL_VAR, ORDER_VAR, ORDER_TYPE_VAR, SEARCH_VAR, IS_POPUP_VAR, SITE_VAR, 'language', 'page_id'):
if i in lookup_params:
del lookup_params[i]
@@ -97,15 +90,15 @@ class CMSChangeList(ChangeList):
if self.real_queryset:
super(CMSChangeList, self).get_results(request)
if not self.is_filtered():
self.full_result_count = self.result_count = self.root_query_set.drafts().count()
self.full_result_count = self.result_count = self.root_queryset.drafts().count()
else:
self.full_result_count = self.root_query_set.drafts().count()
self.full_result_count = self.root_queryset.drafts().count()
def set_items(self, request):
site = self.current_site()
# Get all the pages, ordered by tree ID (it's convenient to build the
# tree using a stack now)
pages = self.get_query_set(request).drafts().order_by('tree_id', 'lft').select_related('publisher_public')
pages = self.get_queryset(request).drafts().order_by('path').select_related('publisher_public')
# Get lists of page IDs for which the current user has
# "permission to..." on the current site.
@@ -118,19 +111,22 @@ class CMSChangeList(ChangeList):
pages = pages.filter(pk__in=perm_edit_ids)
root_pages = []
# Cache view restrictions for the is_restricted template tag
load_view_restrictions(request, pages)
pages = list(pages)
all_pages = pages[:] # That is, basically, a copy.
# Unfortunately we cannot use the MPTT builtin code for pre-caching
# the children here, because MPTT expects the tree to be 'complete'
# and otherwise complaints about 'invalid item order'
cache_tree_children(pages)
ids = dict((page.id, page) for page in pages)
parent_ids = {}
for page in pages:
children = list(page.get_children())
if not page.parent_id in parent_ids:
parent_ids[page.parent_id] = []
parent_ids[page.parent_id].append(page)
for page in pages:
children = parent_ids.get(page.pk, [])
# If the parent page is not among the nodes shown, this node should
# be a "root node". The filtering for this has already been made, so
# using the ids dictionary means this check is constant time
@@ -154,7 +150,7 @@ class CMSChangeList(ChangeList):
page.menu_level = 0
root_pages.append(page)
if page.parent_id:
page.get_cached_ancestors(ascending=True)
page.get_cached_ancestors()
else:
page.ancestors_ascending = []
+7 -6
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from django.contrib.admin.views.decorators import staff_member_required
from django.http import Http404, HttpResponse
from django.shortcuts import get_object_or_404, render_to_response
from django.shortcuts import get_object_or_404, render
from cms.models import Page
from cms.utils import get_cms_setting
@@ -14,17 +14,18 @@ def get_copy_dialog(request, page_id):
if not get_cms_setting('PERMISSION'):
return HttpResponse('')
target_id = request.GET.get('target', False) or request.POST.get('target', False)
callback = request.GET.get('callback', False) or request.POST.get('callback', False)
page = get_object_or_404(Page, pk=page_id)
target = get_object_or_404(Page, pk=request.REQUEST['target'])
target = get_object_or_404(Page, pk=target_id)
if not page.has_change_permission(request) or \
not target.has_add_permission(request):
if not page.has_change_permission(request) or not target.has_add_permission(request):
raise Http404
context = {
'dialog_id': 'dialog-copy',
'form': PermissionForm(), # class needs to be instantiated
'callback': request.REQUEST['callback'],
'callback': callback,
}
return render_to_response("admin/cms/page/tree/copy_premissions.html", context)
return render(request, "admin/cms/page/tree/copy_premissions.html", context)
+36 -45
View File
@@ -1,11 +1,15 @@
# -*- coding: utf-8 -*-
from django import forms
from django.contrib.auth import get_user_model, get_permission_codename
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site
from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.db.models.fields import BooleanField
from django.forms.util import ErrorList
try:
from django.forms.utils import ErrorList
except ImportError:
from django.forms.util import ErrorList
from django.forms.widgets import HiddenInput
from django.template.defaultfilters import slugify
from django.utils.encoding import force_text
@@ -14,11 +18,11 @@ from django.utils.translation import ugettext_lazy as _, get_language
from cms.apphook_pool import apphook_pool
from cms.constants import PAGE_TYPES_ID
from cms.forms.widgets import UserSelectAdminWidget, AppHookSelect, ApplicationConfigSelect
from cms.models import Page, PagePermission, PageUser, ACCESS_PAGE, PageUserGroup, Title, EmptyTitle
from cms.utils.compat.dj import get_user_model, force_unicode
from cms.models import (Page, PagePermission, PageUser, ACCESS_PAGE, PageUserGroup, Title,
EmptyTitle, GlobalPagePermission)
from cms.utils.compat.forms import UserCreationForm
from cms.utils.conf import get_cms_setting
from cms.utils.i18n import get_language_tuple, get_language_list
from cms.utils.i18n import get_language_tuple
from cms.utils.mail import mail_page_user_change
from cms.utils.page import is_valid_page_slug
from cms.utils.page_resolver import is_valid_url
@@ -28,9 +32,9 @@ from cms.utils.permissions import (get_current_user, get_subordinate_users,
from menus.menu_pool import menu_pool
def get_permission_acessor(obj):
def get_permission_accessor(obj):
User = get_user_model()
if isinstance(obj, (PageUser, User,)):
rel_name = 'user_permissions'
else:
@@ -48,17 +52,17 @@ def save_permissions(data, obj):
if not obj.pk:
# save obj, otherwise we can't assign permissions to him
obj.save()
permission_acessor = get_permission_acessor(obj)
permission_accessor = get_permission_accessor(obj)
for model, name in models:
content_type = ContentType.objects.get_for_model(model)
for t in ('add', 'change', 'delete'):
# add permission `t` to model `model`
codename = getattr(model._meta, 'get_%s_permission' % t)()
for key in ('add', 'change', 'delete'):
# add permission `key` for model `model`
codename = get_permission_codename(key, model._meta)
permission = Permission.objects.get(content_type=content_type, codename=codename)
if data.get('can_%s_%s' % (t, name), None):
permission_acessor.add(permission)
if data.get('can_%s_%s' % (key, name), None):
permission_accessor.add(permission)
else:
permission_acessor.remove(permission)
permission_accessor.remove(permission)
class PageForm(forms.ModelForm):
@@ -113,22 +117,14 @@ class PageForm(forms.ModelForm):
def clean(self):
cleaned_data = self.cleaned_data
slug = cleaned_data.get('slug', '')
page = self.instance
lang = cleaned_data.get('language', None)
# No language, can not go further, but validation failed already
if not lang:
return cleaned_data
if 'parent' not in cleaned_data:
cleaned_data['parent'] = None
parent = cleaned_data.get('parent', None)
try:
site = self.cleaned_data.get('site', Site.objects.get_current())
except Site.DoesNotExist:
raise ValidationError("No site found for current settings.")
site = self.cleaned_data.get('site', Site.objects.get_current())
if parent and parent.site != site:
raise ValidationError("Site doesn't match the parent's page site")
@@ -154,7 +150,7 @@ class PageForm(forms.ModelForm):
if hasattr(exc, 'messages'):
errors = exc.messages
else:
errors = [force_unicode(exc.message)]
errors = [force_text(exc.message)]
self._errors['slug'] = ErrorList(errors)
return cleaned_data
@@ -164,12 +160,6 @@ class PageForm(forms.ModelForm):
raise ValidationError(_("Slug must not be empty."))
return slug
def clean_language(self):
language = self.cleaned_data['language']
if not language in get_language_list():
raise ValidationError("Given language does not match language settings.")
return language
class PublicationDatesForm(forms.ModelForm):
language = forms.ChoiceField(label=_("Language"), choices=get_language_tuple(),
@@ -399,10 +389,10 @@ class PagePermissionInlineAdminForm(forms.ModelForm):
"""
Page permission inline admin form used in inline admin. Required, because
user and group queryset must be changed. User can see only users on the same
level or under him in choosen page tree, and users which were created by him,
level or under him in choosen page tree, and users which were created by him,
but aren't assigned to higher page level than current user.
"""
page = forms.ModelChoiceField(Page, label=_('user'), widget=HiddenInput(), required=True)
page = forms.ModelChoiceField(Page.objects.all(), label=_('user'), widget=HiddenInput(), required=True)
def __init__(self, *args, **kwargs):
super(PagePermissionInlineAdminForm, self).__init__(*args, **kwargs)
@@ -458,13 +448,12 @@ class PagePermissionInlineAdminForm(forms.ModelForm):
continue
name = field.name
self.cleaned_data[name] = self.cleaned_data.get(name, False)
can_add = self.cleaned_data['can_add']
can_edit = self.cleaned_data['can_change']
# check if access for childrens, or descendants is granted
if can_add and self.cleaned_data['grant_on'] == ACCESS_PAGE:
# this is a missconfiguration - user can add/move page to current
# page but after he does this, he will not have permissions to
# page but after he does this, he will not have permissions to
# access this page anymore, so avoid this
raise forms.ValidationError(_("Add page permission requires also "
"access to children, or descendants, otherwise added page "
@@ -494,6 +483,7 @@ class PagePermissionInlineAdminForm(forms.ModelForm):
return instance
class Meta:
fields = '__all__'
model = PagePermission
@@ -502,7 +492,7 @@ class ViewRestrictionInlineAdminForm(PagePermissionInlineAdminForm):
def clean_can_view(self):
self.cleaned_data["can_view"] = True
return self.cleaned_data
return True
class GlobalPagePermissionAdminForm(forms.ModelForm):
@@ -512,6 +502,10 @@ class GlobalPagePermissionAdminForm(forms.ModelForm):
raise forms.ValidationError(_('Please select user or group first.'))
return self.cleaned_data
class Meta:
fields = '__all__'
model = GlobalPagePermission
class GenericCmsPermissionForm(forms.ModelForm):
"""Generic form for User & Grup permissions in cms
@@ -535,14 +529,14 @@ class GenericCmsPermissionForm(forms.ModelForm):
"""Read out permissions from permission system.
"""
initials = {}
permission_acessor = get_permission_acessor(obj)
permission_accessor = get_permission_accessor(obj)
for model in (Page, PageUser, PagePermission):
name = model.__name__.lower()
content_type = ContentType.objects.get_for_model(model)
permissions = permission_acessor.filter(content_type=content_type).values_list('codename', flat=True)
for t in ('add', 'change', 'delete'):
codename = getattr(model._meta, 'get_%s_permission' % t)()
initials['can_%s_%s' % (t, name)] = codename in permissions
permissions = permission_accessor.filter(content_type=content_type).values_list('codename', flat=True)
for key in ('add', 'change', 'delete'):
codename = get_permission_codename(key, model._meta)
initials['can_%s_%s' % (key, name)] = codename in permissions
return initials
@@ -552,6 +546,7 @@ class PageUserForm(UserCreationForm, GenericCmsPermissionForm):
'Send email notification to user about username or password change. Requires user email.'))
class Meta:
fields = '__all__'
model = PageUser
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
@@ -606,7 +601,7 @@ class PageUserForm(UserCreationForm, GenericCmsPermissionForm):
return cleaned_data
def save(self, commit=True):
"""Create user, assign him to staff users, and create permissions for
"""Create user, assign him to staff users, and create permissions for
him if required. Also assigns creator to user.
"""
Super = self._password_change and PageUserForm or UserCreationForm
@@ -644,15 +639,11 @@ class PageUserGroupForm(GenericCmsPermissionForm):
def save(self, commit=True):
group = super(GenericCmsPermissionForm, self).save(commit=False)
created = not bool(group.pk)
# assign creator to user
if created:
group.created_by = get_current_user()
if commit:
group.save()
save_permissions(self.cleaned_data, group)
return group
+147 -234
View File
@@ -3,23 +3,33 @@ import copy
from functools import wraps
import json
import sys
from cms.utils.compat import DJANGO_1_7
import django
from django.contrib.admin.helpers import AdminForm
from django.conf import settings
from django.conf.urls import url
from django.contrib import admin, messages
from django.contrib.admin.models import LogEntry, CHANGE
from django.contrib.admin.options import IncorrectLookupParameters
from django.contrib.admin.util import get_deleted_objects
try:
from django.contrib.admin.utils import get_deleted_objects
except ImportError:
from django.contrib.admin.util import get_deleted_objects
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site, get_current_site
from django.contrib.sites.models import Site
try:
from django.contrib.sites.shortcuts import get_current_site
except ImportError:
from django.contrib.sites.models import get_current_site
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist, ValidationError
from django.db import router
from django.db import router, transaction
from django.db.models import Q
from django.http import HttpResponseRedirect, HttpResponse, Http404, HttpResponseBadRequest, HttpResponseForbidden
from django.shortcuts import render_to_response, get_object_or_404
from django.template.context import RequestContext
from django.shortcuts import render, get_object_or_404
from django.template.defaultfilters import escape
from django.utils.encoding import force_text
from django.utils.six.moves.urllib.parse import unquote
from django.utils.translation import ugettext_lazy as _, get_language
from django.utils.decorators import method_decorator
from django.views.decorators.http import require_POST
@@ -39,14 +49,10 @@ from cms.toolbar_pool import toolbar_pool
from cms.utils import helpers, permissions, get_language_from_request, admin as admin_utils, copy_plugins
from cms.utils.i18n import get_language_list, get_language_tuple, get_language_object, force_language
from cms.utils.admin import jsonify_request
from cms.utils.compat import DJANGO_1_4
from cms.utils.compat.dj import force_unicode, is_installed
from cms.utils.compat.urls import unquote
from cms.utils.compat.dj import is_installed
from cms.utils.conf import get_cms_setting
from cms.utils.helpers import find_placeholder_relation
from cms.utils.helpers import find_placeholder_relation, current_site
from cms.utils.permissions import has_global_page_permission, has_generic_permission
from cms.utils.plugins import current_site
from cms.utils.transaction import wrap_transaction
from cms.utils.urlutils import add_url_parameters, admin_reverse
require_POST = method_decorator(require_POST)
@@ -106,14 +112,10 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
def get_urls(self):
"""Get the admin urls
"""
from django.conf.urls import patterns, url
info = "%s_%s" % (self.model._meta.app_label, self.model._meta.module_name)
info = "%s_%s" % (self.model._meta.app_label, self.model._meta.model_name)
pat = lambda regex, fn: url(regex, self.admin_site.admin_view(fn), name='%s_%s' % (info, fn.__name__))
url_patterns = patterns(
'',
url_patterns = [
pat(r'^([0-9]+)/advanced-settings/$', self.advanced),
pat(r'^([0-9]+)/dates/$', self.dates),
pat(r'^([0-9]+)/permission-settings/$', self.permissions),
@@ -123,7 +125,6 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
pat(r'^([0-9]+)/copy-language/$', self.copy_language),
pat(r'^([0-9]+)/dialog/copy/$', get_copy_dialog), # copy dialog
pat(r'^([0-9]+)/change-navigation/$', self.change_innavigation),
pat(r'^([0-9]+)/jsi18n/$', self.redirect_jsi18n),
pat(r'^([0-9]+)/permissions/$', self.get_permissions),
pat(r'^([0-9]+)/undo/$', self.undo),
pat(r'^([0-9]+)/redo/$', self.redo),
@@ -137,7 +138,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
pat(r'^add-page-type/$', self.add_page_type),
pat(r'^published-pages/$', self.get_published_pagelist),
url(r'^resolve/$', self.resolve, name="cms_page_resolve"),
)
]
if plugin_pool.get_all_plugins():
url_patterns += plugin_pool.get_patterns()
@@ -145,9 +146,6 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
url_patterns += super(PageAdmin, self).get_urls()
return url_patterns
def redirect_jsi18n(self, request):
return HttpResponseRedirect(admin_reverse('jsi18n'))
def get_revision_instances(self, request, object):
"""Returns all the instances to be used in the object's revision."""
if isinstance(object, Title):
@@ -174,32 +172,39 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
Move the page in the tree if necessary and save every placeholder
Content object.
"""
from cms.extensions import extension_pool
target = request.GET.get('target', None)
position = request.GET.get('position', None)
if 'recover' in request.path_info:
pk = obj.pk
if obj.parent_id:
parent = Page.objects.get(pk=obj.parent_id)
try:
parent = Page.objects.get(pk=obj.parent_id)
except Page.DoesNotExist:
parent = None
else:
parent = None
obj.lft = 0
obj.rght = 0
obj.tree_id = 0
obj.level = 0
obj.pk = None
obj.insert_at(parent, save=False)
obj.pk = pk
obj.save(no_signals=True)
obj.path = None
obj.numchild = 0
obj.depth = 0
if parent:
saved_obj = parent.add_child(instance=obj)
else:
saved_obj = obj.add_root(instance=obj)
tmp_pk = saved_obj.pk
saved_obj.pk = pk
Page.objects.get(pk=tmp_pk).delete()
saved_obj.save(no_signals=True)
else:
if 'history' in request.path_info:
old_obj = Page.objects.get(pk=obj.pk)
obj.level = old_obj.level
obj.depth = old_obj.depth
obj.parent_id = old_obj.parent_id
obj.rght = old_obj.rght
obj.lft = old_obj.lft
obj.tree_id = old_obj.tree_id
obj.path = old_obj.path
obj.numchild = old_obj.numchild
new = False
if not obj.pk:
new = True
@@ -214,21 +219,27 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
except self.model.DoesNotExist:
pass
else:
obj.move_to(target, position)
if position == 'last-child' or position == 'first-child':
obj.parent_id = target.pk
else:
obj.parent_id = target.parent_id
obj.save()
obj = obj.move(target, pos=position)
page_type_id = form.cleaned_data.get('page_type')
copy_target_id = request.GET.get('copy_target')
copy_target = None
if copy_target_id or page_type_id:
if page_type_id:
copy_target_id = page_type_id
copy_target = Page.objects.get(pk=copy_target_id)
if not copy_target.has_view_permission(request):
raise PermissionDenied()
obj = Page.objects.get(pk=obj.pk) #mptt reload
obj = obj.reload()
copy_target._copy_attributes(obj, clean=True)
obj.save()
for lang in copy_target.languages.split(','):
for lang in copy_target.get_languages():
copy_target._copy_contents(obj, lang)
if not 'permission' in request.path_info:
if 'permission' not in request.path_info:
language = form.cleaned_data['language']
Title.objects.set_or_create(
request,
@@ -236,6 +247,8 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
form,
language,
)
if copy_target:
extension_pool.copy_extensions(copy_target, obj)
# is it home? publish it right away
if new and Page.objects.filter(site_id=obj.site_id).count() == 1:
obj.publish(language)
@@ -349,12 +362,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
return self.change_view(request, object_id, extra_context={'show_permissions': True, 'title': _("Change Permissions")})
def get_inline_instances(self, request, obj=None):
if DJANGO_1_4:
inlines = super(PageAdmin, self).get_inline_instances(request)
if hasattr(self, '_current_page'):
obj = self._current_page
else:
inlines = super(PageAdmin, self).get_inline_instances(request, obj)
inlines = super(PageAdmin, self).get_inline_instances(request, obj)
if get_cms_setting('PERMISSION') and obj:
filtered_inlines = []
for inline in inlines:
@@ -435,12 +443,6 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
extra_context.update(self.get_unihandecode_context(tab_language))
# get_inline_instances will need access to 'obj' so that it can
# determine if current user has enough rights to see PagePermissionInlineAdmin
# because in django versions <1.5 get_inline_instances doesn't receive 'obj'
# as a parameter, the workaround is to set it as an attribute...
if DJANGO_1_4:
self._current_page = obj
response = super(PageAdmin, self).change_view(
request, object_id, form_url=form_url, extra_context=extra_context)
if tab_language and response.status_code == 302 and response._headers['location'][1] == request.path_info:
@@ -603,7 +605,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
def post_add_plugin(self, request, placeholder, plugin):
if is_installed('reversion') and placeholder.page:
plugin_name = force_unicode(plugin_pool.get_plugin(plugin.plugin_type).name)
plugin_name = force_text(plugin_pool.get_plugin(plugin.plugin_type).name)
message = _(u"%(plugin_name)s plugin added to %(placeholder)s") % {
'plugin_name': plugin_name, 'placeholder': placeholder}
self.cleanup_history(placeholder.page)
@@ -621,7 +623,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
if page:
# if reversion is installed, save version of the page plugins
if is_installed('reversion') and page:
plugin_name = force_unicode(plugin_pool.get_plugin(plugin.plugin_type).name)
plugin_name = force_text(plugin_pool.get_plugin(plugin.plugin_type).name)
message = _(
u"%(plugin_name)s plugin edited at position %(position)s in %(placeholder)s") % {
'plugin_name': plugin_name,
@@ -638,7 +640,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
helpers.make_revision_with_plugins(page, request.user, _(u"Plugins were moved"))
def post_delete_plugin(self, request, plugin):
plugin_name = force_unicode(plugin_pool.get_plugin(plugin.plugin_type).name)
plugin_name = force_text(plugin_pool.get_plugin(plugin.plugin_type).name)
page = plugin.placeholder.page
if page:
page.save()
@@ -656,7 +658,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
if page:
page.save()
comment = _('All plugins in the placeholder "%(name)s" were deleted.') % {
'name': force_unicode(placeholder)
'name': force_text(placeholder)
}
if is_installed('reversion'):
self.cleanup_history(page)
@@ -674,7 +676,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
opts = self.model._meta
app_label = opts.app_label
if not self.has_change_permission(request, None):
return HttpResponseForbidden(force_unicode(_("You do not have permission to change pages.")))
return HttpResponseForbidden(force_text(_("You do not have permission to change pages.")))
try:
cl = CMSChangeList(request, self.model, self.list_display, self.list_display_links, self.list_filter,
self.date_hierarchy, self.search_fields, self.list_select_related, self.list_per_page,
@@ -686,7 +688,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
# the 'invalid=1' parameter was already in the query string, something
# is screwed up with the database, so display an error page.
if ERROR_FLAG in request.GET.keys():
return render_to_response('admin/invalid_setup.html', {'title': _('Database error')})
return render(request, 'admin/invalid_setup.html', {'title': _('Database error')})
return HttpResponseRedirect(request.path_info + '?' + ERROR_FLAG + '=1')
cl.set_items(request)
@@ -729,11 +731,11 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
context['has_recover_permission'] = self.has_recover_permission(request)
context['has_change_permission'] = self.has_change_permission(request)
context.update(extra_context or {})
return render_to_response(self.change_list_template or [
return render(request, self.change_list_template or [
'admin/%s/%s/change_list.html' % (app_label, opts.object_name.lower()),
'admin/%s/change_list.html' % app_label,
'admin/change_list.html'
], context, context_instance=RequestContext(request))
], context)
def recoverlist_view(self, request, extra_context=None):
if not self.has_recover_permission(request):
@@ -780,133 +782,38 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
def undo(self, request, object_id):
if not is_installed('reversion'):
return HttpResponseBadRequest('django reversion not installed')
from reversion.models import Revision
from cms.utils.page_resolver import is_valid_url
import reversion
page = get_object_or_404(Page, pk=object_id)
old_titles = list(page.title_set.all())
if not page.publisher_is_draft:
page = page.publisher_draft
if not page.has_change_permission(request):
return HttpResponseForbidden(force_unicode(_("You do not have permission to change this page")))
versions = reversion.get_for_object(page)
if page.revision_id:
current_revision = Revision.objects.get(pk=page.revision_id)
else:
try:
current_version = versions[0]
except IndexError:
return HttpResponseBadRequest("no current revision found")
current_revision = current_version.revision
return HttpResponseForbidden(force_text(_("You do not have permission to change this page")))
try:
previous_version = versions.filter(revision__pk__lt=current_revision.pk)[0]
except IndexError:
return HttpResponseBadRequest("no previous revision found")
previous_revision = previous_version.revision
# clear all plugins
placeholders = page.placeholders.all()
placeholder_ids = []
for placeholder in placeholders:
placeholder_ids.append(placeholder.pk)
plugins = CMSPlugin.objects.filter(placeholder__in=placeholder_ids).order_by('-level')
for plugin in plugins:
plugin._no_reorder = True
plugin.delete()
# TODO: delete placeholders instead of finding duplicates for 3.1
#page.placeholders.all().delete()
reverted, clean = page.undo()
if not clean:
messages.error(request, _("Page reverted but slug stays the same because of url collisions."))
except IndexError as e:
return HttpResponseBadRequest(e.message)
previous_revision.revert(True)
rev_page = get_object_or_404(Page, pk=page.pk)
rev_page.revision_id = previous_revision.pk
rev_page.publisher_public_id = page.publisher_public_id
rev_page.save()
new_placeholders = rev_page.placeholders.all()
slots = {}
for new_ph in new_placeholders:
if not new_ph.slot in slots:
slots[new_ph.slot] = new_ph
else:
if new_ph in placeholder_ids:
new_ph.delete()
elif slots[new_ph.slot] in placeholder_ids:
slots[new_ph.slot].delete()
new_titles = rev_page.title_set.all()
for title in new_titles:
try:
is_valid_url(title.path, rev_page)
except ValidationError:
for old_title in old_titles:
if old_title.language == title.language:
title.slug = old_title.slug
title.save()
messages.error(request, _("Page reverted but slug stays the same because of url collisions."))
return HttpResponse("ok")
@require_POST
def redo(self, request, object_id):
if not is_installed('reversion'):
return HttpResponseBadRequest('django reversion not installed')
from reversion.models import Revision
import reversion
from cms.utils.page_resolver import is_valid_url
page = get_object_or_404(Page, pk=object_id)
old_titles = list(page.title_set.all())
if not page.publisher_is_draft:
page = page.publisher_draft
if not page.has_change_permission(request):
return HttpResponseForbidden(force_unicode(_("You do not have permission to change this page")))
versions = reversion.get_for_object(page)
if page.revision_id:
current_revision = Revision.objects.get(pk=page.revision_id)
else:
try:
current_version = versions[0]
except IndexError:
return HttpResponseBadRequest("no current revision found")
current_revision = current_version.revision
return HttpResponseForbidden(force_text(_("You do not have permission to change this page")))
try:
previous_version = versions.filter(revision__pk__gt=current_revision.pk).order_by('pk')[0]
except IndexError:
return HttpResponseBadRequest("no next revision found")
next_revision = previous_version.revision
# clear all plugins
placeholders = page.placeholders.all()
placeholder_ids = []
for placeholder in placeholders:
placeholder_ids.append(placeholder.pk)
plugins = CMSPlugin.objects.filter(placeholder__in=placeholder_ids).order_by('-level')
for plugin in plugins:
plugin._no_reorder = True
plugin.delete()
# TODO: 3.1 remove the placeholder matching from below and just delete them
#page.placeholders.all().delete()
next_revision.revert(True)
rev_page = get_object_or_404(Page, pk=page.pk)
rev_page.revision_id = next_revision.pk
rev_page.publisher_public_id = page.publisher_public_id
rev_page.save()
new_placeholders = rev_page.placeholders.all()
slots = {}
for new_ph in new_placeholders:
if not new_ph.slot in slots:
slots[new_ph.slot] = new_ph
else:
if new_ph in placeholder_ids:
new_ph.delete()
elif slots[new_ph.slot] in placeholder_ids:
slots[new_ph.slot].delete()
new_titles = rev_page.title_set.all()
for title in new_titles:
try:
is_valid_url(title.path, rev_page)
except ValidationError:
for old_title in old_titles:
if old_title.language == title.language:
title.slug = old_title.slug
title.save()
messages.error(request, _("Page reverted but slug stays the same because of url collisions."))
reverted, clean = page.redo()
if not clean:
messages.error(request, _("Page reverted but slug stays the same because of url collisions."))
except IndexError as e:
return HttpResponseBadRequest(e.message)
return HttpResponse("ok")
@require_POST
@@ -914,11 +821,11 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
def change_template(self, request, object_id):
page = get_object_or_404(Page, pk=object_id)
if not page.has_change_permission(request):
return HttpResponseForbidden(force_unicode(_("You do not have permission to change the template")))
return HttpResponseForbidden(force_text(_("You do not have permission to change the template")))
to_template = request.POST.get("template", None)
if to_template not in dict(get_cms_setting('TEMPLATES')):
return HttpResponseBadRequest(force_unicode(_("Template not valid")))
return HttpResponseBadRequest(force_text(_("Template not valid")))
page.template = to_template
page.save()
@@ -926,10 +833,10 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
message = _("Template changed to %s") % dict(get_cms_setting('TEMPLATES'))[to_template]
self.cleanup_history(page)
helpers.make_revision_with_plugins(page, request.user, message)
return HttpResponse(force_unicode(_("The template was successfully changed")))
return HttpResponse(force_text(_("The template was successfully changed")))
@require_POST
@wrap_transaction
@transaction.atomic
def move_page(self, request, page_id, extra_context=None):
"""
Move the page to the requested target, at the given position
@@ -949,7 +856,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
if not page.has_move_page_permission(request) or \
not target.has_add_permission(request):
return jsonify_request(
HttpResponseForbidden(force_unicode(_("Error! You don't have permissions to move this page. Please reload the page"))))
HttpResponseForbidden(force_text(_("Error! You don't have permissions to move this page. Please reload the page"))))
# move page
page.move_page(target, position)
if is_installed('reversion'):
@@ -988,24 +895,24 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
'page': page,
'permission_set': permission_set,
}
return render_to_response('admin/cms/page/permissions.html', context)
return render(request, 'admin/cms/page/permissions.html', context)
@require_POST
@wrap_transaction
@transaction.atomic
def copy_language(self, request, page_id):
with create_revision():
source_language = request.POST.get('source_language')
target_language = request.POST.get('target_language')
page = Page.objects.get(pk=page_id)
placeholders = page.placeholders.all()
placeholders = page.get_placeholders()
if not target_language or not target_language in get_language_list():
return HttpResponseBadRequest(force_unicode(_("Language must be set to a supported language!")))
return HttpResponseBadRequest(force_text(_("Language must be set to a supported language!")))
for placeholder in placeholders:
plugins = list(
placeholder.cmsplugin_set.filter(language=source_language).order_by('tree_id', 'level', 'position'))
placeholder.cmsplugin_set.filter(language=source_language).order_by('path'))
if not self.has_copy_plugin_permission(request, placeholder, placeholder, plugins):
return HttpResponseForbidden(force_unicode(_('You do not have permission to copy these plugins.')))
return HttpResponseForbidden(force_text(_('You do not have permission to copy these plugins.')))
copy_plugins.copy_plugins_to(plugins, placeholder, target_language)
if page and is_installed('reversion'):
message = _(u"Copied plugins from %(source_language)s to %(target_language)s") % {
@@ -1015,7 +922,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
return HttpResponse("ok")
@require_POST
@wrap_transaction
@transaction.atomic
def copy_page(self, request, page_id, extra_context=None):
"""
Copy the page and all its plugins and descendants to the requested target, at the given position
@@ -1034,11 +941,13 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
site = Site.objects.get(pk=site)
except (ObjectDoesNotExist, AssertionError):
return HttpResponse("error")
#context.update({'error': _('Page could not been moved.')})
else:
try:
permissions = request.GET.get('copy_permissions', False)
if not permissions:
permissions = request.POST.get('copy_permissions', False)
kwargs = {
'copy_permissions': request.REQUEST.get('copy_permissions', False),
'copy_permissions': permissions,
}
page.copy_page(target, site, position, **kwargs)
return jsonify_request(HttpResponse("ok"))
@@ -1049,7 +958,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
return HttpResponseRedirect('../../')
@require_POST
@wrap_transaction
@transaction.atomic
@create_revision()
def publish_page(self, request, page_id, language):
try:
@@ -1060,13 +969,13 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
all_published = True
if page:
if not page.has_publish_permission(request):
return HttpResponseForbidden(force_unicode(_("You do not have permission to publish this page")))
return HttpResponseForbidden(force_text(_("You do not have permission to publish this page")))
published = page.publish(language)
if not published:
all_published = False
statics = request.GET.get('statics', '')
if not statics and not page:
return Http404("No page or stack found for publishing.")
raise Http404("No page or stack found for publishing.")
if statics:
static_ids = statics .split(',')
for pk in static_ids:
@@ -1096,7 +1005,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
self.cleanup_history(page, publish=True)
helpers.make_revision_with_plugins(page, request.user, PUBLISH_COMMENT)
# create a new publish reversion
if 'node' in request.REQUEST:
if 'node' in request.GET or 'node' in request.POST:
# if request comes from tree..
return admin_utils.render_admin_menu_item(request, page)
@@ -1150,7 +1059,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
deleted.append(revision.pk)
@require_POST
@wrap_transaction
@transaction.atomic
def unpublish(self, request, page_id, language):
"""
Publish or unpublish a language of a page
@@ -1158,9 +1067,9 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
site = Site.objects.get_current()
page = get_object_or_404(Page, pk=page_id)
if not page.has_publish_permission(request):
return HttpResponseForbidden(force_unicode(_("You do not have permission to unpublish this page")))
return HttpResponseForbidden(force_text(_("You do not have permission to unpublish this page")))
if not page.publisher_public_id:
return HttpResponseForbidden(force_unicode(_("This page was never published")))
return HttpResponseForbidden(force_text(_("This page was never published")))
try:
page.unpublish(language)
message = _('The %(language)s page "%(page)s" was successfully unpublished') % {
@@ -1186,25 +1095,24 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
return HttpResponseRedirect(path)
@require_POST
@wrap_transaction
@transaction.atomic
def revert_page(self, request, page_id, language):
page = get_object_or_404(Page, id=page_id)
# ensure user has permissions to publish this page
if not page.has_change_permission(request):
return HttpResponseForbidden(force_unicode(_("You do not have permission to change this page")))
return HttpResponseForbidden(force_text(_("You do not have permission to change this page")))
page.revert(language)
messages.info(request, _('The page "%s" was successfully reverted.') % page)
if 'node' in request.REQUEST:
if 'node' in request.GET or 'node' in request.POST:
# if request comes from tree..
return admin_utils.render_admin_menu_item(request, page)
referer = request.META.get('HTTP_REFERER', '')
path = '../../'
if admin_reverse('index') not in referer:
path = '%s?%s' % (referer.split('?')[0], get_cms_setting('CMS_TOOLBAR_URL__EDIT_OFF'))
# TODO: This should never fail, but it may be a POF
path = page.get_absolute_url(language=language)
path = '%s?%s' % (path, get_cms_setting('CMS_TOOLBAR_URL__EDIT_OFF'))
return HttpResponseRedirect(path)
@create_revision()
@@ -1220,7 +1128,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
pluginopts = CMSPlugin._meta
try:
obj = self.queryset(request).get(pk=unquote(object_id))
obj = self.get_queryset(request).get(pk=unquote(object_id))
except self.model.DoesNotExist:
# Don't raise Http404 just yet, because we haven't checked
# permissions yet. We don't want an unauthenticated user to be able
@@ -1228,12 +1136,12 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
obj = None
if not self.has_delete_permission(request, obj):
return HttpResponseForbidden(force_unicode(_("You do not have permission to change this page")))
return HttpResponseForbidden(force_text(_("You do not have permission to change this page")))
if obj is None:
raise Http404(
_('%(name)s object with primary key %(key)r does not exist.') % {
'name': force_unicode(opts.verbose_name),
'name': force_text(opts.verbose_name),
'key': escape(object_id)
})
@@ -1249,16 +1157,29 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
'user': request.user,
'using': using
}
deleted_objects, perms_needed = get_deleted_objects(
[titleobj],
titleopts,
**kwargs
)[:2]
to_delete_plugins, perms_needed_plugins = get_deleted_objects(
saved_plugins,
pluginopts,
**kwargs
)[:2]
if DJANGO_1_7:
deleted_objects, perms_needed = get_deleted_objects(
[titleobj],
titleopts,
**kwargs
)[:2]
to_delete_plugins, perms_needed_plugins = get_deleted_objects(
saved_plugins,
pluginopts,
**kwargs
)[:2]
else:
deleted_objects, __, perms_needed = get_deleted_objects(
[titleobj],
titleopts,
**kwargs
)[:3]
to_delete_plugins, __, perms_needed_plugins = get_deleted_objects(
saved_plugins,
pluginopts,
**kwargs
)[:3]
deleted_objects.append(to_delete_plugins)
perms_needed = set(list(perms_needed) + list(perms_needed_plugins))
@@ -1268,7 +1189,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
raise PermissionDenied
message = _('Title and plugins with language %(language)s was deleted') % {
'language': force_unicode(get_language_object(language)['name'])
'language': force_text(get_language_object(language)['name'])
}
self.log_change(request, titleobj, message)
messages.info(request, message)
@@ -1291,7 +1212,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
context = {
"title": _("Are you sure?"),
"object_name": force_unicode(titleopts.verbose_name),
"object_name": force_text(titleopts.verbose_name),
"object": titleobj,
"deleted_objects": deleted_objects,
"perms_lacking": perms_needed,
@@ -1300,12 +1221,12 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
"app_label": app_label,
}
context.update(extra_context or {})
context_instance = RequestContext(request, current_app=self.admin_site.name)
return render_to_response(self.delete_confirmation_template or [
request.current_app = self.admin_site.name
return render(request, self.delete_confirmation_template or [
"admin/%s/%s/delete_confirmation.html" % (app_label, titleopts.object_name.lower()),
"admin/%s/delete_confirmation.html" % app_label,
"admin/delete_confirmation.html"
], context, context_instance=context_instance)
], context)
def preview_page(self, request, object_id, language):
"""Redirecting preview function based on draft_id
@@ -1331,7 +1252,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
page.toggle_in_navigation()
language = request.GET.get('language') or get_language_from_request(request)
return admin_utils.render_admin_menu_item(request, page, language=language)
return HttpResponseForbidden(force_unicode(_("You do not have permission to change this page's in_navigation status")))
return HttpResponseForbidden(force_text(_("You do not have permission to change this page's in_navigation status")))
def descendants(self, request, page_id, language):
"""
@@ -1362,10 +1283,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
def resolve(self, request):
if not request.user.is_staff:
if DJANGO_1_4:
return HttpResponse('/', mimetype='text/plain')
else:
return HttpResponse('/', content_type='text/plain')
return HttpResponse('/', content_type='text/plain')
obj = False
url = False
if request.session.get('cms_log_latest', False):
@@ -1379,14 +1297,14 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
# This is a test if the object url can be retrieved
# In case it can't, object it's not taken into account
try:
force_unicode(obj.get_absolute_url())
force_text(obj.get_absolute_url())
except:
obj = None
else:
obj = None
if not obj:
pk = request.REQUEST.get('pk')
full_model = request.REQUEST.get('model')
pk = request.GET.get('pk', False) or request.POST.get('pk', False)
full_model = request.GET.get('model') or request.POST.get('model', False)
if pk and full_model:
app_label, model = full_model.split('.')
if pk and app_label:
@@ -1396,11 +1314,11 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
except ctype.model_class().DoesNotExist:
obj = None
try:
force_unicode(obj.get_absolute_url())
force_text(obj.get_absolute_url())
except:
obj = None
if obj:
if not request.toolbar or not request.toolbar.edit_mode:
if not getattr(request, 'toolbar', False) or not getattr(request.toolbar, 'edit_mode', False):
if isinstance(obj, Page):
if obj.get_public_object():
url = obj.get_public_object().get_absolute_url()
@@ -1414,7 +1332,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
else:
url = obj.get_absolute_url()
if url:
return HttpResponse(force_unicode(url), content_type='text/plain')
return HttpResponse(force_text(url), content_type='text/plain')
return HttpResponse('', content_type='text/plain')
def lookup_allowed(self, key, *args, **kwargs):
@@ -1436,7 +1354,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
if not has_generic_permission(title.page.pk, request.user, "change",
title.page.site.pk):
return HttpResponseForbidden(force_unicode(_("You do not have permission to edit this page")))
return HttpResponseForbidden(force_text(_("You do not have permission to edit this page")))
class PageTitleForm(django.forms.ModelForm):
"""
@@ -1476,10 +1394,10 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
context.update({
'cancel': True,
})
return render_to_response('admin/cms/page/plugin/confirm_form.html', context, RequestContext(request))
return render(request, 'admin/cms/page/plugin/confirm_form.html', context)
if not cancel_clicked and request.method == 'POST' and saved_successfully:
return render_to_response('admin/cms/page/plugin/confirm_form.html', context, RequestContext(request))
return render_to_response('admin/cms/page/plugin/change_form.html', context, RequestContext(request))
return render(request, 'admin/cms/page/plugin/confirm_form.html', context)
return render(request, 'admin/cms/page/plugin/change_form.html', context)
def get_published_pagelist(self, *args, **kwargs):
"""
@@ -1507,12 +1425,7 @@ class PageAdmin(PlaceholderAdminMixin, ModelAdmin):
'redirect_url': page.get_absolute_url(language=language_code)
}
)
if DJANGO_1_4:
return HttpResponse(json.dumps(results), mimetype='application/json')
else:
return HttpResponse(json.dumps(results), content_type='application/json')
return HttpResponse(json.dumps(results), content_type='application/json')
else:
return HttpResponseForbidden()
+27 -17
View File
@@ -2,13 +2,14 @@
from copy import deepcopy
from django.contrib import admin
from django.contrib.admin import site
from django.contrib.auth import get_user_model, get_permission_codename
from django.contrib.auth.admin import UserAdmin
from django.utils.translation import ugettext as _
from django.db import OperationalError
from django.utils.translation import ugettext, ugettext_lazy as _
from cms.admin.forms import GlobalPagePermissionAdminForm, PagePermissionInlineAdminForm, ViewRestrictionInlineAdminForm
from cms.exceptions import NoPermissionsException
from cms.models import Page, PagePermission, GlobalPagePermission, PageUser
from cms.utils.compat.dj import get_user_model
from cms.utils.conf import get_cms_setting
from cms.utils.helpers import classproperty
from cms.utils.permissions import get_user_permission_level
@@ -37,14 +38,23 @@ class PagePermissionInlineAdmin(TabularInline):
def raw_id_fields(cls):
# Dynamically set raw_id_fields based on settings
threshold = get_cms_setting('RAW_ID_USERS')
if threshold and get_user_model().objects.count() > threshold:
return ['user']
return []
def queryset(self, request):
# Given a fresh django-cms install and a django settings with the
# CMS_RAW_ID_USERS = CMS_PERMISSION = True
# django throws an OperationalError when running
# ./manage migrate
# because auth_user doesn't exists yet
try:
threshold = threshold and get_user_model().objects.count() > threshold
except OperationalError:
threshold = False
return ['user'] if threshold else []
def get_queryset(self, request):
"""
Queryset change, so user with global change permissions can see
all permissions. Otherwise can user see only permissions for
all permissions. Otherwise can user see only permissions for
peoples which are under him (he can't see his permissions, because
this will lead to violation, when he can add more power to itself)
"""
@@ -77,7 +87,7 @@ class PagePermissionInlineAdmin(TabularInline):
exclude.append('can_move_page')
formset_cls = super(PagePermissionInlineAdmin, self
).get_formset(request, obj=None, exclude=exclude, **kwargs)
qs = self.queryset(request)
qs = self.get_queryset(request)
if obj is not None:
qs = qs.filter(page=obj)
formset_cls._queryset = qs
@@ -102,13 +112,13 @@ class ViewRestrictionInlineAdmin(PagePermissionInlineAdmin):
flag, he can't change assign can_publish permissions.
"""
formset_cls = super(PagePermissionInlineAdmin, self).get_formset(request, obj, **kwargs)
qs = self.queryset(request)
qs = self.get_queryset(request)
if obj is not None:
qs = qs.filter(page=obj)
formset_cls._queryset = qs
return formset_cls
def queryset(self, request):
def get_queryset(self, request):
"""
Returns a QuerySet of all model instances that can be edited by the
admin site. This is used by changelist_view.
@@ -145,18 +155,18 @@ class GenericCmsPermissionAdmin(object):
"""
fieldsets = deepcopy(self.fieldsets)
perm_models = (
(Page, _('Page permissions')),
(PageUser, _('User & Group permissions')),
(PagePermission, _('Page permissions management')),
(Page, ugettext('Page permissions')),
(PageUser, ugettext('User & Group permissions')),
(PagePermission, ugettext('Page permissions management')),
)
for i, perm_model in enumerate(perm_models):
model, title = perm_model
opts, fields = model._meta, []
name = model.__name__.lower()
for t in ('add', 'change', 'delete'):
fn = getattr(opts, 'get_%s_permission' % t)
if request.user.has_perm(opts.app_label + '.' + fn()):
fields.append('can_%s_%s' % (t, name))
for key in ('add', 'change', 'delete'):
perm_code = '%s.%s' % (opts.app_label, get_permission_codename(key, opts))
if request.user.has_perm(perm_code):
fields.append('can_%s_%s' % (key, name))
if fields:
fieldsets.insert(2 + i, (title, {'fields': (fields,)}))
return fieldsets
+132 -159
View File
@@ -1,39 +1,51 @@
# -*- coding: utf-8 -*-
from cms.models.placeholderpluginmodel import PlaceholderReference
from cms.utils.urlutils import admin_reverse
from django.contrib.admin.helpers import AdminForm
from django.utils.decorators import method_decorator
import json
from django.conf import settings
from django.conf.urls import url
from django.contrib.admin.helpers import AdminForm
try:
from django.contrib.admin.utils import get_deleted_objects
except ImportError:
from django.contrib.admin.util import get_deleted_objects
from django.core.exceptions import PermissionDenied
from django.db import router, transaction
from django.http import (
HttpResponse,
HttpResponseBadRequest,
HttpResponseForbidden,
HttpResponseNotFound,
HttpResponseRedirect,
)
from django.shortcuts import get_object_or_404, render
from django.template.defaultfilters import force_escape, escapejs
from django.template.response import TemplateResponse
from django.utils.decorators import method_decorator
from django.utils.encoding import force_text
from django.utils.translation import ugettext as _
from django.views.decorators.clickjacking import xframe_options_sameorigin
from django.views.decorators.http import require_POST
from cms.constants import PLUGIN_COPY_ACTION, PLUGIN_MOVE_ACTION
from cms.exceptions import PluginLimitReached
from cms.models.placeholdermodel import Placeholder
from cms.models.placeholderpluginmodel import PlaceholderReference
from cms.models.pluginmodel import CMSPlugin
from cms.plugin_pool import plugin_pool
from cms.utils import get_cms_setting
from cms.utils.compat.dj import force_unicode
from cms.utils.plugins import requires_reload, has_reached_plugin_limit
from django.contrib.admin import ModelAdmin
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden, HttpResponseNotFound
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.template.defaultfilters import force_escape, escapejs
from django.utils.translation import ugettext as _
from django.conf import settings
from django.views.decorators.http import require_POST
import warnings
from django.template.response import TemplateResponse
from django.contrib.admin.util import get_deleted_objects
from django.core.exceptions import PermissionDenied
from django.db import router
from django.http import HttpResponseRedirect
from cms.utils import copy_plugins, permissions, get_language_from_request
from cms.utils.compat import DJANGO_1_4
from cms.utils import (
copy_plugins,
get_cms_setting,
get_language_from_request,
permissions,
)
from cms.utils.compat import DJANGO_1_7
from cms.utils.i18n import get_language_list
from cms.utils.transaction import wrap_transaction
from cms.utils.plugins import (
requires_reload,
has_reached_plugin_limit,
reorder_plugins
)
from cms.utils.urlutils import admin_reverse
class FrontendEditableAdminMixin(object):
@@ -43,16 +55,12 @@ class FrontendEditableAdminMixin(object):
"""
Register the url for the single field edit view
"""
from django.conf.urls import patterns, url
from cms.urls import SLUG_REGEXP
info = "%s_%s" % (self.model._meta.app_label, self.model._meta.module_name)
info = "%s_%s" % (self.model._meta.app_label, self.model._meta.model_name)
pat = lambda regex, fn: url(regex, self.admin_site.admin_view(fn), name='%s_%s' % (info, fn.__name__))
url_patterns = patterns(
'',
url_patterns = [
pat(r'edit-field/(%s)/([a-z\-]+)/$' % SLUG_REGEXP, self.edit_field),
)
]
return url_patterns + super(FrontendEditableAdminMixin, self).get_urls()
def _get_object_for_single_field(self, object_id, language):
@@ -73,16 +81,16 @@ class FrontendEditableAdminMixin(object):
if not fields:
context = {
'opts': opts,
'message': force_unicode(_("Field %s not found")) % raw_fields
'message': force_text(_("Field %s not found")) % raw_fields
}
return render_to_response('admin/cms/page/plugin/error_form.html', context, RequestContext(request))
return render(request, 'admin/cms/page/plugin/error_form.html', context)
if not request.user.has_perm("{0}.change_{1}".format(self.model._meta.app_label,
self.model._meta.module_name)):
self.model._meta.model_name)):
context = {
'opts': opts,
'message': force_unicode(_("You do not have permission to edit this item"))
'message': force_text(_("You do not have permission to edit this item"))
}
return render_to_response('admin/cms/page/plugin/error_form.html', context, RequestContext(request))
return render(request, 'admin/cms/page/plugin/error_form.html', context)
# Dinamically creates the form class with only `field_name` field
# enabled
form_class = self.get_form(request, obj, fields=fields)
@@ -116,10 +124,10 @@ class FrontendEditableAdminMixin(object):
context.update({
'cancel': True,
})
return render_to_response('admin/cms/page/plugin/confirm_form.html', context, RequestContext(request))
return render(request, 'admin/cms/page/plugin/confirm_form.html', context)
if not cancel_clicked and request.method == 'POST' and saved_successfully:
return render_to_response('admin/cms/page/plugin/confirm_form.html', context, RequestContext(request))
return render_to_response('admin/cms/page/plugin/change_form.html', context, RequestContext(request))
return render(request, 'admin/cms/page/plugin/confirm_form.html', context)
return render(request, 'admin/cms/page/plugin/change_form.html', context)
class PlaceholderAdminMixin(object):
@@ -127,21 +135,17 @@ class PlaceholderAdminMixin(object):
"""
Register the plugin specific urls (add/edit/copy/remove/move)
"""
from django.conf.urls import patterns, url
from cms.urls import SLUG_REGEXP
info = "%s_%s" % (self.model._meta.app_label, self.model._meta.module_name)
info = "%s_%s" % (self.model._meta.app_label, self.model._meta.model_name)
pat = lambda regex, fn: url(regex, self.admin_site.admin_view(fn), name='%s_%s' % (info, fn.__name__))
url_patterns = patterns(
'',
url_patterns = [
pat(r'copy-plugins/$', self.copy_plugins),
pat(r'add-plugin/$', self.add_plugin),
pat(r'edit-plugin/(%s)/$' % SLUG_REGEXP, self.edit_plugin),
pat(r'delete-plugin/(%s)/$' % SLUG_REGEXP, self.delete_plugin),
pat(r'clear-placeholder/(%s)/$' % SLUG_REGEXP, self.clear_placeholder),
pat(r'move-plugin/$', self.move_plugin),
)
]
return url_patterns + super(PlaceholderAdminMixin, self).get_urls()
def has_add_plugin_permission(self, request, placeholder, plugin_type):
@@ -219,20 +223,14 @@ class PlaceholderAdminMixin(object):
- plugin_language
- plugin_parent (optional)
"""
plugin_type = request.POST['plugin_type']
placeholder_id = request.POST.get('placeholder_id', None)
parent_id = request.POST.get('parent_id', None)
if parent_id:
warnings.warn("parent_id is deprecated and will be removed in 3.1, use plugin_parent instead",
DeprecationWarning)
if not parent_id:
parent_id = request.POST.get('plugin_parent', None)
placeholder = get_object_or_404(Placeholder, pk=placeholder_id)
if not self.has_add_plugin_permission(request, placeholder, plugin_type):
return HttpResponseForbidden(force_unicode(_('You do not have permission to add a plugin')))
parent = None
plugin_type = request.POST['plugin_type']
placeholder_id = request.POST.get('placeholder_id', None)
placeholder = get_object_or_404(Placeholder, pk=placeholder_id)
parent_id = request.POST.get('plugin_parent', None)
language = request.POST.get('plugin_language') or get_language_from_request(request)
if not self.has_add_plugin_permission(request, placeholder, plugin_type):
return HttpResponseForbidden(force_text(_('You do not have permission to add a plugin')))
try:
has_reached_plugin_limit(placeholder, plugin_type, language,
template=self.get_placeholder_template(request, placeholder))
@@ -240,7 +238,6 @@ class PlaceholderAdminMixin(object):
return HttpResponseBadRequest(er)
# page add-plugin
if not parent_id:
position = request.POST.get('plugin_order',
CMSPlugin.objects.filter(language=language, placeholder=placeholder).count())
# in-plugin add-plugin
@@ -254,35 +251,32 @@ class PlaceholderAdminMixin(object):
# Sanity check to make sure we're not getting bogus values from JavaScript:
if settings.USE_I18N:
if not language or not language in [lang[0] for lang in settings.LANGUAGES]:
return HttpResponseBadRequest(force_unicode(_("Language must be set to a supported language!")))
return HttpResponseBadRequest(force_text(_("Language must be set to a supported language!")))
if parent and parent.language != language:
return HttpResponseBadRequest(force_unicode(_("Parent plugin language must be same as language!")))
return HttpResponseBadRequest(force_text(_("Parent plugin language must be same as language!")))
else:
language = settings.LANGUAGE_CODE
plugin = CMSPlugin(language=language, plugin_type=plugin_type, position=position, placeholder=placeholder)
if parent:
plugin.position = CMSPlugin.objects.filter(parent=parent).count()
plugin.insert_at(parent, position='last-child', save=False)
plugin.parent_id = parent.pk
plugin.save()
self.post_add_plugin(request, placeholder, plugin)
response = {
'url': force_unicode(
admin_reverse("%s_%s_edit_plugin" % (self.model._meta.app_label, self.model._meta.module_name),
'url': force_text(
admin_reverse("%s_%s_edit_plugin" % (self.model._meta.app_label, self.model._meta.model_name),
args=[plugin.pk])),
'delete': force_unicode(
admin_reverse("%s_%s_delete_plugin" % (self.model._meta.app_label, self.model._meta.module_name),
'delete': force_text(
admin_reverse("%s_%s_delete_plugin" % (self.model._meta.app_label, self.model._meta.model_name),
args=[plugin.pk])),
'breadcrumb': plugin.get_breadcrumb(),
}
if DJANGO_1_4:
return HttpResponse(json.dumps(response), mimetype='application/json')
else:
return HttpResponse(json.dumps(response), content_type='application/json')
return HttpResponse(json.dumps(response), content_type='application/json')
@method_decorator(require_POST)
@xframe_options_sameorigin
@wrap_transaction
@transaction.atomic
def copy_plugins(self, request):
"""
POST request should have the following data:
@@ -303,7 +297,7 @@ class PlaceholderAdminMixin(object):
source_placeholder = get_object_or_404(Placeholder, pk=source_placeholder_id)
target_placeholder = get_object_or_404(Placeholder, pk=target_placeholder_id)
if not target_language or not target_language in get_language_list():
return HttpResponseBadRequest(force_unicode(_("Language must be set to a supported language!")))
return HttpResponseBadRequest(force_text(_("Language must be set to a supported language!")))
if source_plugin_id:
source_plugin = get_object_or_404(CMSPlugin, pk=source_plugin_id)
reload_required = requires_reload(PLUGIN_COPY_ACTION, [source_plugin])
@@ -313,16 +307,16 @@ class PlaceholderAdminMixin(object):
plugins = inst.placeholder_ref.get_plugins_list()
else:
plugins = list(
source_placeholder.cmsplugin_set.filter(tree_id=source_plugin.tree_id, lft__gte=source_plugin.lft,
rght__lte=source_plugin.rght).order_by('tree_id', 'level',
'position'))
source_placeholder.cmsplugin_set.filter(
path__startswith=source_plugin.path,
depth__gte=source_plugin.depth).order_by('path')
)
else:
plugins = list(
source_placeholder.cmsplugin_set.filter(language=source_language).order_by('tree_id', 'level',
'position'))
source_placeholder.cmsplugin_set.filter(language=source_language).order_by('path'))
reload_required = requires_reload(PLUGIN_COPY_ACTION, plugins)
if not self.has_copy_plugin_permission(request, source_placeholder, target_placeholder, plugins):
return HttpResponseForbidden(force_unicode(_('You do not have permission to copy these plugins.')))
return HttpResponseForbidden(force_text(_('You do not have permission to copy these plugins.')))
if target_placeholder.pk == request.toolbar.clipboard.pk and not source_plugin_id and not target_plugin_id:
# if we copy a whole placeholder to the clipboard create PlaceholderReference plugin instead and fill it
# the content of the source_placeholder.
@@ -336,43 +330,42 @@ class PlaceholderAdminMixin(object):
else:
copy_plugins.copy_plugins_to(plugins, target_placeholder, target_language, target_plugin_id)
plugin_list = CMSPlugin.objects.filter(language=target_language, placeholder=target_placeholder).order_by(
'tree_id', 'level', 'position')
'path')
reduced_list = []
for plugin in plugin_list:
reduced_list.append(
{
'id': plugin.pk, 'type': plugin.plugin_type, 'parent': plugin.parent_id,
'position': plugin.position, 'desc': force_unicode(plugin.get_short_description()),
'position': plugin.position, 'desc': force_text(plugin.get_short_description()),
'language': plugin.language, 'placeholder_id': plugin.placeholder_id
}
)
self.post_copy_plugins(request, source_placeholder, target_placeholder, plugins)
json_response = {'plugin_list': reduced_list, 'reload': reload_required}
if DJANGO_1_4:
return HttpResponse(json.dumps(json_response), mimetype='application/json')
else:
return HttpResponse(json.dumps(json_response), content_type='application/json')
return HttpResponse(json.dumps(json_response), content_type='application/json')
@xframe_options_sameorigin
def edit_plugin(self, request, plugin_id):
try:
plugin_id = int(plugin_id)
except ValueError:
return HttpResponseNotFound(force_unicode(_("Plugin not found")))
return HttpResponseNotFound(force_text(_("Plugin not found")))
cms_plugin = get_object_or_404(CMSPlugin.objects.select_related('placeholder'), pk=plugin_id)
instance, plugin_admin = cms_plugin.get_plugin_instance(self.admin_site)
if not self.has_change_plugin_permission(request, cms_plugin):
return HttpResponseForbidden(force_unicode(_("You do not have permission to edit this plugin")))
return HttpResponseForbidden(force_text(_("You do not have permission to edit this plugin")))
plugin_admin.cms_plugin_instance = cms_plugin
try:
plugin_admin.placeholder = cms_plugin.placeholder
except Placeholder.DoesNotExist:
pass
if request.method == "POST":
# set the continue flag, otherwise will plugin_admin make redirect to list
# view, which actually doesn't exists
request.POST['_continue'] = True
# set the continue flag, otherwise plugin_admin will make redirect
# to list view, which actually doesn't exists
mutable_post = request.POST.copy()
mutable_post['_continue'] = True
request.POST = mutable_post
if request.POST.get("_cancel", False):
# cancel button was clicked
context = {
@@ -387,15 +380,15 @@ class PlaceholderAdminMixin(object):
}
instance = cms_plugin.get_plugin_instance()[0]
if instance:
context['name'] = force_unicode(instance)
context['name'] = force_text(instance)
else:
# cancelled before any content was added to plugin
cms_plugin.delete()
context.update({
"deleted": True,
'name': force_unicode(cms_plugin),
'name': force_text(cms_plugin),
})
return render_to_response('admin/cms/page/plugin/confirm_form.html', context, RequestContext(request))
return render(request, 'admin/cms/page/plugin/confirm_form.html', context)
if not instance:
# instance doesn't exist, call add view
@@ -413,13 +406,13 @@ class PlaceholderAdminMixin(object):
'CMS_MEDIA_URL': get_cms_setting('MEDIA_URL'),
'plugin': saved_object,
'is_popup': True,
'name': force_unicode(saved_object),
'name': force_text(saved_object),
"type": saved_object.get_plugin_name(),
'plugin_id': plugin_id,
'icon': force_escape(saved_object.get_instance_icon_src()),
'alt': force_escape(saved_object.get_instance_icon_alt()),
}
return render_to_response('admin/cms/page/plugin/confirm_form.html', context, RequestContext(request))
return render(request, 'admin/cms/page/plugin/confirm_form.html', context)
return response
@method_decorator(require_POST)
@@ -446,79 +439,68 @@ class PlaceholderAdminMixin(object):
language = plugin.language
order = request.POST.getlist("plugin_order[]")
if not self.has_move_plugin_permission(request, plugin, placeholder):
return HttpResponseForbidden(force_unicode(_("You have no permission to move this plugin")))
if plugin.parent_id != parent_id:
if parent_id:
parent = CMSPlugin.objects.get(pk=parent_id)
if parent.placeholder_id != placeholder.pk:
return HttpResponseBadRequest(force_unicode('parent must be in the same placeholder'))
if parent.language != language:
return HttpResponseBadRequest(force_unicode('parent must be in the same language as plugin_language'))
else:
parent = None
plugin.move_to(parent, position='last-child')
return HttpResponseForbidden(force_text(_("You have no permission to move this plugin")))
if not placeholder == source_placeholder:
try:
template = self.get_placeholder_template(request, placeholder)
has_reached_plugin_limit(placeholder, plugin.plugin_type, plugin.language, template=template)
except PluginLimitReached as er:
return HttpResponseBadRequest(er)
plugin.save()
for child in plugin.get_descendants(include_self=True):
if parent_id:
if plugin.parent_id != parent_id:
parent = CMSPlugin.objects.get(pk=parent_id)
if parent.placeholder_id != placeholder.pk:
return HttpResponseBadRequest(force_text('parent must be in the same placeholder'))
if parent.language != language:
return HttpResponseBadRequest(force_text('parent must be in the same language as plugin_language'))
plugin.parent_id = parent.pk
plugin.save()
plugin = plugin.move(parent, pos='last-child')
else:
sibling = CMSPlugin.get_last_root_node()
plugin.parent_id = None
plugin.save()
plugin = plugin.move(sibling, pos='right')
for child in [plugin] + list(plugin.get_descendants()):
child.placeholder = placeholder
child.language = language
child.save()
plugins = CMSPlugin.objects.filter(parent=parent_id, placeholder=placeholder, language=language).order_by('position')
x = 0
for level_plugin in plugins:
if order:
x = 0
found = False
for pk in order:
if level_plugin.pk == int(pk):
level_plugin.position = x
level_plugin.save()
found = True
break
x += 1
if not found:
return HttpResponseBadRequest('order parameter did not have all plugins of the same level in it')
else:
level_plugin.position = x
level_plugin.save()
x += 1
plugins = reorder_plugins(placeholder, parent_id, language, order)
if not plugins:
return HttpResponseBadRequest('order parameter did not have all plugins of the same level in it')
self.post_move_plugin(request, source_placeholder, placeholder, plugin)
json_response = {'reload': requires_reload(PLUGIN_MOVE_ACTION, [plugin])}
if DJANGO_1_4:
return HttpResponse(json.dumps(json_response), mimetype='application/json')
else:
return HttpResponse(json.dumps(json_response), content_type='application/json')
return HttpResponse(json.dumps(json_response), content_type='application/json')
@xframe_options_sameorigin
def delete_plugin(self, request, plugin_id):
plugin = get_object_or_404(CMSPlugin.objects.select_related('placeholder'), pk=plugin_id)
if not self.has_delete_plugin_permission(request, plugin):
return HttpResponseForbidden(force_unicode(_("You do not have permission to delete this plugin")))
return HttpResponseForbidden(force_text(_("You do not have permission to delete this plugin")))
plugin_cms_class = plugin.get_plugin_class()
plugin_class = plugin_cms_class.model
opts = plugin_class._meta
using = router.db_for_write(plugin_class)
app_label = opts.app_label
(deleted_objects, perms_needed, protected) = get_deleted_objects(
[plugin], opts, request.user, self.admin_site, using)
if DJANGO_1_7:
deleted_objects, perms_needed, protected = get_deleted_objects(
[plugin], opts, request.user, self.admin_site, using)
else:
deleted_objects, __, perms_needed, protected = get_deleted_objects(
[plugin], opts, request.user, self.admin_site, using)
if request.POST: # The user has already confirmed the deletion.
if perms_needed:
raise PermissionDenied(_("You do not have permission to delete this plugin"))
obj_display = force_unicode(plugin)
obj_display = force_text(plugin)
self.log_deletion(request, plugin, obj_display)
plugin.delete()
self.message_user(request, _('The %(name)s plugin "%(obj)s" was deleted successfully.') % {
'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
'name': force_text(opts.verbose_name), 'obj': force_text(obj_display)})
self.post_delete_plugin(request, plugin)
return HttpResponseRedirect(admin_reverse('index', current_app=self.admin_site.name))
plugin_name = force_unicode(plugin_pool.get_plugin(plugin.plugin_type).name)
plugin_name = force_text(plugin_pool.get_plugin(plugin.plugin_type).name)
if perms_needed or protected:
title = _("Cannot delete %(name)s") % {"name": plugin_name}
else:
@@ -540,22 +522,27 @@ class PlaceholderAdminMixin(object):
def clear_placeholder(self, request, placeholder_id):
placeholder = get_object_or_404(Placeholder, pk=placeholder_id)
if not self.has_clear_placeholder_permission(request, placeholder):
return HttpResponseForbidden(force_unicode(_("You do not have permission to clear this placeholder")))
return HttpResponseForbidden(force_text(_("You do not have permission to clear this placeholder")))
language = request.GET.get('language', None)
plugins = placeholder.get_plugins(language)
opts = Placeholder._meta
using = router.db_for_write(Placeholder)
app_label = opts.app_label
(deleted_objects, perms_needed, protected) = get_deleted_objects(
plugins, opts, request.user, self.admin_site, using)
obj_display = force_unicode(placeholder)
if DJANGO_1_7:
deleted_objects, perms_needed, protected = get_deleted_objects(
plugins, opts, request.user, self.admin_site, using)
else:
deleted_objects, __, perms_needed, protected = get_deleted_objects(
plugins, opts, request.user, self.admin_site, using)
obj_display = force_text(placeholder)
if request.POST: # The user has already confirmed the deletion.
if perms_needed:
return HttpResponseForbidden(force_unicode(_("You do not have permission to clear this placeholder")))
return HttpResponseForbidden(force_text(_("You do not have permission to clear this placeholder")))
self.log_deletion(request, placeholder, obj_display)
placeholder.clear(language)
self.message_user(request, _('The placeholder "%(obj)s" was cleared successfully.') % {
'obj': force_unicode(obj_display)})
'obj': force_text(obj_display)})
self.post_clear_placeholder(request, placeholder)
return HttpResponseRedirect(admin_reverse('index', current_app=self.admin_site.name))
if perms_needed or protected:
@@ -574,17 +561,3 @@ class PlaceholderAdminMixin(object):
}
return TemplateResponse(request, "admin/cms/page/plugin/delete_confirmation.html", context,
current_app=self.admin_site.name)
class PlaceholderAdmin(PlaceholderAdminMixin, ModelAdmin):
def __init__(self, *args, **kwargs):
warnings.warn("Class PlaceholderAdmin is deprecated and will be removed in 3.1. "
"Instead, combine PlaceholderAdminMixin with admin.ModelAdmin.", DeprecationWarning)
super(PlaceholderAdmin, self).__init__(*args, **kwargs)
class FrontendEditableAdmin(FrontendEditableAdminMixin):
def __init__(self, *args, **kwargs):
warnings.warn("Class FrontendEditableAdmin is deprecated and will be removed in 3.1. "
"Instead, use FrontendEditableAdminMixin.", DeprecationWarning)
super(FrontendEditableAdmin, self).__init__(*args, **kwargs)
+13 -28
View File
@@ -1,34 +1,30 @@
# -*- coding: utf-8 -*-
import json
from functools import update_wrapper
import json
from django.conf.urls import url
from django.contrib import admin
from django.contrib.admin import ModelAdmin
from django.contrib.auth.admin import csrf_protect_m
from django.db import transaction
from django.http import HttpResponseRedirect, HttpResponse
from django.utils.translation import override
from cms.models import UserSettings
from cms.utils.compat import DJANGO_1_4
from cms.utils.transaction import wrap_transaction
from cms.utils.urlutils import admin_reverse
class SettingsAdmin(ModelAdmin):
def get_urls(self):
from django.conf.urls import patterns, url
def wrap(view):
def wrapper(*args, **kwargs):
return self.admin_site.admin_view(view)(*args, **kwargs)
return update_wrapper(wrapper, view)
info = self.model._meta.app_label, self.model._meta.module_name
info = self.model._meta.app_label, self.model._meta.model_name
urlpatterns = patterns(
'',
return [
url(r'^session_store/$',
self.session_store,
name='%s_%s_session_store' % info),
@@ -38,11 +34,10 @@ class SettingsAdmin(ModelAdmin):
url(r'^(.+)/$',
wrap(self.change_view),
name='%s_%s_change' % info),
)
return urlpatterns
]
@csrf_protect_m
@wrap_transaction
@transaction.atomic
def change_view(self, request, id=None):
model = self.model
try:
@@ -57,25 +52,15 @@ class SettingsAdmin(ModelAdmin):
POST should have a settings parameter
"""
if not request.user.is_staff:
if DJANGO_1_4:
return HttpResponse(json.dumps(""),
mimetype="application/json")
else:
return HttpResponse(json.dumps(""),
content_type="application/json")
return HttpResponse(json.dumps(""),
content_type="application/json")
if request.method == "POST":
request.session['cms_settings'] = request.POST['settings']
request.session.save()
if DJANGO_1_4:
return HttpResponse(
json.dumps(request.session.get('cms_settings', '')),
mimetype="application/json"
)
else:
return HttpResponse(
json.dumps(request.session.get('cms_settings', '')),
content_type="application/json"
)
return HttpResponse(
json.dumps(request.session.get('cms_settings', '')),
content_type="application/json"
)
def save_model(self, request, obj, form, change):
obj.user = request.user
+7 -7
View File
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
from django.contrib import admin
from django.contrib.auth import get_user_model
from cms.admin.forms import PageUserForm, PageUserGroupForm
from cms.admin.permissionadmin import GenericCmsPermissionAdmin
from cms.exceptions import NoPermissionsException
from cms.models import PageUser, PageUserGroup
from cms.utils.compat.dj import get_user_model
from cms.utils.compat.forms import UserAdmin
from cms.utils.conf import get_cms_setting
from cms.utils.permissions import get_subordinate_users
@@ -21,24 +21,24 @@ class PageUserAdmin(admin_class, GenericCmsPermissionAdmin):
form = PageUserForm
add_form = PageUserForm
model = PageUser
def queryset(self, request):
qs = super(PageUserAdmin, self).queryset(request)
def get_queryset(self, request):
qs = super(PageUserAdmin, self).get_queryset(request)
try:
user_id_set = get_subordinate_users(request.user).values_list('id', flat=True)
return qs.filter(pk__in=user_id_set)
except NoPermissionsException:
return self.model.objects.get_empty_query_set()
class PageUserGroupAdmin(admin.ModelAdmin, GenericCmsPermissionAdmin):
form = PageUserGroupForm
list_display = ('name', 'created_by')
fieldsets = [
(None, {'fields': ('name',)}),
]
def get_fieldsets(self, request, obj=None):
return self.update_permission_fieldsets(request, obj)
+3 -3
View File
@@ -18,7 +18,7 @@ def revert_plugins(request, version_id, obj):
for rev in revs:
obj = rev.object
if obj.__class__ == Placeholder:
placeholders[obj.pk] = obj
placeholders[obj.pk] = obj
if obj.__class__ == CMSPlugin:
cms_plugin_list.append(obj)
elif hasattr(obj, 'cmsplugin_ptr_id'):
@@ -27,14 +27,14 @@ def revert_plugins(request, version_id, obj):
pass
#page = obj #Page.objects.get(pk=obj.pk)
elif obj.__class__ == Title:
titles.append(obj)
titles.append(obj)
else:
others.append(rev)
if not page.has_change_permission(request):
raise Http404
current_plugins = list(CMSPlugin.objects.filter(placeholder__page=page))
for pk, placeholder in placeholders.items():
# admin has already created the placeholders/ get them instead
# admin has already created the placeholders/ get them instead
try:
placeholders[pk] = page.placeholders.get(slot=placeholder.slot)
except Placeholder.DoesNotExist:
+118 -38
View File
@@ -8,6 +8,7 @@ calling these methods!
"""
import datetime
from django.contrib.auth import get_user_model
from django.contrib.sites.models import Site
from django.core.exceptions import FieldError
from django.core.exceptions import PermissionDenied
@@ -15,7 +16,9 @@ from django.core.exceptions import ValidationError
from django.template.defaultfilters import slugify
from django.template.loader import get_template
from django.utils import six
from django.utils.translation import activate
from cms import constants
from cms.admin.forms import save_permissions
from cms.app_base import CMSApp
from cms.apphook_pool import apphook_pool
@@ -29,21 +32,12 @@ from cms.models.titlemodels import Title
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from cms.utils import copy_plugins
from cms.utils.compat.dj import get_user_model
from cms.utils.conf import get_cms_setting
from cms.utils.i18n import get_language_list
from cms.utils.permissions import _thread_locals
from cms.utils.permissions import _thread_locals, current_user, has_page_change_permission
from menus.menu_pool import menu_pool
#===============================================================================
# Constants
#===============================================================================
VISIBILITY_ALL = None
VISIBILITY_USERS = 1
VISIBILITY_STAFF = 2
#===============================================================================
# Helpers/Internals
#===============================================================================
@@ -59,13 +53,14 @@ def _generate_valid_slug(source, parent, language):
qs = Title.objects.filter(language=language, page__parent=parent)
else:
qs = Title.objects.filter(language=language, page__parent__isnull=True)
used = qs.values_list('slug', flat=True)
used = list(qs.values_list('slug', flat=True))
baseslug = slugify(source)
slug = baseslug
i = 1
while slug in used:
slug = '%s-%s' % (baseslug, i)
i += 1
if used:
while slug in used:
slug = '%s-%s' % (baseslug, i)
i += 1
return slug
@@ -103,7 +98,7 @@ def _verify_plugin_type(plugin_type):
(plugin_model, plugin_type)
"""
if (hasattr(plugin_type, '__module__') and
issubclass(plugin_type, CMSPluginBase)):
issubclass(plugin_type, CMSPluginBase)):
plugin_pool.set_plugin_meta()
plugin_model = plugin_type.model
assert plugin_type in plugin_pool.plugins.values()
@@ -119,8 +114,9 @@ def _verify_plugin_type(plugin_type):
raise TypeError('plugin_type must be CMSPluginBase subclass or string')
return plugin_model, plugin_type
#===============================================================================
# Public API
# Public API
#===============================================================================
def create_page(title, template, language, menu_title=None, slug=None,
@@ -129,11 +125,11 @@ def create_page(title, template, language, menu_title=None, slug=None,
publication_date=None, publication_end_date=None,
in_navigation=False, soft_root=False, reverse_id=None,
navigation_extenders=None, published=False, site=None,
login_required=False, limit_visibility_in_menu=VISIBILITY_ALL,
login_required=False, limit_visibility_in_menu=constants.VISIBILITY_ALL,
position="last-child", overwrite_url=None, xframe_options=Page.X_FRAME_OPTIONS_INHERIT):
"""
Create a CMS Page and it's title for the given language
See docs/extending_cms/api_reference.rst for more info
"""
# ugly permissions hack
@@ -181,11 +177,18 @@ def create_page(title, template, language, menu_title=None, slug=None,
assert navigation_extenders in menus
# validate menu visibility
accepted_limitations = (VISIBILITY_ALL, VISIBILITY_USERS, VISIBILITY_STAFF)
accepted_limitations = (constants.VISIBILITY_ALL, constants.VISIBILITY_USERS, constants.VISIBILITY_ANONYMOUS)
assert limit_visibility_in_menu in accepted_limitations
# validate position
assert position in ('last-child', 'first-child', 'left', 'right')
if parent:
if position in ('last-child', 'first-child'):
parent_id = parent.pk
else:
parent_id = parent.parent_id
else:
parent_id = None
# validate and normalize apphook
if apphook:
application_urls = _verify_apphook(apphook, apphook_namespace)
@@ -199,7 +202,7 @@ def create_page(title, template, language, menu_title=None, slug=None,
page = Page(
created_by=created_by,
changed_by=created_by,
parent=parent,
parent_id=parent_id,
publication_date=publication_date,
publication_end_date=publication_end_date,
in_navigation=in_navigation,
@@ -212,10 +215,12 @@ def create_page(title, template, language, menu_title=None, slug=None,
site=site,
login_required=login_required,
limit_visibility_in_menu=limit_visibility_in_menu,
xframe_options=xframe_options,
xframe_options=xframe_options,
)
page.insert_at(parent, position)
page.save()
page = page.add_root(instance=page)
if parent:
page = page.move(target=parent, pos=position)
create_title(
language=language,
@@ -240,9 +245,9 @@ def create_title(language, title, page, menu_title=None, slug=None,
parent=None, overwrite_url=None):
"""
Create a title.
Parent is only used if slug=None.
See docs/extending_cms/api_reference.rst for more info
"""
# validate page
@@ -277,7 +282,7 @@ def add_plugin(placeholder, plugin_type, language, position='last-child',
target=None, **data):
"""
Add a plugin to a placeholder
See docs/extending_cms/api_reference.rst for more info
"""
# validate placeholder
@@ -287,29 +292,58 @@ def add_plugin(placeholder, plugin_type, language, position='last-child',
plugin_model, plugin_type = _verify_plugin_type(plugin_type)
if target:
if position == 'last-child':
new_pos = CMSPlugin.objects.filter(language=language, parent=target, tree_id=target.tree_id).count()
if CMSPlugin.node_order_by:
position = 'sorted-child'
new_pos = CMSPlugin.objects.filter(parent=target).count()
parent_id = target.pk
elif position == 'first-child':
new_pos = 0
if CMSPlugin.node_order_by:
position = 'sorted-child'
parent_id = target.pk
elif position == 'left':
new_pos = target.position
if CMSPlugin.node_order_by:
position = 'sorted-sibling'
parent_id = target.parent_id
elif position == 'right':
new_pos = target.position + 1
if CMSPlugin.node_order_by:
position = 'sorted-sibling'
parent_id = target.parent_id
else:
raise Exception('position not supported: %s' % position)
for pl in CMSPlugin.objects.filter(language=language, parent=target.parent_id, tree_id=target.tree_id, position__gte=new_pos):
if position == 'last-child' or position == 'first-child':
qs = CMSPlugin.objects.filter(language=language, parent=target, position__gte=new_pos,
placeholder=placeholder)
else:
qs = CMSPlugin.objects.filter(language=language, parent=target.parent_id, position__gte=new_pos,
placeholder=placeholder)
for pl in qs:
pl.position += 1
pl.save()
else:
new_pos = CMSPlugin.objects.filter(language=language, parent__isnull=True, placeholder=placeholder).count()
if position == 'last-child':
new_pos = CMSPlugin.objects.filter(language=language, parent__isnull=True, placeholder=placeholder).count()
else:
new_pos = 0
for pl in CMSPlugin.objects.filter(language=language, parent__isnull=True, position__gte=new_pos,
placeholder=placeholder):
pl.position += 1
pl.save()
parent_id = None
plugin_base = CMSPlugin(
plugin_type=plugin_type,
placeholder=placeholder,
position=new_pos,
language=language
language=language,
parent_id=parent_id,
)
plugin_base.insert_at(target, position=position, save=False)
plugin_base = plugin_base.add_root(instance=plugin_base)
if target:
plugin_base = plugin_base.move(target, pos=position)
plugin = plugin_model(**data)
plugin_base.set_base_attr(plugin)
plugin.save()
@@ -326,7 +360,7 @@ def create_page_user(created_by, user,
can_delete_pagepermission=True, grant_all=False):
"""
Creates a page user.
See docs/extending_cms/api_reference.rst for more info
"""
if grant_all:
@@ -369,7 +403,7 @@ def assign_user_to_page(page, user, grant_on=ACCESS_PAGE_AND_DESCENDANTS,
grant_all=False, global_permission=False):
"""
Assigns given user to page, and gives him requested permissions.
See docs/extending_cms/api_reference.rst for more info
"""
grant_all = grant_all and not global_permission
@@ -399,7 +433,7 @@ def publish_page(page, user, language):
"""
Publish a page. This sets `page.published` to `True` and calls publish()
which does the actual publishing.
See docs/extending_cms/api_reference.rst for more info
"""
page = page.reload()
@@ -411,10 +445,41 @@ def publish_page(page, user, language):
request = FakeRequest(user)
if not page.has_publish_permission(request):
raise PermissionDenied()
page.publish(language)
# Set the current_user to have the page's changed_by
# attribute set correctly.
# 'user' is a user object, but current_user() just wants the username (a string).
with current_user(user.get_username()):
page.publish(language)
return page.reload()
def publish_pages(include_unpublished=False, language=None, site=None):
"""
Create published public version of selected drafts.
"""
qs = Page.objects.drafts()
if not include_unpublished:
qs = qs.filter(title_set__published=True).distinct()
if site:
qs = qs.filter(site=site)
output_language = None
for i, page in enumerate(qs):
add = True
titles = page.title_set
if not include_unpublished:
titles = titles.filter(published=True)
for lang in titles.values_list("language", flat=True):
if language is None or lang == language:
if not output_language:
output_language = lang
if not page.publish(lang):
add = False
# we may need to activate the first (main) language for proper page title rendering
activate(output_language)
yield (page, add)
def get_page_draft(page):
"""
Returns the draft version of a page, regardless if the passed in
@@ -456,13 +521,28 @@ def copy_plugins_to_language(page, source_language, target_language,
:return int: number of copied plugins
"""
copied = 0
placeholders = page.placeholders.all()
placeholders = page.get_placeholders()
for placeholder in placeholders:
# only_empty is True we check if the placeholder already has plugins and
# we skip it if has some
if not only_empty or not placeholder.cmsplugin_set.filter(language=target_language).exists():
plugins = list(
placeholder.cmsplugin_set.filter(language=source_language).order_by('tree_id', 'level', 'position'))
placeholder.cmsplugin_set.filter(language=source_language).order_by('path'))
copied_plugins = copy_plugins.copy_plugins_to(plugins, placeholder, target_language)
copied += len(copied_plugins)
return copied
def can_change_page(request):
"""
Check whether a user has the permission to change the page.
This will work across all permission-related setting, with a unified interface
to permission checking.
"""
# check global permissions if CMS_PERMISSION is active
global_permission = get_cms_setting('PERMISSION') and has_page_change_permission(request)
# check if user has page edit permission
page_permission = request.current_page and request.current_page.has_change_permission(request)
return global_permission or page_permission
+8 -6
View File
@@ -6,15 +6,18 @@ try:
except ImportError:
# Python < 2.7
from django.utils.datastructures import SortedDict as OrderedDict
try:
from importlib import import_module
except ImportError:
# Python < 2.7
from django.utils.importlib import import_module
from django.conf import settings
from django.conf.urls import patterns
from django.contrib.sites.models import Site
from django.core.exceptions import ImproperlyConfigured
from django.core.urlresolvers import (RegexURLResolver, Resolver404, reverse,
RegexURLPattern)
RegexURLPattern)
from django.utils import six
from django.utils.importlib import import_module
from django.utils.translation import get_language
from cms.apphook_pool import apphook_pool
@@ -209,7 +212,7 @@ def get_app_patterns():
# Loop over all titles with an application hooked to them
# TODO: Need to be fixed for django-treebeard when forward ported to 3.1
for title in title_qs.exclude(page__application_urls=None).exclude(page__application_urls='').order_by('-page__level').select_related():
for title in title_qs.exclude(page__application_urls=None).exclude(page__application_urls='').order_by('-page__path').select_related():
path = title.path
mix_id = "%s:%s:%s" % (path + "/", title.page.application_urls, title.language)
if mix_id in included:
@@ -236,8 +239,7 @@ def get_app_patterns():
if app.permissions:
_set_permissions(current_patterns, app.exclude_permissions)
extra_patterns = patterns('', *current_patterns)
resolver.url_patterns_dict[lang] = extra_patterns
resolver.url_patterns_dict[lang] = current_patterns
app_patterns.append(resolver)
APP_RESOLVERS.append(resolver)
return app_patterns
-2
View File
@@ -10,5 +10,3 @@ class CMSConfig(AppConfig):
def ready(self):
setup()
from cms.plugin_pool import plugin_pool
plugin_pool.set_plugin_meta()
+87
View File
@@ -0,0 +1,87 @@
# -*- coding: utf-8 -*-
import re
from cms.utils import get_cms_setting
CMS_PAGE_CACHE_VERSION_KEY = get_cms_setting("CACHE_PREFIX") + 'CMS_PAGE_CACHE_VERSION'
def _get_cache_version():
"""
Returns the current page cache version, explicitly setting one if not
defined.
"""
from django.core.cache import cache
version = cache.get(CMS_PAGE_CACHE_VERSION_KEY)
if version:
return version
else:
_set_cache_version(1)
return 1
def _set_cache_version(version):
"""
Set the cache version to the specified value.
"""
from django.core.cache import cache
cache.set(
CMS_PAGE_CACHE_VERSION_KEY,
version,
get_cms_setting('CACHE_DURATIONS')['content']
)
def invalidate_cms_page_cache():
"""
Invalidates the CMS PAGE CACHE.
"""
#
# NOTE: We're using a cache versioning strategy for invalidating the page
# cache when necessary. Instead of wiping all the old entries, we simply
# increment the version number rendering all previous entries
# inaccessible and left to expire naturally.
#
# ALSO NOTE: According to the Django documentation, a timeout value of
# `None' (in version 1.6+) is supposed to mean "cache forever", however,
# this is actually only implemented as only slightly less than 30 days in
# some backends (memcached, in particular). In older Djangos, `None' means
# "use default value". To avoid issues arising from different Django
# versions and cache backend implementations, we will explicitly set the
# lifespan of the CMS_PAGE_CACHE_VERSION entry to whatever is set in
# settings.CACHE_DURATIONS['content']. This allows users to adjust as
# necessary for their backend.
#
# To prevent writing cache entries that will live longer than our version
# key, we will always re-write the current version number into the cache
# just after we write any new cache entries, thus ensuring that the
# version number will always outlive any entries written against that
# version. This is a cheap operation.
#
# If there are no new cache writes before the version key expires, its
# perfectly OK, since any previous entries cached against that version
# will have also expired, so, it'd be pointless to try to access them
# anyway.
#
version = _get_cache_version()
_set_cache_version(version + 1)
CLEAN_KEY_PATTERN = re.compile(r'[^a-zA-Z0-9_-]')
def _clean_key(key):
return CLEAN_KEY_PATTERN.sub('-', key)
def _get_cache_key(name, page_lookup, lang, site_id):
from cms.models import Page
if isinstance(page_lookup, Page):
page_key = str(page_lookup.pk)
else:
page_key = str(page_lookup)
page_key = _clean_key(page_key)
return get_cms_setting('CACHE_PREFIX') + name + '__page_lookup:' + page_key + '_site:' + str(site_id) + '_lang:' + str(lang)
+31
View File
@@ -0,0 +1,31 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from cms.utils import get_cms_setting
def _site_cache_key(lang):
return "%s-%s" %(get_cms_setting('SITE_CHOICES_CACHE_KEY'), lang)
def _page_cache_key(lang):
return "%s-%s" %(get_cms_setting('PAGE_CHOICES_CACHE_KEY'), lang)
def _clean_many(prefix):
from django.core.cache import cache
keys = []
if settings.USE_I18N:
for lang in [language[0] for language in settings.LANGUAGES]:
keys.append("%s-%s" %(prefix, lang))
else:
keys = ["%s-%s" %(prefix, settings.LANGUAGE_CODE)]
cache.delete_many(keys)
def clean_site_choices_cache(sender, **kwargs):
_clean_many(get_cms_setting('SITE_CHOICES_CACHE_KEY'))
def clean_page_choices_cache(sender, **kwargs):
_clean_many(get_cms_setting('PAGE_CHOICES_CACHE_KEY'))
+97
View File
@@ -0,0 +1,97 @@
# -*- coding: utf-8 -*-
import hashlib
from django.conf import settings
from django.utils.cache import add_never_cache_headers
from django.utils.encoding import iri_to_uri, force_text
from django.utils.timezone import get_current_timezone_name
from cms.cache import _get_cache_version, _set_cache_version, _get_cache_key
from cms.utils import get_cms_setting
def _page_cache_key(request):
#md5 key of current path
cache_key = "%s:%d:%s" % (
get_cms_setting("CACHE_PREFIX"),
settings.SITE_ID,
hashlib.md5(iri_to_uri(request.get_full_path()).encode('utf-8')).hexdigest()
)
if settings.USE_TZ:
# The datetime module doesn't restrict the output of tzname().
# Windows is known to use non-standard, locale-dependant names.
# User-defined tzinfo classes may return absolutely anything.
# Hence this paranoid conversion to create a valid cache key.
tz_name = force_text(get_current_timezone_name(), errors='ignore')
cache_key += '.%s' % tz_name.encode('ascii', 'ignore').decode('ascii').replace(' ', '_')
return cache_key
def set_page_cache(response):
from django.core.cache import cache
if not get_cms_setting('PAGE_CACHE'):
return response
request = response._request
save_cache = True
for placeholder in getattr(request, 'placeholders', []):
if not placeholder.cache_placeholder:
save_cache = False
break
if hasattr(request, 'toolbar'):
if request.toolbar.edit_mode or request.toolbar.show_toolbar:
save_cache = False
if request.user.is_authenticated():
save_cache = False
if not save_cache:
add_never_cache_headers(response)
return response
else:
version = _get_cache_version()
ttl = get_cms_setting('CACHE_DURATIONS')['content']
cache.set(
_page_cache_key(request),
(response.content, response._headers),
ttl,
version=version
)
# See note in invalidate_cms_page_cache()
_set_cache_version(version)
def get_page_cache(request):
from django.core.cache import cache
return cache.get(_page_cache_key(request),
version=_get_cache_version())
def get_xframe_cache(page):
from django.core.cache import cache
return cache.get('cms:xframe_options:%s' % page.pk)
def set_xframe_cache(page, xframe_options):
from django.core.cache import cache
cache.set('cms:xframe_options:%s' % page.pk,
xframe_options,
version=_get_cache_version())
_set_cache_version(_get_cache_version())
def _page_url_key(page_lookup, lang, site_id):
return _get_cache_key('page_url', page_lookup, lang, site_id) + '_type:absolute_url'
def set_page_url_cache(page_lookup, lang, site_id, url):
from django.core.cache import cache
cache.set(_page_url_key(page_lookup, lang, site_id),
url,
get_cms_setting('CACHE_DURATIONS')['content'], version=_get_cache_version())
_set_cache_version(_get_cache_version())
def get_page_url_cache(page_lookup, lang, site_id):
from django.core.cache import cache
return cache.get(_page_url_key(page_lookup, lang, site_id),
version=_get_cache_version())
+18 -14
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from django.contrib.auth import get_user_model
from cms.utils import get_cms_setting
from cms.utils.compat.dj import get_user_model
PERMISSION_KEYS = [
@@ -15,15 +16,18 @@ def get_cache_key(user, key):
return "%s:permission:%s:%s" % (
get_cms_setting('CACHE_PREFIX'), username, key)
def get_cache_version_key():
def get_cache_permission_version_key():
return "%s:permission:version" % (get_cms_setting('CACHE_PREFIX'),)
def get_cache_version():
def get_cache_permission_version():
from django.core.cache import cache
version = cache.get(get_cache_version_key())
if version is None:
try:
version = int(cache.get(get_cache_permission_version_key()))
except Exception:
version = 1
return version
return int(version)
def get_permission_cache(user, key):
@@ -31,7 +35,7 @@ def get_permission_cache(user, key):
Helper for reading values from cache
"""
from django.core.cache import cache
return cache.get(get_cache_key(user, key), version=get_cache_version())
return cache.get(get_cache_key(user, key), version=get_cache_permission_version())
def set_permission_cache(user, key, value):
@@ -43,8 +47,8 @@ def set_permission_cache(user, key, value):
# store this key, so we can clean it when required
cache_key = get_cache_key(user, key)
cache.set(cache_key, value,
get_cms_setting('CACHE_DURATIONS')['permissions'],
version=get_cache_version())
get_cms_setting('CACHE_DURATIONS')['permissions'],
version=get_cache_permission_version())
def clear_user_permission_cache(user):
@@ -53,14 +57,14 @@ def clear_user_permission_cache(user):
"""
from django.core.cache import cache
for key in PERMISSION_KEYS:
cache.delete(get_cache_key(user, key), version=get_cache_version())
cache.delete(get_cache_key(user, key), version=get_cache_permission_version())
def clear_permission_cache():
from django.core.cache import cache
version = get_cache_version()
version = get_cache_permission_version()
if version > 1:
cache.incr(get_cache_version_key())
cache.incr(get_cache_permission_version_key())
else:
cache.set(get_cache_version_key(), 2,
get_cms_setting('CACHE_DURATIONS')['permissions'])
cache.set(get_cache_permission_version_key(), 2,
get_cms_setting('CACHE_DURATIONS')['permissions'])
+63
View File
@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.utils.encoding import force_text
from django.utils.timezone import get_current_timezone_name
from cms.cache import _get_cache_version, _set_cache_version, _clean_key, _get_cache_key
from cms.utils import get_cms_setting
def _placeholder_cache_key(placeholder, lang):
cache_key = '%srender_placeholder:%s.%s' % (get_cms_setting("CACHE_PREFIX"), placeholder.pk, str(lang))
if settings.USE_TZ:
tz_name = force_text(get_current_timezone_name(), errors='ignore')
cache_key += '.%s' % tz_name.encode('ascii', 'ignore').decode('ascii').replace(' ', '_')
return cache_key
def set_placeholder_cache(placeholder, lang, content):
"""
Caches the rendering of a placeholder
"""
from django.core.cache import cache
cache.set(_placeholder_cache_key(placeholder, lang),
content,
get_cms_setting('CACHE_DURATIONS')['content'],
version=_get_cache_version())
_set_cache_version(_get_cache_version())
def get_placeholder_cache(placeholder, lang):
"""
Retrieves the cached content of a placeholder
"""
from django.core.cache import cache
return cache.get(_placeholder_cache_key(placeholder, lang),
version=_get_cache_version())
def clear_placeholder_cache(placeholder, lang):
from django.core.cache import cache
cache.delete(_placeholder_cache_key(placeholder, lang), version=_get_cache_version())
def _placeholder_page_cache_key(page_lookup, lang, site_id, placeholder_name):
base_key = _get_cache_key('_show_placeholder_for_page', page_lookup, lang, site_id)
return _clean_key('%s_placeholder:%s' % (base_key, placeholder_name))
def get_placeholder_page_cache(page_lookup, lang, site_id, placeholder_name):
from django.core.cache import cache
return cache.get(_placeholder_page_cache_key(page_lookup, lang, site_id, placeholder_name),
version=_get_cache_version())
def set_placeholder_page_cache(page_lookup, lang, site_id, placeholder_name, content):
from django.core.cache import cache
cache.set(_placeholder_page_cache_key(page_lookup, lang, site_id, placeholder_name),
content,
get_cms_setting('CACHE_DURATIONS')['content'], version=_get_cache_version())
_set_cache_version(_get_cache_version())
+7 -7
View File
@@ -5,9 +5,8 @@ from cms.models.placeholderpluginmodel import PlaceholderReference
from cms.plugin_base import CMSPluginBase, PluginMenuItem
from cms.plugin_pool import plugin_pool
from cms.plugin_rendering import render_placeholder
from cms.utils.plugins import downcast_plugins, build_plugin_tree
from cms.utils.urlutils import admin_reverse
from django.conf.urls import patterns, url
from django.conf.urls import url
from django.http import HttpResponseForbidden, HttpResponseBadRequest, HttpResponse
from django.middleware.csrf import get_token
from django.utils.safestring import mark_safe
@@ -20,6 +19,7 @@ class PlaceholderPlugin(CMSPluginBase):
#require_parent = True
render_plugin = False
admin_preview = False
system = True
model = PlaceholderReference
@@ -32,13 +32,15 @@ class AliasPlugin(CMSPluginBase):
allow_children = False
model = AliasPluginModel
render_template = "cms/plugins/alias.html"
system = True
def render(self, context, instance, placeholder):
from cms.utils.plugins import downcast_plugins, build_plugin_tree
context['instance'] = instance
context['placeholder'] = placeholder
if instance.plugin_id:
plugins = instance.plugin.get_descendants(include_self=True).order_by('placeholder', 'tree_id', 'level',
'position')
plugins = instance.plugin.get_descendants().order_by('placeholder', 'path')
plugins = [instance.plugin] + list(plugins)
plugins = downcast_plugins(plugins)
plugins[0].parent_id = None
plugins = build_plugin_tree(plugins)
@@ -67,11 +69,9 @@ class AliasPlugin(CMSPluginBase):
]
def get_plugin_urls(self):
urlpatterns = [
return [
url(r'^create_alias/$', self.create_alias, name='cms_create_alias'),
]
urlpatterns = patterns('', *urlpatterns)
return urlpatterns
def create_alias(self, request):
if not request.user.is_staff:
+89 -59
View File
@@ -1,28 +1,28 @@
# -*- coding: utf-8 -*-
from django.conf import settings
from django.core.urlresolvers import reverse, NoReverseMatch, resolve, Resolver404
from django.utils.translation import ugettext_lazy as _
from django.contrib import admin
from django.contrib.auth.models import User, AnonymousUser
from django.contrib.auth import get_permission_codename, get_user_model
from django.contrib.auth.models import AnonymousUser
from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse, NoReverseMatch, resolve, Resolver404
from django.template.loader import render_to_string
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
try:
from django.contrib.auth import get_user_model
except ImportError:
get_user_model = lambda: User
from cms.api import get_page_draft
from cms.api import get_page_draft, can_change_page
from cms.constants import TEMPLATE_INHERITANCE_MAGIC, PUBLISHER_STATE_PENDING
from cms.models import Title, Page
from cms.toolbar.items import TemplateItem
from cms.toolbar_base import CMSToolbar
from cms.toolbar_pool import toolbar_pool
from cms.utils.compat import DJANGO_1_4
from cms.utils.i18n import get_language_tuple, force_language, get_language_dict
from cms.utils.compat.dj import is_installed
from cms.utils import get_cms_setting
from cms.utils.permissions import get_user_sites_queryset, has_page_change_permission
from cms.utils.permissions import (
get_user_sites_queryset,
has_auth_page_permission,
)
from cms.utils.urlutils import add_url_parameters, admin_reverse
from menus.utils import DefaultLanguageChanger
@@ -47,6 +47,7 @@ USER_SETTINGS_BREAK = 'User Settings Break'
ADD_PAGE_LANGUAGE_BREAK = "Add page language Break"
REMOVE_PAGE_LANGUAGE_BREAK = "Remove page language Break"
COPY_PAGE_LANGUAGE_BREAK = "Copy page language Break"
TOOLBAR_DISABLE_BREAK = 'Toolbar disable Break'
@toolbar_pool.register
@@ -86,9 +87,12 @@ class PlaceholderToolbar(CMSToolbar):
build_mode = self.toolbar.build_mode
build_url = '?%s' % get_cms_setting('CMS_TOOLBAR_URL__BUILD')
edit_url = '?%s' % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')
switcher = self.toolbar.add_button_list('Mode Switcher', side=self.toolbar.RIGHT, extra_classes=extra_classes)
switcher.add_button(_('Structure'), build_url, active=build_mode, disabled=not build_mode)
switcher.add_button(_('Content'), edit_url, active=not build_mode, disabled=build_mode)
if self.request.user.has_perm("cms.use_structure"):
switcher = self.toolbar.add_button_list('Mode Switcher', side=self.toolbar.RIGHT,
extra_classes=extra_classes)
switcher.add_button(_('Structure'), build_url, active=build_mode, disabled=not build_mode)
switcher.add_button(_('Content'), edit_url, active=not build_mode, disabled=build_mode)
@toolbar_pool.register
@@ -96,46 +100,56 @@ class BasicToolbar(CMSToolbar):
"""
Basic Toolbar for site and languages menu
"""
page = None
_language_menu = None
_admin_menu = None
def init_from_request(self):
self.page = get_page_draft(self.request.current_page)
def populate(self):
self.init_from_request()
if not self.page:
self.init_from_request()
self.add_admin_menu()
self.add_language_menu()
self.add_admin_menu()
self.add_language_menu()
user_settings = self.request.toolbar.get_user_settings()
self.clipboard = user_settings.clipboard
def add_admin_menu(self):
admin_menu = self.toolbar.get_or_create_menu(ADMIN_MENU_IDENTIFIER, self.current_site.name)
if not self._admin_menu:
self._admin_menu = self.toolbar.get_or_create_menu(ADMIN_MENU_IDENTIFIER, self.current_site.name)
# Users button
self.add_users_button(self._admin_menu)
# Users button
self.add_users_button(admin_menu)
# sites menu
if get_cms_setting('PERMISSION'):
sites_queryset = get_user_sites_queryset(self.request.user)
else:
sites_queryset = Site.objects.all()
# sites menu
if get_cms_setting('PERMISSION'):
sites_queryset = get_user_sites_queryset(self.request.user)
else:
sites_queryset = Site.objects.all()
if len(sites_queryset) > 1:
sites_menu = self._admin_menu.get_or_create_menu('sites', _('Sites'))
sites_menu.add_sideframe_item(_('Admin Sites'), url=admin_reverse('sites_site_changelist'))
sites_menu.add_break(ADMIN_SITES_BREAK)
for site in sites_queryset:
sites_menu.add_link_item(site.name, url='http://%s' % site.domain,
active=site.pk == self.current_site.pk)
if len(sites_queryset) > 1:
sites_menu = admin_menu.get_or_create_menu('sites', _('Sites'))
sites_menu.add_sideframe_item(_('Admin Sites'), url=admin_reverse('sites_site_changelist'))
sites_menu.add_break(ADMIN_SITES_BREAK)
for site in sites_queryset:
sites_menu.add_link_item(site.name, url='http://%s' % site.domain,
active=site.pk == self.current_site.pk)
# admin
self._admin_menu.add_sideframe_item(_('Administration'), url=admin_reverse('index'))
self._admin_menu.add_break(ADMINISTRATION_BREAK)
# admin
admin_menu.add_sideframe_item(_('Administration'), url=admin_reverse('index'))
admin_menu.add_break(ADMINISTRATION_BREAK)
# cms users
self._admin_menu.add_sideframe_item(_('User settings'), url=admin_reverse('cms_usersettings_change'))
self._admin_menu.add_break(USER_SETTINGS_BREAK)
# cms users
admin_menu.add_sideframe_item(_('User settings'), url=admin_reverse('cms_usersettings_change'))
admin_menu.add_break(USER_SETTINGS_BREAK)
# Disable toolbar
self._admin_menu.add_link_item(_('Disable toolbar'), url='?%s' % get_cms_setting('CMS_TOOLBAR_URL__DISABLE'))
self._admin_menu.add_break(TOOLBAR_DISABLE_BREAK)
# logout
self.add_logout_button(admin_menu)
# logout
self.add_logout_button(self._admin_menu)
def add_users_button(self, parent):
User = get_user_model()
@@ -143,8 +157,8 @@ class BasicToolbar(CMSToolbar):
if User in admin.site._registry:
opts = User._meta
if self.request.user.has_perm('%s.%s' % (opts.app_label, opts.get_change_permission())):
user_changelist_url = admin_reverse('%s_%s_changelist' % (opts.app_label, opts.module_name))
if self.request.user.has_perm('%s.%s' % (opts.app_label, get_permission_codename('change', opts))):
user_changelist_url = admin_reverse('%s_%s_changelist' % (opts.app_label, opts.model_name))
parent.add_sideframe_item(_('Users'), url=user_changelist_url)
def add_logout_button(self, parent):
@@ -169,15 +183,15 @@ class BasicToolbar(CMSToolbar):
parent.add_ajax_item(logout_menu_text, action=admin_reverse('logout'), active=True, on_success=on_success)
def add_language_menu(self):
if settings.USE_I18N:
language_menu = self.toolbar.get_or_create_menu(LANGUAGE_MENU_IDENTIFIER, _('Language'))
if settings.USE_I18N and not self._language_menu:
self._language_menu = self.toolbar.get_or_create_menu(LANGUAGE_MENU_IDENTIFIER, _('Language'))
language_changer = getattr(self.request, '_language_changer', DefaultLanguageChanger(self.request))
for code, name in get_language_tuple(self.current_site.pk):
try:
url = language_changer(code)
except NoReverseMatch:
url = DefaultLanguageChanger(self.request)(code)
language_menu.add_link_item(name, url=url, active=self.current_lang == code)
self._language_menu.add_link_item(name, url=url, active=self.current_lang == code)
def get_username(self, user=None, default=''):
user = user or self.request.user
@@ -185,16 +199,27 @@ class BasicToolbar(CMSToolbar):
name = user.get_full_name()
if name:
return name
elif DJANGO_1_4:
return user.username
else:
return user.get_username()
except (AttributeError, NotImplementedError):
return default
def get_clipboard_plugins(self):
self.populate()
if not hasattr(self, "clipboard"):
return []
return self.clipboard.get_plugins()
def render_addons(self, context):
context.push()
context['local_toolbar'] = self
clipboard = mark_safe(render_to_string('cms/toolbar/clipboard.html', context))
context.pop()
return [clipboard]
@toolbar_pool.register
class PageToolbar(CMSToolbar):
_changed_admin_menu = None
watch_models = [Page]
# Helpers
@@ -231,14 +256,16 @@ class PageToolbar(CMSToolbar):
def has_page_change_permission(self):
if not hasattr(self, 'page_change_permission'):
# check global permissions if CMS_PERMISSIONS is active
global_permission = self.permissions_activated and has_page_change_permission(self.request)
# check if user has page edit permission
page_permission = self.page and self.page.has_change_permission(self.request)
self.page_change_permission = global_permission or page_permission
if not self.page and not get_cms_setting('PERMISSION'):
# We can't check permissions for an individual page
# and can't check global cms permissions because
# user opted out of them.
# So just check django auth permissions.
user = self.request.user
can_change = has_auth_page_permission(user, action='change')
else:
can_change = can_change_page(self.request)
self.page_change_permission = can_change
return self.page_change_permission
def page_is_pending(self, page, language):
@@ -280,8 +307,8 @@ class PageToolbar(CMSToolbar):
def post_template_populate(self):
self.init_placeholders_from_request()
self.add_publish_button()
self.add_draft_live()
self.add_publish_button()
# Buttons
@@ -386,7 +413,7 @@ class PageToolbar(CMSToolbar):
question=question % name, on_success=self.toolbar.REFRESH_PAGE)
def change_admin_menu(self):
if self.has_page_change_permission():
if not self._changed_admin_menu and self.has_page_change_permission():
admin_menu = self.toolbar.get_or_create_menu(ADMIN_MENU_IDENTIFIER)
url = admin_reverse('cms_page_changelist') # cms page admin
params = {'language': self.toolbar.language}
@@ -394,6 +421,8 @@ class PageToolbar(CMSToolbar):
params['page_id'] = self.page.pk
url = add_url_parameters(url, params)
admin_menu.add_sideframe_item(_('Pages'), url=url, position=0)
# Used to prevent duplicates
self._changed_admin_menu = True
def add_page_menu(self):
if self.page and self.has_page_change_permission():
@@ -523,7 +552,8 @@ class PageToolbar(CMSToolbar):
revert_action = admin_reverse('cms_page_revert_page', args=(self.page.pk, self.current_lang))
revert_question = _('Are you sure you want to revert to live?')
is_enabled = self.page.is_dirty(self.current_lang) and self.page.publisher_public
history_menu.add_ajax_item(_('Revert to live'), action=revert_action, question=revert_question,
disabled=not self.page.is_dirty(self.current_lang),
on_success=refresh, extra_classes=('cms_toolbar-revert',))
disabled=not is_enabled,
on_success=refresh, extra_classes=('cms-toolbar-revert',))
history_menu.add_modal_item(_('View history'), url=admin_reverse('cms_page_history', args=(self.page.pk,)))
+6
View File
@@ -18,3 +18,9 @@ PUBLISHER_STATE_DIRTY = 1
PUBLISHER_STATE_PENDING = 4
PAGE_TYPES_ID = "page_types"
VISIBILITY_ALL = None
VISIBILITY_USERS = 1
VISIBILITY_ANONYMOUS = 2
PAGE_USERNAME_MAX_LENGTH = 255
+1 -8
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from cms.utils.conf import get_cms_setting
from cms.utils import get_template_from_request
import warnings
def cms_settings(request):
"""
@@ -12,10 +12,3 @@ def cms_settings(request):
'CMS_MEDIA_URL': get_cms_setting('MEDIA_URL'),
'CMS_TEMPLATE': lambda: get_template_from_request(request),
}
def media(request):
warnings.warn('cms.context_processors.media has been deprecated in favor of '
'cms.context_processors.cms_settings. Please update your '
'configuration', DeprecationWarning)
return cms_settings(request)
+2 -2
View File
@@ -21,6 +21,7 @@ class AppAlreadyRegistered(Exception):
class ToolbarAlreadyRegistered(Exception):
pass
class ToolbarNotRegistered(Exception):
pass
@@ -47,7 +48,7 @@ class PermissionsException(Exception):
class NoPermissionsException(PermissionsException):
"""Can be fired when some violate action is performed on permission system.
"""Can be fired when some violate action is performed on permission system.
"""
@@ -81,4 +82,3 @@ class PluginConsistencyError(Exception): pass
class PlaceholderNotFound(Exception): pass
+6 -7
View File
@@ -34,8 +34,8 @@ class PageExtensionAdmin(ExtensionAdmin):
"""
return {}
def queryset(self, request):
return super(PageExtensionAdmin, self).queryset(request).filter(extended_object__publisher_is_draft=True)
def get_queryset(self, request):
return super(PageExtensionAdmin, self).get_queryset(request).filter(extended_object__publisher_is_draft=True)
@csrf_protect_m
def add_view(self, request, form_url='', extra_context=None):
@@ -49,7 +49,7 @@ class PageExtensionAdmin(ExtensionAdmin):
extension = self.model.objects.get(extended_object=page)
opts = self.model._meta
change_url = reverse('admin:%s_%s_change' %
(opts.app_label, opts.module_name),
(opts.app_label, opts.model_name),
args=(extension.pk,),
current_app=self.admin_site.name)
return HttpResponseRedirect(change_url)
@@ -81,8 +81,8 @@ class TitleExtensionAdmin(ExtensionAdmin):
"""
return {}
def queryset(self, request):
return super(TitleExtensionAdmin, self).queryset(request).filter(extended_object__page__publisher_is_draft=True)
def get_queryset(self, request):
return super(TitleExtensionAdmin, self).get_queryset(request).filter(extended_object__page__publisher_is_draft=True)
@csrf_protect_m
def add_view(self, request, form_url='', extra_context=None):
@@ -96,11 +96,10 @@ class TitleExtensionAdmin(ExtensionAdmin):
extension = self.model.objects.get(extended_object=title)
opts = self.model._meta
change_url = reverse('admin:%s_%s_change' %
(opts.app_label, opts.module_name),
(opts.app_label, opts.model_name),
args=(extension.pk,),
current_app=self.admin_site.name)
return HttpResponseRedirect(change_url)
except self.model.DoesNotExist:
pass
return super(ExtensionAdmin, self).add_view(request, form_url, extra_context)
+1 -1
View File
@@ -89,7 +89,7 @@ class ExtensionPool(object):
def copy_extensions(self, source_page, target_page, languages=None):
if not languages:
languages = source_page.get_languages()
languages = target_page.get_languages()
if self.page_extensions:
self._copy_page_extensions(source_page, target_page, None, clone=True)
self._remove_orphaned_page_extensions()
-3
View File
@@ -116,6 +116,3 @@ class TitleExtension(BaseExtension):
Title.objects.filter(pk=self.extended_object.pk).update(
publisher_state=PUBLISHER_STATE_DIRTY) # mark title dirty
return super(BaseExtension, self).delete(*args, **kwargs)
+8 -6
View File
@@ -2,7 +2,7 @@
from cms.utils.urlutils import admin_reverse
from cms.api import get_page_draft
from cms.toolbar_base import CMSToolbar
from cms.utils import get_cms_setting
from cms.utils import get_cms_setting, get_language_list
from cms.utils.permissions import has_page_change_permission
from django.core.urlresolvers import NoReverseMatch
@@ -99,13 +99,14 @@ class ExtensionToolbar(CMSToolbar):
except self.model.DoesNotExist:
page_extension = None
try:
model_name = self.model.__name__.lower()
if page_extension:
admin_url = admin_reverse(
'%s_%s_change' % (self.model._meta.app_label, self.model._meta.model_name),
'%s_%s_change' % (self.model._meta.app_label, model_name),
args=(page_extension.pk,))
else:
admin_url = "%s?extended_object=%s" % (
admin_reverse('%s_%s_add' % (self.model._meta.app_label, self.model._meta.model_name)),
admin_reverse('%s_%s_add' % (self.model._meta.app_label, model_name)),
self.page.pk)
except NoReverseMatch: # pragma: no cover
admin_url = None
@@ -125,7 +126,7 @@ class ExtensionToolbar(CMSToolbar):
if language:
titles = page.get_title_obj(language),
else:
titles = page.title_set.all()
titles = page.title_set.filter(language__in=get_language_list(page.site_id))
# Titles
for title in titles:
try:
@@ -133,13 +134,14 @@ class ExtensionToolbar(CMSToolbar):
except self.model.DoesNotExist:
title_extension = None
try:
model_name = self.model.__name__.lower()
if title_extension:
admin_url = admin_reverse(
'%s_%s_change' % (self.model._meta.app_label, self.model._meta.model_name),
'%s_%s_change' % (self.model._meta.app_label, model_name),
args=(title_extension.pk,))
else:
admin_url = "%s?extended_object=%s" % (
admin_reverse('%s_%s_add' % (self.model._meta.app_label, self.model._meta.model_name)),
admin_reverse('%s_%s_add' % (self.model._meta.app_label, model_name)),
title.pk)
except NoReverseMatch: # pragma: no cover
admin_url = None
-1
View File
@@ -1 +0,0 @@
+5 -5
View File
@@ -1,12 +1,12 @@
# -*- coding: utf-8 -*-
import six
from django.utils.translation import ugettext_lazy as _
from django import forms
from django.contrib.admin.widgets import RelatedFieldWidgetWrapper
from django.forms.fields import EMPTY_VALUES
from cms.models.pagemodel import Page
from cms.forms.widgets import PageSelectWidget, PageSmartLinkWidget
from django.utils.translation import ugettext_lazy as _
from cms.forms.utils import get_site_choices, get_page_choices
from cms.forms.widgets import PageSelectWidget, PageSmartLinkWidget
from cms.models.pagemodel import Page
class SuperLazyIterator(object):
@@ -84,5 +84,5 @@ class PageSmartLinkField(forms.CharField):
def widget_attrs(self, widget):
attrs = super(PageSmartLinkField, self).widget_attrs(widget)
attrs.update({'placeholder_text': six.text_type(self.placeholder_text)})
attrs.update({'placeholder_text': self.placeholder_text})
return attrs
+21 -47
View File
@@ -1,26 +1,31 @@
# -*- coding: utf-8 -*-
from collections import defaultdict
try:
from collections import OrderedDict
except ImportError:
from django.utils.datastructures import SortedDict as OrderedDict
from cms.exceptions import LanguageError
from cms.models import Page
from cms.models.titlemodels import Title
from cms.utils import i18n
from cms.utils.conf import get_cms_setting
from django.conf import settings
from django.contrib.sites.models import Site
from django.db.models.signals import post_save, post_delete
from django.utils.datastructures import SortedDict
from django.utils.html import escape
from django.utils.safestring import mark_safe
from cms.cache.choices import (
clean_site_choices_cache, clean_page_choices_cache,
_site_cache_key, _page_cache_key)
from cms.exceptions import LanguageError
from cms.models import Page, Title
from cms.utils import i18n
def update_site_and_page_choices(lang=None):
lang = lang or i18n.get_current_language()
SITE_CHOICES_KEY = get_site_cache_key(lang)
PAGE_CHOICES_KEY = get_page_cache_key(lang)
SITE_CHOICES_KEY = _site_cache_key(lang)
PAGE_CHOICES_KEY = _page_cache_key(lang)
title_queryset = (Title.objects.drafts()
.select_related('page', 'page__site')
.order_by('page__tree_id', 'page__lft', 'page__rght'))
pages = defaultdict(SortedDict)
.select_related('page', 'page__site')
.order_by('page__path'))
pages = defaultdict(OrderedDict)
sites = {}
for title in title_queryset:
page = pages[title.page.site.pk].get(title.page.pk, {})
@@ -50,8 +55,8 @@ def update_site_and_page_choices(lang=None):
if not title:
continue
indent = u"&nbsp;&nbsp;" * title.page.level
page_title = mark_safe(u"%s%s" % (indent, title.title))
indent = u"&nbsp;&nbsp;" * (title.page.depth - 1)
page_title = mark_safe(u"%s%s" % (indent, escape(title.title)))
site_page_choices.append((title.page.pk, page_title))
page_choices.append((sitename, site_page_choices))
@@ -65,7 +70,7 @@ def update_site_and_page_choices(lang=None):
def get_site_choices(lang=None):
from django.core.cache import cache
lang = lang or i18n.get_current_language()
site_choices = cache.get(get_site_cache_key(lang))
site_choices = cache.get(_site_cache_key(lang))
if site_choices is None:
site_choices, page_choices = update_site_and_page_choices(lang)
return site_choices
@@ -74,43 +79,12 @@ def get_site_choices(lang=None):
def get_page_choices(lang=None):
from django.core.cache import cache
lang = lang or i18n.get_current_language()
page_choices = cache.get(get_page_cache_key(lang))
page_choices = cache.get(_page_cache_key(lang))
if page_choices is None:
site_choices, page_choices = update_site_and_page_choices(lang)
return page_choices
def _get_key(prefix, lang):
return "%s-%s" % (prefix, lang)
def get_site_cache_key(lang):
return _get_key(get_cms_setting('SITE_CHOICES_CACHE_KEY'), lang)
def get_page_cache_key(lang):
return _get_key(get_cms_setting('PAGE_CHOICES_CACHE_KEY'), lang)
def _clean_many(prefix):
from django.core.cache import cache
keys = []
if settings.USE_I18N:
for lang in [language[0] for language in settings.LANGUAGES]:
keys.append(_get_key(prefix, lang))
else:
keys = [_get_key(prefix, settings.LANGUAGE_CODE)]
cache.delete_many(keys)
def clean_site_choices_cache(sender, **kwargs):
_clean_many(get_cms_setting('SITE_CHOICES_CACHE_KEY'))
def clean_page_choices_cache(sender, **kwargs):
_clean_many(get_cms_setting('PAGE_CHOICES_CACHE_KEY'))
post_save.connect(clean_page_choices_cache, sender=Page)
post_save.connect(clean_site_choices_cache, sender=Site)
post_delete.connect(clean_page_choices_cache, sender=Page)
+20 -17
View File
@@ -3,17 +3,18 @@
from itertools import chain
from django.contrib.admin.templatetags.admin_static import static
from django.contrib.auth import get_permission_codename
from django.contrib.sites.models import Site
from django.core.urlresolvers import NoReverseMatch, reverse_lazy
from django.forms.widgets import Select, MultiWidget, TextInput
from django.utils.encoding import force_text
from django.utils.html import escape, escapejs
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
from cms.forms.utils import get_site_choices, get_page_choices
from cms.models import Page, PageUser
from cms.templatetags.cms_admin import CMS_ADMIN_ICON_BASE
from cms.utils.compat.dj import force_unicode
class PageSelectWidget(MultiWidget):
@@ -39,11 +40,11 @@ class PageSelectWidget(MultiWidget):
return [site.pk, page.pk, page.pk]
site = Site.objects.get_current()
return [site.pk,None,None]
def _has_changed(self, initial, data):
# THIS IS A COPY OF django.forms.widgets.Widget._has_changed()
# (except for the first if statement)
"""
Return True if data differs from initial.
"""
@@ -58,14 +59,14 @@ class PageSelectWidget(MultiWidget):
initial_value = u''
else:
initial_value = initial
if force_unicode(initial_value) != force_unicode(data_value):
if force_text(initial_value) != force_text(data_value):
return True
return False
def render(self, name, value, attrs=None):
# THIS IS A COPY OF django.forms.widgets.MultiWidget.render()
# (except for the last line)
# value is a list of values, each corresponding to a widget
# in self.widgets.
@@ -102,9 +103,11 @@ class PageSelectWidget(MultiWidget):
var handlePageChange = function(page_id) {
if (page_id) {
$("#id_%(name)s_2 option").attr('selected', false);
$("#id_%(name)s_2 option[value=" + page_id + "]").attr('selected', true);
$("#id_%(name)s_2 option[value='" + page_id + "']").attr('selected', true);
} else {
$("#id_%(name)s_2 option[value=]").attr('selected', true);
if ($("#id_%(name)s_2").length) {
$("#id_%(name)s_2 option[value='']").attr('selected', true);
}
};
};
$("#id_%(name)s_0").change(function(){
@@ -122,7 +125,7 @@ class PageSelectWidget(MultiWidget):
})(django.jQuery);
</script>''' % {'name': name})
return mark_safe(self.format_output(output))
def format_output(self, rendered_widgets):
return u' '.join(rendered_widgets)
@@ -187,7 +190,7 @@ class PageSmartLinkWidget(TextInput):
'element_id': id_,
'placeholder_text': final_attrs.get('placeholder_text', ''),
'language_code': self.language,
'ajax_url': force_unicode(self.ajax_url)
'ajax_url': force_text(self.ajax_url)
}]
output.append(super(PageSmartLinkWidget, self).render(name, value, attrs))
@@ -207,14 +210,14 @@ class UserSelectAdminWidget(Select):
"""Special widget used in page permission inlines, because we have to render
an add user (plus) icon, but point it somewhere else - to special user creation
view, which is accessible only if user haves "add user" permissions.
Current user should be assigned to widget in form constructor as an user
Current user should be assigned to widget in form constructor as an user
attribute.
"""
def render(self, name, value, attrs=None, choices=()):
output = [super(UserSelectAdminWidget, self).render(name, value, attrs, choices)]
output = [super(UserSelectAdminWidget, self).render(name, value, attrs, choices)]
if hasattr(self, 'user') and (self.user.is_superuser or \
self.user.has_perm(PageUser._meta.app_label + '.' + PageUser._meta.get_add_permission())):
self.user.has_perm(PageUser._meta.app_label + '.' + get_permission_codename('add', PageUser._meta))):
# append + icon
add_url = '../../../cms/pageuser/add/'
output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \
@@ -250,7 +253,7 @@ class AppHookSelect(Select):
selected_html = ''
if option_value in self.app_namespaces:
data_html = mark_safe(' data-namespace="%s"' % self.app_namespaces[option_value])
data_html = mark_safe(' data-namespace="%s"' % escape(self.app_namespaces[option_value]))
else:
data_html = ''
@@ -289,11 +292,11 @@ class ApplicationConfigSelect(Select):
super(ApplicationConfigSelect, self).__init__(attrs, choices)
def render(self, name, value, attrs=None, choices=()):
output = [super(ApplicationConfigSelect, self).render(name, value, attrs, choices)]
output = list(super(ApplicationConfigSelect, self).render(name, value, attrs, choices))
output.append('<script>\n')
output.append('var apphooks_configuration = {\n')
for application, cms_app in self.app_configs.items():
output.append("'%s': [%s]," % (application, ",".join(["['%s', '%s']" % (config.pk, force_text(config)) for config in cms_app.get_configs()])))
output.append("'%s': [%s]," % (application, ",".join(["['%s', '%s']" % (config.pk, escapejs(escape(config))) for config in cms_app.get_configs()]))) # noqa
output.append('\n};\n')
output.append('var apphooks_configuration_url = {\n')
for application, cms_app in self.app_configs.items():
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+6 -5
View File
@@ -7,16 +7,17 @@ msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Afrikaans (http://www.transifex.com/projects/p/django-cms/language/af/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Afrikaans (http://www.transifex.com/divio/django-cms/language/af/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: af\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr ""
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+8 -6
View File
@@ -3,21 +3,23 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Abdelkader Maarouf <dep2g2@gmail.com>, 2015
# Ahmed H <info@draco-003.com>, 2013
msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Arabic (http://www.transifex.com/projects/p/django-cms/language/ar/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Arabic (http://www.transifex.com/divio/django-cms/language/ar/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ar\n"
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr "هل أنت متأكد من الإنتقال الى مكان آخر دون حفظ الصفحة أولاً؟"
msgstr "هل أنت متأكد من الإنتقال الى jfويب أخر دون حفظ الصفحة أولاً؟"
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+7 -6
View File
@@ -7,16 +7,17 @@ msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Belarusian (http://www.transifex.com/projects/p/django-cms/language/be/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Belarusian (http://www.transifex.com/divio/django-cms/language/be/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: be\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr ""
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+6 -5
View File
@@ -10,16 +10,17 @@ msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Bulgarian (http://www.transifex.com/projects/p/django-cms/language/bg/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Bulgarian (http://www.transifex.com/divio/django-cms/language/bg/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bg\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr "Наистина ли искате да промените раздели без първо да запазите страницата?"
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+6 -5
View File
@@ -8,16 +8,17 @@ msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Bengali (http://www.transifex.com/projects/p/django-cms/language/bn/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Bengali (http://www.transifex.com/divio/django-cms/language/bn/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: bn\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr "আপনি কি নিশ্চিত যে, আপনি পৃষ্ঠাটি সংরক্ষণ না করেই ট্যাব পরিবর্তন করতে চান?"
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+8 -7
View File
@@ -3,21 +3,22 @@
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
# Roger Pons <rogerpons@gmail.com>, 2012
# Roger Pons <rogerpons@gmail.com>, 2012,2015
msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Catalan (http://www.transifex.com/projects/p/django-cms/language/ca/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Catalan (http://www.transifex.com/divio/django-cms/language/ca/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ca\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr "Estàs segur que voleu canviar de secció sense guardar la primera pàgina?"
msgstr "Esteu segur que voleu canviar de secció sense guardar la primera pàgina?"
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+6 -5
View File
@@ -7,16 +7,17 @@ msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Chinese (Mandarin) (http://www.transifex.com/projects/p/django-cms/language/cmn/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2016-01-19 20:20+0000\n"
"Last-Translator: Martin Koistinen <mkoistinen@gmail.com>\n"
"Language-Team: Chinese (Mandarin) (http://www.transifex.com/divio/django-cms/language/cmn/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: cmn\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr ""
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+7 -5
View File
@@ -5,20 +5,22 @@
# Translators:
# Jakub Dorňák <jdornak@redhat.com>, 2013
# xlu <xlu@seznam.cz>, 2013
# xlu <xlu@seznam.cz>, 2013
msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Czech (http://www.transifex.com/projects/p/django-cms/language/cs/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Czech (http://www.transifex.com/divio/django-cms/language/cs/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: cs\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr "Určitě chcete změnit záložku bez uložení změn?"
File diff suppressed because it is too large Load Diff
+23
View File
@@ -0,0 +1,23 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2010-11-30 06:49+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Czech (Czech Republic) (http://www.transifex.com/divio/django-cms/language/cs_CZ/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: cs_CZ\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr ""
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+6 -5
View File
@@ -7,16 +7,17 @@ msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Welsh (http://www.transifex.com/projects/p/django-cms/language/cy/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Welsh (http://www.transifex.com/divio/django-cms/language/cy/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: cy\n"
"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr ""
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+7 -5
View File
@@ -5,20 +5,22 @@
# Translators:
# Kristian Øllegaard <kristian@oellegaard.com>, 2011
# Kristian Øllegaard <kristian@oellegaard.com>, 2011
# Kristian Øllegaard <kristian@oellegaard.com>, 2011
msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Danish (http://www.transifex.com/projects/p/django-cms/language/da/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Danish (http://www.transifex.com/divio/django-cms/language/da/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: da\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr "Er du sikker på du vil ændre tabs uden at gemme siden først?"
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+7 -5
View File
@@ -5,20 +5,22 @@
# Translators:
# Jonas Obrist <me@ojii.ch>, 2011
# Michael P. Jung <michael.jung@terreon.de>, 2013
# Stefan T. Oertel <me@schneck.cc>, 2015
msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: German (http://www.transifex.com/projects/p/django-cms/language/de/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: German (http://www.transifex.com/divio/django-cms/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr "Sind Sie sicher Sie wollen die Sprache ändern ohne vorher zu speichern?"
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+6 -5
View File
@@ -8,16 +8,17 @@ msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-01-12 21:31+0100\n"
"PO-Revision-Date: 2013-12-12 08:53+0000\n"
"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
"Language-Team: Greek (http://www.transifex.com/projects/p/django-cms/language/el/)\n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: Greek (http://www.transifex.com/divio/django-cms/language/el/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: el\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/cms/js/modules/cms.changeform.js:60
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr "Είσαι σίγουρος πως θες να αλλάξεις καρτέλες χωρίς να έχεις αποθηκεύσει πρώτα τη σελίδα?"
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+11 -9
View File
@@ -1,22 +1,24 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
# Translators:
# Jonas Obrist <ojiidotch@gmail.com>, 2011
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-02-22 19:10+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"POT-Creation-Date: 2016-04-26 12:22-0400\n"
"PO-Revision-Date: 2015-10-31 12:28+0000\n"
"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: English (http://www.transifex.com/digi604/django-cms/language/"
"en/)\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/cms/js/modules/cms.changeform.js:60
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr ""
msgstr "Are you sure you want to change tabs without saving the page first?"
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
+23
View File
@@ -0,0 +1,23 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-11-05 10:16-0500\n"
"PO-Revision-Date: 2010-11-30 06:49+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: English (United Kingdom) (http://www.transifex.com/divio/django-cms/language/en_GB/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: en_GB\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: static/cms/js/dist/bundle.admin.changeform.min.js:1
#: static/cms/js/modules/cms.changeform.js:75
msgid "Are you sure you want to change tabs without saving the page first?"
msgstr ""
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More