From 205592741cec8a7f367fe19499dfe8fff9183fe3 Mon Sep 17 00:00:00 2001 From: Alexandru Artimon Date: Mon, 27 Oct 2014 15:21:09 +0200 Subject: [PATCH 01/31] fixes #1566 - Search/Data List: Change style of dataset/indicator titles - set the default link color as well --- .../ckanext/hdx_theme/fanstatic/css/header.css | 10 +++++++++- .../ckanext/hdx_theme/fanstatic/css/search.css | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/header.css b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/header.css index 32e2681cb2..a30396afc8 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/header.css +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/header.css @@ -256,6 +256,12 @@ } /* END Header */ +/* Default link style */ + a, a:hover, a:focus { + color: #007ce0; + } +/* END Default link style */ + /* HDX Version display */ .logo #hdxVersion{ color: #888888; @@ -1345,6 +1351,8 @@ a, a:hover, a:focus{ } /* END Style indicator graph */ + + /* Style Show-more */ /span.is-more a.more-link, .more-link { background-color: transparent; @@ -1353,4 +1361,4 @@ a, a:hover, a:focus{ margin-left: 0; padding: 0; } -/* END Style Show-more */ \ No newline at end of file +/* END Style Show-more */ diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/search.css b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/search.css index d211ae2489..269ad896b2 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/search.css +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/search.css @@ -46,7 +46,7 @@ font-family: 'Source Sans Pro', sans-serif; font-weight: 400; font-size: 14px; - color: #000000; + color: #007ce0; letter-spacing: 0.01em; line-height: 1; } From 450be0e5a9cdaaefdcc4ce5513c0ba382f292081 Mon Sep 17 00:00:00 2001 From: Alexandru Artimon Date: Mon, 27 Oct 2014 16:55:29 +0200 Subject: [PATCH 02/31] fixes #1564 - Search/Data List: change "Preview" to "Hide Preview" when graph is shown - added functionality to swap callbacks and texts on the link - added animation when hiding graph - created set of callbacks to fix the case when a user opens a graph then opens another one without hiding the first one - fix animation on the above case --- .../hdx_theme/fanstatic/indicator_graph.js | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/indicator_graph.js b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/indicator_graph.js index b5308870ec..7b0e97594d 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/indicator_graph.js +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/indicator_graph.js @@ -12,7 +12,7 @@ ckan.module('hdx-indicator-graph', function ($, _) { if (!this.options.click_only) this._init(); else - $(this.el).click(this._onClick); + $(this.el).click(this._onClickPreview); }, c3_chart: null, filteredLocations: null, @@ -35,7 +35,7 @@ ckan.module('hdx-indicator-graph', function ($, _) { _period_type_default: "LATEST_YEAR_BY_COUNTRY", _continuous_location_initialize: true, _chart_initialized: false, - _onClick: function(){ + _onClickPreview: function(){ /** * Reset Module state */ @@ -45,13 +45,38 @@ ckan.module('hdx-indicator-graph', function ($, _) { * Click Only callback */ var container = this.ckanModule.options.container; - const cont = $("#" + container); - cont.slideUp(100); - cont.dequeue(); + var cont = $("#" + container); + if (cont.length > 0){ + $(cont.context.previewLink).trigger("click", $.proxy(this.ckanModule._onClickPreviewGenerate, this)); + } + else{ + $.proxy(this.ckanModule._onClickPreviewGenerate, this)(); + } + }, + _onClickPreviewGenerate: function (){ + var container = this.ckanModule.options.container; var parent = $(this).parents(this.ckanModule.options.parent_selector); - cont.remove(); parent.append('
'); + var cont = $("#" + container); + cont.context.previewLink = this; this.ckanModule._init(); + $(this).text("Hide preview"); + $(this).unbind("click"); + + $(this).click(this.ckanModule._onClickHidePreview); + }, + _onClickHidePreview: function (context, callback){ + $(this).text("Preview"); + $(this).unbind("click"); + $(this).click(this.ckanModule._onClickPreview); + + var container = $("#"+this.ckanModule.options.container); + container.slideUp(300, function (){ + container.remove(); + if (callback){ + callback(); + } + }); }, _init: function(){ /** From 3748838690eb18010f1d758484a5e31c003b1536 Mon Sep 17 00:00:00 2001 From: Alexandru Artimon Date: Tue, 28 Oct 2014 15:05:22 +0200 Subject: [PATCH 03/31] fixes #1517 - Main Nav changes to accomodate "Feedback" button - removed "Contact" from main menu - added Feedback button - changed new dataset button caption to "Share data" - fixed secondary menu positioning --- .../hdx_theme/fanstatic/css/header.css | 28 ++++++++++++++----- .../hdx_theme/templates/header-new.html | 6 ++-- .../ckanext/hdx_theme/templates/header.html | 6 ++-- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/header.css b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/header.css index a30396afc8..7c321fe985 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/header.css +++ b/ckanext-hdx_theme/ckanext/hdx_theme/fanstatic/css/header.css @@ -189,8 +189,6 @@ .newHeader .content .navbar nav li.submitData{ background-color: #f2645a; border-radius: 6px; - position: relative; - top: -16px; width: 200px; margin-right: 20px; } @@ -199,14 +197,17 @@ margin: 0; } - .newHeader .content .navbar nav .pull-right li.dropdown{ + .newHeader .content .navbar .pull-right { position: relative; - top: -12px; + top: -15px; + } + + .newHeader .content .navbar nav .pull-right li.dropdown{ + margin-top: 5px; } .newHeader .content .navbar nav .pull-right li.newLogin{ - position: relative; - top: -12px; + margin-top: 5px; } .navbar .nav > li.newLogin > a.btn:hover, .navbar .nav > li.newLogin > a.btn:focus{ @@ -1354,7 +1355,7 @@ a, a:hover, a:focus{ /* Style Show-more */ -/span.is-more a.more-link, .more-link { +span.is-more a.more-link, .more-link { background-color: transparent; border: 0 none; border-radius: 0; @@ -1362,3 +1363,16 @@ a, a:hover, a:focus{ padding: 0; } /* END Style Show-more */ + + +/* Feedback Button */ + #feedback-button { + background-color: #888888; + color: #ffffff; + line-height: 20px; + text-shadow: none; + border-radius: 20px; + margin-top: 10px; + margin-right: 15px; + } +/* END Feedback Button */ \ No newline at end of file diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/header-new.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/header-new.html index ef81dcf9e1..92a516a2da 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/header-new.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/header-new.html @@ -28,7 +28,6 @@

  • {{ _("Countries")}}
  • {{ _('Organizations') }}
  • {{ _('Blog') }}
  • -
  • {{ _('Contact') }}
  • {{ _('About') }}
  • {% endblock %} @@ -36,9 +35,12 @@

    + + +
    - + Feedback
    diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/header.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/header.html index 96a7b1dda1..cfcb98daf4 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/header.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/header.html @@ -52,7 +52,7 @@

    {% endblock %} - + Feedback
    From d8e160bfe5eca029edd657d01f553517b9ca2c47 Mon Sep 17 00:00:00 2001 From: Dan Mihaila Date: Mon, 3 Nov 2014 15:19:05 +0200 Subject: [PATCH 28/31] fixing sitemap name plugin --- ckanext-sitemap/setup.py | 47 ++++++++++++++++++++-------------------- common-config-ini.txt | 2 +- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/ckanext-sitemap/setup.py b/ckanext-sitemap/setup.py index 0b591644f3..723f003c6d 100644 --- a/ckanext-sitemap/setup.py +++ b/ckanext-sitemap/setup.py @@ -1,32 +1,33 @@ from setuptools import setup, find_packages -import sys, os +import sys +import os version = '0.1' setup( - name='ckanext-sitemap', - version=version, - description="Sitemap extension for CKAN", - long_description="""\ + name='ckanext-sitemap', + version=version, + description="Sitemap extension for CKAN", + long_description="""\ """, - classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers - keywords='', - author='Aleksi Suomalainen', - author_email='aleksi.suomalainen@nomovok.com', - url='https://github.com/locusf/ckanext-sitemap', - license='AGPL', - packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), - namespace_packages=['ckanext', 'ckanext.sitemap'], - include_package_data=True, - zip_safe=False, - install_requires=[ - # -*- Extra requirements: -*- - ], - setup_requires=[ - 'nose' - ], - entry_points=\ - """ + classifiers=[ + ], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + keywords='', + author='Aleksi Suomalainen', + author_email='aleksi.suomalainen@nomovok.com', + url='https://github.com/locusf/ckanext-sitemap', + license='AGPL', + packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), + namespace_packages=['ckanext', 'ckanext.sitemap'], + include_package_data=True, + zip_safe=False, + install_requires=[ + # -*- Extra requirements: -*- + ], + setup_requires=[ + 'nose' + ], + entry_points=""" [ckan.plugins] # Add plugins here, eg sitemap=ckanext.sitemap.plugin:SitemapPlugin diff --git a/common-config-ini.txt b/common-config-ini.txt index a59b4dbce7..a1176bdfba 100644 --- a/common-config-ini.txt +++ b/common-config-ini.txt @@ -76,7 +76,7 @@ ckan.site_id = default # Add ``resource_proxy`` to enable resorce proxying and get around the # same origin policy #ckan.plugins_deprecated = hdx_orgs register metadata_fields dataset_auth ungroups hdx_theme stats text_preview recline_preview -ckan.plugins = hdx_search hdx_sitemap hdx_org_group hdx_package hdx_users hdx_theme stats text_preview recline_preview +ckan.plugins = hdx_search sitemap hdx_org_group hdx_package hdx_users hdx_theme stats text_preview recline_preview ## Front-End Settings From 82451d3b3e93f9a41bd5972b63d03fc118e6e6be Mon Sep 17 00:00:00 2001 From: Marianne Bellotti Date: Mon, 3 Nov 2014 08:59:51 -0500 Subject: [PATCH 29/31] should be private= False not private = 0 --- ckanext-pages/.gitignore | 10 + ckanext-pages/README.md | 33 +++ ckanext-pages/ckanext/__init__.py | 8 + ckanext-pages/ckanext/pages/__init__.py | 7 + ckanext-pages/ckanext/pages/actions.py | 219 ++++++++++++++ ckanext-pages/ckanext/pages/auth.py | 64 ++++ ckanext-pages/ckanext/pages/controller.py | 279 ++++++++++++++++++ ckanext-pages/ckanext/pages/db.py | 123 ++++++++ ckanext-pages/ckanext/pages/plugin.py | 147 +++++++++ .../templates_group/group/read_base.html | 6 + .../templates_main/ckanext_pages/base.html | 17 ++ .../ckanext_pages/base_form.html | 117 ++++++++ .../ckanext_pages/confirm_delete.html | 22 ++ .../ckanext_pages/edit_base.html | 3 + .../ckanext_pages/group_page.html | 13 + .../ckanext_pages/group_page_edit.html | 7 + .../ckanext_pages/group_page_list.html | 14 + .../ckanext_pages/organization_page.html | 13 + .../ckanext_pages/organization_page_edit.html | 7 + .../ckanext_pages/organization_page_list.html | 14 + .../templates_main/ckanext_pages/page.html | 19 ++ .../ckanext_pages/pages_edit.html | 7 + .../ckanext_pages/pages_list.html | 12 + .../ckanext_pages/snippets/pages_list.html | 28 ++ .../pages/theme/templates_main/header.html | 10 + .../organization/read_base.html | 6 + ckanext-pages/setup.py | 29 ++ ckanext-sitemap/ckanext/sitemap/controller.py | 4 +- 28 files changed, 1236 insertions(+), 2 deletions(-) create mode 100644 ckanext-pages/.gitignore create mode 100644 ckanext-pages/README.md create mode 100644 ckanext-pages/ckanext/__init__.py create mode 100644 ckanext-pages/ckanext/pages/__init__.py create mode 100644 ckanext-pages/ckanext/pages/actions.py create mode 100644 ckanext-pages/ckanext/pages/auth.py create mode 100644 ckanext-pages/ckanext/pages/controller.py create mode 100644 ckanext-pages/ckanext/pages/db.py create mode 100644 ckanext-pages/ckanext/pages/plugin.py create mode 100644 ckanext-pages/ckanext/pages/theme/templates_group/group/read_base.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base_form.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/confirm_delete.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/edit_base.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_edit.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_list.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_edit.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_list.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/page.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_edit.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_list.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/snippets/pages_list.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/header.html create mode 100644 ckanext-pages/ckanext/pages/theme/templates_organization/organization/read_base.html create mode 100644 ckanext-pages/setup.py diff --git a/ckanext-pages/.gitignore b/ckanext-pages/.gitignore new file mode 100644 index 0000000000..595975452c --- /dev/null +++ b/ckanext-pages/.gitignore @@ -0,0 +1,10 @@ +*.egg-info +*.pyc +*.swp +*.swo +*~ +#* +.#* +build/ +dist/ +distribute-* \ No newline at end of file diff --git a/ckanext-pages/README.md b/ckanext-pages/README.md new file mode 100644 index 0000000000..30cb98b272 --- /dev/null +++ b/ckanext-pages/README.md @@ -0,0 +1,33 @@ +ckanext-pages +============= + +This extension gives you an easy way to add simple pages to CKAN. + +By default you can add pages to the main CKAN menu. + + + +Extra config options allow you to control the creation of extra pages against groups and organizations. + +To swich on this behaviour, to your config add: + +``` +ckanext.pages.organization = True +ckanext.pages.group = True +``` + +These options are False by default and this feature is experimental. + + +This module also gives you a quick way to remove default elements from the CKAN menu and you may need todo this +in order for you to have space for the new items you add. These options are: + +``` +ckanext.pages.about_menu = False +ckanext.pages.group_menu = False +ckanext.pages.organization_menu = False +``` + +By default these are all set to True, like on a default install. + + diff --git a/ckanext-pages/ckanext/__init__.py b/ckanext-pages/ckanext/__init__.py new file mode 100644 index 0000000000..bf99a9da02 --- /dev/null +++ b/ckanext-pages/ckanext/__init__.py @@ -0,0 +1,8 @@ +# this is a namespace package +try: + import pkg_resources + pkg_resources.declare_namespace(__name__) +except ImportError: + import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) + diff --git a/ckanext-pages/ckanext/pages/__init__.py b/ckanext-pages/ckanext/pages/__init__.py new file mode 100644 index 0000000000..2e2033b3c0 --- /dev/null +++ b/ckanext-pages/ckanext/pages/__init__.py @@ -0,0 +1,7 @@ +# this is a namespace package +try: + import pkg_resources + pkg_resources.declare_namespace(__name__) +except ImportError: + import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/ckanext-pages/ckanext/pages/actions.py b/ckanext-pages/ckanext/pages/actions.py new file mode 100644 index 0000000000..a52d37f264 --- /dev/null +++ b/ckanext-pages/ckanext/pages/actions.py @@ -0,0 +1,219 @@ +import datetime + +import ckan.plugins as p +import ckan.lib.navl.dictization_functions as df +import ckan.new_authz as new_authz + +import db +def page_name_validator(key, data, errors, context): + session = context['session'] + page = context.get('page') + group_id = context.get('group_id') + if page and page == data[key]: + return + + query = session.query(db.Page.name).filter_by(name=data[key], group_id=group_id) + result = query.first() + if result: + errors[key].append( + p.toolkit._('Page name already exists in database')) + +schema = { + 'id': [p.toolkit.get_validator('ignore_empty'), unicode], + 'title': [p.toolkit.get_validator('not_empty'), unicode], + 'name': [p.toolkit.get_validator('not_empty'), unicode, + p.toolkit.get_validator('name_validator'), page_name_validator], + 'content': [p.toolkit.get_validator('ignore_missing'), unicode], + # 'lang': [p.toolkit.get_validator('not_empty'), unicode], + 'order': [p.toolkit.get_validator('ignore_missing'), + unicode], + 'private': [p.toolkit.get_validator('ignore_missing'), + p.toolkit.get_validator('boolean_validator')], + 'group_id': [p.toolkit.get_validator('ignore_missing'), unicode], + 'user_id': [p.toolkit.get_validator('ignore_missing'), unicode], + 'created': [p.toolkit.get_validator('ignore_missing'), + p.toolkit.get_validator('isodate')], +} + + +def _pages_show(context, data_dict): + if db.pages_table is None: + db.init_db(context['model']) + org_id = data_dict.get('org_id') + page = data_dict.get('page') + out = db.Page.get(group_id=org_id, name=page) + if out: + out = db.table_dictize(out, context) + return out + + +def _pages_list(context, data_dict): + search = {} + if db.pages_table is None: + db.init_db(context['model']) + org_id = data_dict.get('org_id') + ordered = data_dict.get('order') + private = data_dict.get('private', True) + if ordered: + search['order'] = True + if not org_id: + search['group_id'] = None + try: + p.toolkit.check_access('ckanext_pages_update', context, data_dict) + if not private: + search['private'] = False + except p.toolkit.NotAuthorized: + search['private'] = False + else: + group = context['model'].Group.get(org_id) + user = context['user'] + member = new_authz.has_user_permission_for_group_or_org( + group.id, user, 'read') + search['group_id'] = org_id + if not member: + search['private'] = False + out = db.Page.pages(**search) + return [{'title': pg.title, + 'content': pg.content, + 'name': pg.name, + 'group_id': pg.group_id, + } for pg in out] + + +def _pages_delete(context, data_dict): + if db.pages_table is None: + db.init_db(context['model']) + org_id = data_dict.get('org_id') + page = data_dict.get('page') + out = db.Page.get(group_id=org_id, name=page) + if out: + session = context['session'] + session.delete(out) + session.commit() + + +def _pages_update(context, data_dict): + if db.pages_table is None: + db.init_db(context['model']) + org_id = data_dict.get('org_id') + page = data_dict.get('page') + # we need the page in the context for name validation + context['page'] = page + context['group_id'] = org_id + + data, errors = df.validate(data_dict, schema, context) + + if errors: + raise p.toolkit.ValidationError(errors) + + out = db.Page.get(group_id=org_id, name=page) + if not out: + out = db.Page() + out.group_id = org_id + out.name = page + items = ['title', 'content', 'name', 'private', 'order'] + for item in items: + setattr(out, item, data.get(item)) + + out.modified = datetime.datetime.utcnow() + out.user_id = p.toolkit.c.userobj.id + out.save() + session = context['session'] + session.add(out) + session.commit() + + +def pages_show(context, data_dict): + try: + p.toolkit.check_access('ckanext_pages_show', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_show(context, data_dict) + + +def pages_update(context, data_dict): + try: + p.toolkit.check_access('ckanext_pages_update', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_update(context, data_dict) + + +def pages_delete(context, data_dict): + try: + p.toolkit.check_access('ckanext_pages_delete', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_delete(context, data_dict) + + +def pages_list(context, data_dict): + try: + p.toolkit.check_access('ckanext_pages_list', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_list(context, data_dict) + + +def org_pages_show(context, data_dict): + try: + p.toolkit.check_access('ckanext_org_pages_show', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_show(context, data_dict) + + +def org_pages_update(context, data_dict): + try: + p.toolkit.check_access('ckanext_org_pages_update', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_update(context, data_dict) + + +def org_pages_delete(context, data_dict): + try: + p.toolkit.check_access('ckanext_org_pages_delete', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_delete(context, data_dict) + + +def org_pages_list(context, data_dict): + try: + p.toolkit.check_access('ckanext_org_pages_list', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_list(context, data_dict) + + +def group_pages_show(context, data_dict): + try: + p.toolkit.check_access('ckanext_group_pages_show', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_show(context, data_dict) + + +def group_pages_update(context, data_dict): + try: + p.toolkit.check_access('ckanext_group_pages_update', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_update(context, data_dict) + + +def group_pages_delete(context, data_dict): + try: + p.toolkit.check_access('ckanext_group_pages_delete', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_delete(context, data_dict) + + +def group_pages_list(context, data_dict): + try: + p.toolkit.check_access('ckanext_group_pages_list', context, data_dict) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) + return _pages_list(context, data_dict) diff --git a/ckanext-pages/ckanext/pages/auth.py b/ckanext-pages/ckanext/pages/auth.py new file mode 100644 index 0000000000..7449b78aa2 --- /dev/null +++ b/ckanext-pages/ckanext/pages/auth.py @@ -0,0 +1,64 @@ +import ckan.plugins as p +import ckan.new_authz as new_authz + +import db + + +def sysadmin(context, data_dict): + return {'success': False} + +def anyone(context, data_dict): + return {'success': True} + +def group_admin(context, data_dict): + return p.toolkit.check_access('group_update', context, data_dict) + + +def org_admin(context, data_dict): + return p.toolkit.check_access('group_update', context, data_dict) + + +def page_privacy(context, data_dict): + if db.pages_table is None: + db.init_db(context['model']) + org_id = data_dict.get('org_id') + page = data_dict.get('page') + out = db.Page.get(group_id=org_id, name=page) + if out and out.private == False: + return {'success': True} + # no org_id means it's a universal page + if not org_id: + if out and out.private: + return {'success': False} + return {'success': True} + group = context['model'].Group.get(org_id) + user = context['user'] + authorized = new_authz.has_user_permission_for_group_or_org(group.id, + user, + 'read') + if not authorized: + return {'success': False, + 'msg': p.toolkit._( + 'User %s not authorized to read this page') % user} + else: + return {'success': True} + +# Starting from 2.2 you need to explicitly flag auth functions that allow +# anonymous access +if p.toolkit.check_ckan_version(min_version='2.2'): + anyone = p.toolkit.auth_allow_anonymous_access(anyone) + page_privacy = p.toolkit.auth_allow_anonymous_access(page_privacy) + + +pages_show = page_privacy +pages_update = sysadmin +pages_delete = sysadmin +pages_list = anyone +org_pages_show = page_privacy +org_pages_update = org_admin +org_pages_delete = org_admin +org_pages_list = anyone +group_pages_show = page_privacy +group_pages_update = group_admin +group_pages_delete = group_admin +group_pages_list = anyone diff --git a/ckanext-pages/ckanext/pages/controller.py b/ckanext-pages/ckanext/pages/controller.py new file mode 100644 index 0000000000..c832883f14 --- /dev/null +++ b/ckanext-pages/ckanext/pages/controller.py @@ -0,0 +1,279 @@ +import ckan.plugins as p + +_ = p.toolkit._ + +class PagesController(p.toolkit.BaseController): + controller = 'ckanext.pages.controller:PagesController' + + def _get_group_dict(self, id): + ''' returns the result of group_show action or aborts if there is a + problem ''' + + def _template_setup_org(self, id): + if not id: + return + # we need the org for the rest of the page + context = {'for_view': True} + try: + p.toolkit.c.group_dict = p.toolkit.get_action('organization_show')(context, {'id': id}) + except p.toolkit.ObjectNotFound: + p.toolkit.abort(404, _('Organization not found')) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, _('Unauthorized to read organization %s') % id) + + def org_show(self, id, page=None): + if page: + page = page[1:] + self._template_setup_org(id) + if page is '': + return self._org_list_pages(id) + _page = p.toolkit.get_action('ckanext_pages_show')( + data_dict={'org_id': p.toolkit.c.group_dict['id'], + 'page': page,} + ) + if _page is None: + return self._org_list_pages(id) + p.toolkit.c.page = _page + return p.toolkit.render('ckanext_pages/organization_page.html') + + def _org_list_pages(self, id): + p.toolkit.c.pages_dict = p.toolkit.get_action('ckanext_pages_list')( + data_dict={'org_id': p.toolkit.c.group_dict['id']} + ) + return p.toolkit.render('ckanext_pages/organization_page_list.html') + + + def org_delete(self, id, page): + self._template_setup_org(id) + page = page[1:] + if 'cancel' in p.toolkit.request.params: + p.toolkit.redirect_to(controller=self.controller, action='org_edit', id=p.toolkit.c.group_dict['name'], page='/' + page) + + ## try: + ## self._check_access('group_delete', {}, {'id': id}) + ## except p.toolkit.NotAuthorized: + ## p.toolkit.abort(401, _('Unauthorized to delete page')) + + try: + if p.toolkit.request.method == 'POST': + p.toolkit.get_action('ckanext_pages_delete')({}, {'org_id': p.toolkit.c.group_dict['id'], 'page': page}) + p.toolkit.redirect_to(controller=self.controller, action='org_show', id=id, page='') + else: + p.toolkit.abort(404, _('Page Not Found')) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, _('Unauthorized to delete page')) + except p.toolkit.ObjectNotFound: + p.toolkit.abort(404, _('Group not found')) + return p.toolkit.render('ckanext_pages/confirm_delete.html', {'page': page}) + + + def org_edit(self, id, page=None, data=None, errors=None, error_summary=None): + self._template_setup_org(id) + if page: + page = page[1:] + _page = p.toolkit.get_action('ckanext_pages_show')( + data_dict={'org_id': p.toolkit.c.group_dict['id'], + 'page': page,} + ) + if _page is None: + _page = {} + + if p.toolkit.request.method == 'POST' and not data: + data = p.toolkit.request.POST + items = ['title', 'name', 'content', 'private'] + # update config from form + for item in items: + if item in data: + _page[item] = data[item] + _page['org_id'] = p.toolkit.c.group_dict['id'], + _page['page'] = page + try: + junk = p.toolkit.get_action('ckanext_pages_update')( + data_dict=_page + ) + except p.toolkit.ValidationError, e: + errors = e.error_dict + error_summary = e.error_summary + return self.org_edit(id, '/' + page, data, + errors, error_summary) + p.toolkit.redirect_to(p.toolkit.url_for('organization_pages', id=id, page='/' + _page['name'])) + + if not data: + data = _page + + errors = errors or {} + error_summary = error_summary or {} + + vars = {'data': data, 'errors': errors, + 'error_summary': error_summary, 'page': page} + + return p.toolkit.render('ckanext_pages/organization_page_edit.html', + extra_vars=vars) + + def _template_setup_group(self, id): + if not id: + return + # we need the org for the rest of the page + context = {'for_view': True} + try: + p.toolkit.c.group_dict = p.toolkit.get_action('group_show')(context, {'id': id}) + except p.toolkit.ObjectNotFound: + p.toolkit.abort(404, _('Group not found')) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, _('Unauthorized to read group %s') % id) + + + def group_show(self, id, page=None): + if page: + page = page[1:] + self._template_setup_group(id) + if page is '': + return self._group_list_pages(id) + _page = p.toolkit.get_action('ckanext_pages_show')( + data_dict={'org_id': p.toolkit.c.group_dict['id'], + 'page': page,} + ) + if _page is None: + return self._group_list_pages(id) + p.toolkit.c.page = _page + return p.toolkit.render('ckanext_pages/group_page.html') + + def _group_list_pages(self, id): + p.toolkit.c.pages_dict = p.toolkit.get_action('ckanext_pages_list')( + data_dict={'org_id': p.toolkit.c.group_dict['id']} + ) + return p.toolkit.render('ckanext_pages/group_page_list.html') + + def group_edit(self, id, page=None, data=None, errors=None, error_summary=None): + self._template_setup_group(id) + if page: + page = page[1:] + _page = p.toolkit.get_action('ckanext_pages_show')( + data_dict={'org_id': p.toolkit.c.group_dict['id'], + 'page': page,} + ) + if _page is None: + _page = {} + + if p.toolkit.request.method == 'POST' and not data: + data = p.toolkit.request.POST + items = ['title', 'name', 'content', 'private'] + # update config from form + for item in items: + if item in data: + _page[item] = data[item] + _page['org_id'] = p.toolkit.c.group_dict['id'] + _page['page'] = page + try: + junk = p.toolkit.get_action('ckanext_pages_update')( + data_dict=_page + ) + except p.toolkit.ValidationError, e: + errors = e.error_dict + error_summary = e.error_summary + return self.group_edit(id, '/' + page, data, + errors, error_summary) + p.toolkit.redirect_to(p.toolkit.url_for('group_pages', id=id, page='/' + _page['name'])) + + if not data: + data = _page + + errors = errors or {} + error_summary = error_summary or {} + + vars = {'data': data, 'errors': errors, + 'error_summary': error_summary, 'page': page} + + return p.toolkit.render('ckanext_pages/group_page_edit.html', + extra_vars=vars) + + + def pages_show(self, page=None): + if page: + page = page[1:] + if not page: + return self._pages_list_pages() + _page = p.toolkit.get_action('ckanext_pages_show')( + data_dict={'org_id': None, + 'page': page,} + ) + if _page is None: + return self._pages_list_pages() + p.toolkit.c.page = _page + return p.toolkit.render('ckanext_pages/page.html') + + def _pages_list_pages(self): + p.toolkit.c.pages_dict = p.toolkit.get_action('ckanext_pages_list')( + data_dict={'org_id': None} + ) + return p.toolkit.render('ckanext_pages/pages_list.html') + + def pages_delete(self, page): + page = page[1:] + if 'cancel' in p.toolkit.request.params: + p.toolkit.redirect_to(controller=self.controller, action='pages_edit', page='/' + page) + + + try: + if p.toolkit.request.method == 'POST': + p.toolkit.get_action('ckanext_pages_delete')({}, {'page': page}) + p.toolkit.redirect_to(controller=self.controller, action='pages_show', page='') + else: + p.toolkit.abort(404, _('Page Not Found')) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, _('Unauthorized to delete page')) + except p.toolkit.ObjectNotFound: + p.toolkit.abort(404, _('Group not found')) + return p.toolkit.render('ckanext_pages/confirm_delete.html', {'page': page}) + + + def pages_edit(self, page=None, data=None, errors=None, error_summary=None): + if page: + page = page[1:] + _page = p.toolkit.get_action('ckanext_pages_show')( + data_dict={'org_id': None, + 'page': page,} + ) + if _page is None: + _page = {} + + if p.toolkit.request.method == 'POST' and not data: + data = p.toolkit.request.POST + items = ['title', 'name', 'content', 'private', 'order'] + + # update config from form + for item in items: + if item in data: + _page[item] = data[item] + _page['org_id'] = None + _page['page'] = page + try: + junk = p.toolkit.get_action('ckanext_pages_update')( + data_dict=_page + ) + except p.toolkit.ValidationError, e: + errors = e.error_dict + error_summary = e.error_summary + return self.pages_edit('/' + page, data, + errors, error_summary) + p.toolkit.redirect_to(p.toolkit.url_for('pages_show', page='/' + _page['name'])) + + try: + p.toolkit.check_access('ckanext_pages_update', {'user': p.toolkit.c.user or p.toolkit.c.author}) + except p.toolkit.NotAuthorized: + p.toolkit.abort(401, _('Unauthorized to create or edit a page')) + + if not data: + data = _page + + errors = errors or {} + error_summary = error_summary or {} + + vars = {'data': data, 'errors': errors, + 'error_summary': error_summary, 'page': page} + + return p.toolkit.render('ckanext_pages/pages_edit.html', + extra_vars=vars) + + + diff --git a/ckanext-pages/ckanext/pages/db.py b/ckanext-pages/ckanext/pages/db.py new file mode 100644 index 0000000000..0695c58d55 --- /dev/null +++ b/ckanext-pages/ckanext/pages/db.py @@ -0,0 +1,123 @@ +import datetime +import uuid + +import sqlalchemy as sa +from sqlalchemy.orm import class_mapper + + +pages_table = None +Page = None + + +def make_uuid(): + return unicode(uuid.uuid4()) + + +def init_db(model): + class _Page(model.DomainObject): + + @classmethod + def get(cls, **kw): + '''Finds a single entity in the register.''' + query = model.Session.query(cls).autoflush(False) + return query.filter_by(**kw).first() + + @classmethod + def pages(cls, **kw): + '''Finds a single entity in the register.''' + order = kw.pop('order', False) + + query = model.Session.query(cls).autoflush(False) + query = query.filter_by(**kw) + if order: + query = query.order_by(cls.order).filter(cls.order != '') + return query.all() + + global Page + Page = _Page + # We will just try to create the table. If it already exists we get an + # error but we can just skip it and carry on. + sql = ''' + CREATE TABLE ckanext_pages ( + id text NOT NULL, + title text, + name text, + content text, + lang text, + "order" text, + private boolean, + group_id text, + user_id text NOT NULL, + created timestamp without time zone, + modified timestamp without time zone + ); + ''' + conn = model.Session.connection() + try: + conn.execute(sql) + except sa.exc.ProgrammingError: + pass + model.Session.commit() + + types = sa.types + global pages_table + pages_table = sa.Table('ckanext_pages', model.meta.metadata, + sa.Column('id', types.UnicodeText, primary_key=True, default=make_uuid), + sa.Column('title', types.UnicodeText, default=u''), + sa.Column('name', types.UnicodeText, default=u''), + sa.Column('content', types.UnicodeText, default=u''), + sa.Column('lang', types.UnicodeText, default=u''), + sa.Column('order', types.UnicodeText, default=u''), + sa.Column('private',types.Boolean,default=True), + sa.Column('group_id', types.UnicodeText, default=None), + sa.Column('user_id', types.UnicodeText, default=u''), + sa.Column('created', types.DateTime, default=datetime.datetime.utcnow), + sa.Column('modified', types.DateTime, default=datetime.datetime.utcnow), + ) + + model.meta.mapper( + Page, + pages_table, + ) + + +def table_dictize(obj, context, **kw): + '''Get any model object and represent it as a dict''' + result_dict = {} + + if isinstance(obj, sa.engine.base.RowProxy): + fields = obj.keys() + else: + ModelClass = obj.__class__ + table = class_mapper(ModelClass).mapped_table + fields = [field.name for field in table.c] + + for field in fields: + name = field + if name in ('current', 'expired_timestamp', 'expired_id'): + continue + if name == 'continuity_id': + continue + value = getattr(obj, name) + if value is None: + result_dict[name] = value + elif isinstance(value, dict): + result_dict[name] = value + elif isinstance(value, int): + result_dict[name] = value + elif isinstance(value, datetime.datetime): + result_dict[name] = value.isoformat() + elif isinstance(value, list): + result_dict[name] = value + else: + result_dict[name] = unicode(value) + + result_dict.update(kw) + + ##HACK For optimisation to get metadata_modified created faster. + + context['metadata_modified'] = max(result_dict.get('revision_timestamp', ''), + context.get('metadata_modified', '')) + + return result_dict + diff --git a/ckanext-pages/ckanext/pages/plugin.py b/ckanext-pages/ckanext/pages/plugin.py new file mode 100644 index 0000000000..194b89d0cf --- /dev/null +++ b/ckanext-pages/ckanext/pages/plugin.py @@ -0,0 +1,147 @@ +import logging +from pylons import config + +import ckan.plugins as p +import ckan.lib.helpers as h + +import actions +import auth + +log = logging.getLogger(__name__) + +def build_pages_nav_main(*args): + + about_menu = p.toolkit.asbool(config.get('ckanext.pages.about_menu', True)) + group_menu = p.toolkit.asbool(config.get('ckanext.pages.group_menu', True)) + org_menu = p.toolkit.asbool(config.get('ckanext.pages.organization_menu', True)) + + new_args = [] + for arg in args: + if arg[0] == 'about' and not about_menu: + continue + if arg[0] == 'organizations_index' and not org_menu: + continue + if arg[0] == 'group_index' and not group_menu: + continue + new_args.append(arg) + + output = h.build_nav_main(*new_args) + + # do not display any private datasets in menu even for sysadmins + pages_list = p.toolkit.get_action('ckanext_pages_list')(None, {'order': True, 'private': False}) + + page_name = '' + + if (p.toolkit.c.action == 'pages_show' + and p.toolkit.c.controller == 'ckanext.pages.controller:PagesController'): + page_name = p.toolkit.c.environ['routes.url'].current().split('/')[-1] + + for page in pages_list: + link = h.link_to(page.get('title'), + h.url_for('/pages/' + str(page['name']))) + + if page['name'] == page_name: + li = h.literal('
  • ') + link + h.literal('
  • ') + else: + li = h.literal('
  • ') + link + h.literal('
  • ') + output = output + li + + return output + + + +class PagesPlugin(p.SingletonPlugin): + p.implements(p.IConfigurer, inherit=True) + p.implements(p.ITemplateHelpers, inherit=True) + p.implements(p.IConfigurable, inherit=True) + p.implements(p.IRoutes, inherit=True) + p.implements(p.IActions, inherit=True) + p.implements(p.IAuthFunctions, inherit=True) + + def update_config(self, config): + self.organization_pages = p.toolkit.asbool(config.get('ckanext.pages.organization', False)) + self.group_pages = p.toolkit.asbool(config.get('ckanext.pages.group', False)) + + p.toolkit.add_template_directory(config, 'theme/templates_main') + if self.group_pages: + p.toolkit.add_template_directory(config, 'theme/templates_group') + if self.organization_pages: + p.toolkit.add_template_directory(config, 'theme/templates_organization') + + + def configure(self, config): + return + + def get_helpers(self): + return { + 'build_nav_main': build_pages_nav_main + } + + def after_map(self, map): + controller = 'ckanext.pages.controller:PagesController' + + if self.organization_pages: + map.connect('organization_pages_delete', '/organization/pages_delete/{id}{page:/.*|}', + action='org_delete', ckan_icon='delete', controller=controller) + map.connect('organization_pages_edit', '/organization/pages_edit/{id}{page:/.*|}', + action='org_edit', ckan_icon='edit', controller=controller) + map.connect('organization_pages', '/organization/pages/{id}{page:/.*|}', + action='org_show', ckan_icon='file', controller=controller, highlight_actions='org_edit org_show') + + if self.group_pages: + map.connect('group_pages_delete', '/group/pages_delete/{id}{page:/.*|}', + action='group_delete', ckan_icon='delete', controller=controller) + map.connect('group_pages_edit', '/group/pages_edit/{id}{page:/.*|}', + action='group_edit', ckan_icon='edit', controller=controller) + map.connect('group_pages', '/group/pages/{id}{page:/.*|}', + action='group_show', ckan_icon='file', controller=controller, highlight_actions='group_edit group_show') + + + map.connect('pages_delete', '/pages_delete{page:/.*|}', + action='pages_delete', ckan_icon='delete', controller=controller) + map.connect('pages_edit', '/pages_edit{page:/.*|}', + action='pages_edit', ckan_icon='edit', controller=controller) + map.connect('pages_show', '/pages{page:/.*|}', + action='pages_show', ckan_icon='file', controller=controller, highlight_actions='pages_edit pages_show') + return map + + def get_actions(self): + actions_dict = { + 'ckanext_pages_show': actions.pages_show, + 'ckanext_pages_update': actions.pages_update, + 'ckanext_pages_delete': actions.pages_delete, + 'ckanext_pages_list': actions.pages_list, + } + if self.organization_pages: + org_actions={ + 'ckanext_org_pages_show': actions.org_pages_show, + 'ckanext_org_pages_update': actions.org_pages_update, + 'ckanext_org_pages_delete': actions.org_pages_delete, + 'ckanext_org_pages_list': actions.org_pages_list, + } + actions_dict.update(org_actions) + if self.group_pages: + group_actions={ + 'ckanext_group_pages_show': actions.group_pages_show, + 'ckanext_group_pages_update': actions.group_pages_update, + 'ckanext_group_pages_delete': actions.group_pages_delete, + 'ckanext_group_pages_list': actions.group_pages_list, + } + actions_dict.update(group_actions) + return actions_dict + + def get_auth_functions(self): + return { + 'ckanext_pages_show': auth.pages_show, + 'ckanext_pages_update': auth.pages_update, + 'ckanext_pages_delete': auth.pages_delete, + 'ckanext_pages_list': auth.pages_list, + 'ckanext_org_pages_show': auth.org_pages_show, + 'ckanext_org_pages_update': auth.org_pages_update, + 'ckanext_org_pages_delete': auth.org_pages_delete, + 'ckanext_org_pages_list': auth.org_pages_list, + 'ckanext_group_pages_show': auth.group_pages_show, + 'ckanext_group_pages_update': auth.group_pages_update, + 'ckanext_group_pages_delete': auth.group_pages_delete, + 'ckanext_group_pages_list': auth.group_pages_list, + } diff --git a/ckanext-pages/ckanext/pages/theme/templates_group/group/read_base.html b/ckanext-pages/ckanext/pages/theme/templates_group/group/read_base.html new file mode 100644 index 0000000000..62c2bffa3d --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_group/group/read_base.html @@ -0,0 +1,6 @@ +{% ckan_extends %} + +{% block content_primary_nav %} + {{ super() }} + {{ h.build_nav_icon('group_pages', _('Pages'), id=c.group_dict.name, page='') }} +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base.html new file mode 100644 index 0000000000..a639da7682 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base.html @@ -0,0 +1,17 @@ +{% extends 'page.html' %} + +{% block page_header %}{% endblock %} + +{% block secondary_content %} +
    +

    + + {{ _('What are Pages?') }} +

    +
    + {% trans %} +

    Pages are are simple way to add extra pages to your ckan instance. You can assign an order to them.

    + {% endtrans %} +
    +
    +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base_form.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base_form.html new file mode 100644 index 0000000000..8ebc0dc4ef --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base_form.html @@ -0,0 +1,117 @@ +{% import 'macros/form.html' as form %} + +{% if type == 'org' %} + {% set action_url = h.url_for('organization_pages_edit', id=id, page='/' + page) %} + {% set cancel_url = h.url_for('organization_pages', id=id, page='') %} + {% set slug_prefix = cancel_url ~ '/' %} + {% set slug_domain = h.url_for('organization_pages', id=id, page='', qualified=true) %} + {% set hide_field_order = true %} +{% elif type == 'group' %} + {% set action_url = h.url_for('group_pages_edit', id=id, page='/' + page) %} + {% set cancel_url = h.url_for('group_pages', id=id, page='') %} + {% set slug_prefix = cancel_url ~ '/' %} + {% set slug_domain = h.url_for('group_pages', id=id, page='', qualified=true) %} + {% set hide_field_order = true %} +{% else %} + {% set action_url = h.url_for('pages_edit', page='/' + page) %} + {% set cancel_url = h.url_for('pages_show', page='') %} + {% set slug_prefix = cancel_url ~ '/' %} + {% set slug_domain = h.url_for('pages_show', page='', qualified=true) %} +{% endif %} + +{% set data = data or {} %} +{% set errors = errors or {} %} + +{% if not page %} +

    {{ _('Add page') }}

    +{% else %} +

    {{ _('Edit page') }}

    +{% endif %} + +
    + + {{ form.input('title', id='field-title', label=_('Title'), placeholder=_('eg. Page Title'), value=data.title, error=errors.title, classes=['control-full', 'control-large'], attrs={'data-module': 'slug-preview-target'}) }} + + {% set domain = slug_domain|replace("http://", "")|replace("https://", "") %} + {% set attrs = {'data-module': 'slug-preview-slug', 'data-module-prefix': domain~'/', 'data-module-placeholder': ''} %} + {{ form.prepend('name', id='field-name', label=_('URL'), prepend=slug_prefix, placeholder=_('eg. my-page'), value=data.name, error=errors.name, attrs=attrs) }} + + {#{{ form.input('name', id='field-name', label=_('Name'), placeholder=_('my-name'), value=data.name, error=errors.name, classes=['control-full']) }}#} + +
    + +
    + +
    +
    + + {% if not hide_field_order %} +
    + +
    + +
    +
    + + {% endif %} +{# data.content #} + + + + + {{ form.input('search', id='search', label=_('Search for Datasets'), placeholder=_('eg. ebola'), classes=['control-full', 'control-large']) }} + +
    + + {{ form.markdown('content', id='field-content', label=_('Content'), placeholder=_('My content'), value=data.content, error=errors.content) }} + +
    + {% if not page %} + {{ _('Cancel') }} + + {% else %} + + {% block delete_button %} + {% if h.check_access('ckanext_pages_delete', {'id': data.id}) %} + {% set locale = h.dump_json({'content': _('Are you sure you want to delete this Page?')}) %} + {% block delete_button_text %}{{ _('Delete') }}{% endblock %} + {% endif %} + {% endblock %} + + + {% endif %} +
    + + diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/confirm_delete.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/confirm_delete.html new file mode 100644 index 0000000000..6ab5f92814 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/confirm_delete.html @@ -0,0 +1,22 @@ +{% extends "page.html" %} + +{% block subtitle %}{{ _("Confirm Delete") }}{% endblock %} + +{% block maintag %}
    {% endblock %} + +{% block main_content %} +
    +
    + {% block form %} +

    {{ _('Are you sure you want to delete page - {name}?').format(name=c.page_dict.name) }}

    +

    + {% set action = form_action or h.url_for('organization_pages_delete', id=c.group_dict.name, page='/' + page) %} +

    + + +
    +

    + {% endblock %} +
    +
    +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/edit_base.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/edit_base.html new file mode 100644 index 0000000000..c17a16c476 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/edit_base.html @@ -0,0 +1,3 @@ +{% extends 'ckanext_pages/base.html' %} + +{% block subtitle %}{{ _('Pages') }}{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page.html new file mode 100644 index 0000000000..300178c48e --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page.html @@ -0,0 +1,13 @@ +{% extends 'group/read_base.html' %} + +{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} + +{% block primary_content_inner %} + {% link_for _('Edit page'), controller='ckanext.pages.controller:PagesController', action='group_edit', id=c.group_dict.name, page='/' + c.page.name, class_='btn btn-primary pull-right', icon='edit' %} +

    {{ c.page.title }}

    + {% if c.page.content %} + {{ h.render_markdown(c.page.content) }} + {% else %} +

    {{ _('This page currently has no content') }}

    + {% endif %} +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_edit.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_edit.html new file mode 100644 index 0000000000..2bcc1790c8 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_edit.html @@ -0,0 +1,7 @@ +{% extends 'group/read_base.html' %} + +{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} + +{% block primary_content_inner %} + {% snippet 'ckanext_pages/base_form.html', type='group', id=c.group_dict.name, page=page, data=data, errors=errors %} +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_list.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_list.html new file mode 100644 index 0000000000..bfc1b7ccc9 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_list.html @@ -0,0 +1,14 @@ +{% extends "group/read_base.html" %} + +{% block page_primary_action %} + {% if h.check_access('package_create', {'group_id': c.group_dict.id}) %} + {% link_for _('Add page'), controller='ckanext.pages.controller:PagesController', action='group_edit', id=c.group_dict.name, page='', class_='btn btn-primary', icon='plus-sign-alt' %} + {% endif %} +{% endblock %} + +{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} + +{% block primary_content_inner %} +

    {{ _('Pages') }}

    + {% snippet 'ckanext_pages/snippets/pages_list.html', pages=c.pages_dict, type='group', id=c.group_dict.name %} +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page.html new file mode 100644 index 0000000000..b6976d7599 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page.html @@ -0,0 +1,13 @@ +{% extends 'organization/read_base.html' %} + +{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} + +{% block primary_content_inner %} + {% link_for _('Edit page'), controller='ckanext.pages.controller:PagesController', action='org_edit', id=c.group_dict.name, page='/' + c.page.name, class_='btn btn-primary pull-right', icon='edit' %} +

    {{ c.page.title }}

    + {% if c.page.content %} + {{ h.render_markdown(c.page.content) }} + {% else %} +

    {{ _('This page currently has no content') }}

    + {% endif %} +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_edit.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_edit.html new file mode 100644 index 0000000000..c2d9740aec --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_edit.html @@ -0,0 +1,7 @@ +{% extends 'organization/read_base.html' %} + +{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} + +{% block primary_content_inner %} + {% snippet 'ckanext_pages/base_form.html', type='org', id=c.group_dict.name, page=page, data=data, errors=errors %} +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_list.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_list.html new file mode 100644 index 0000000000..7c0745f955 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_list.html @@ -0,0 +1,14 @@ +{% extends 'organization/read_base.html' %} + +{% block page_primary_action %} + {% if h.check_access('package_create', {'group_id': c.group_dict.id}) %} + {% link_for _('Add page'), controller='ckanext.pages.controller:PagesController', action='org_edit', id=c.group_dict.name, page='', class_='btn btn-primary', icon='plus-sign-alt' %} + {% endif %} +{% endblock %} + +{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} + +{% block primary_content_inner %} +

    {{ _('Pages') }}

    + {% snippet 'ckanext_pages/snippets/pages_list.html', pages=c.pages_dict, type='org', id=c.group_dict.name %} +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/page.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/page.html new file mode 100644 index 0000000000..c5d2a3a253 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/page.html @@ -0,0 +1,19 @@ +{% extends 'page.html' %} + +{% block subtitle %}{{ c.page.title }}{% endblock %} + +{% block primary %} +
    + {% if h.check_access('ckanext_pages_update') %} + {% link_for _('Edit'), controller='ckanext.pages.controller:PagesController', action='pages_edit', page='/' + c.page.name, class_='btn btn-primary pull-right', icon='edit' %} + {% endif %} +

    {{ c.page.title }}

    + {% if c.page.content %} + {{ h.render_markdown(c.page.content) }} + {% else %} +

    {{ _('This page currently has no content') }}

    + {% endif %} +
    +{% endblock %} + +{% block secondary %}{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_edit.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_edit.html new file mode 100644 index 0000000000..85bac8c597 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_edit.html @@ -0,0 +1,7 @@ +{% extends 'ckanext_pages/edit_base.html' %} + +{% block subtitle %}{{ _('Edit Page')}} {% endblock %} + +{% block primary_content_inner %} + {% snippet 'ckanext_pages/base_form.html', page=page, data=data, errors=errors %} +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_list.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_list.html new file mode 100644 index 0000000000..2423ed2c7a --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_list.html @@ -0,0 +1,12 @@ +{% extends 'ckanext_pages/edit_base.html' %} + +{% block page_primary_action %} + {% if h.check_access('ckanext_pages_update', {}) %} + {% link_for _('Add page'), controller='ckanext.pages.controller:PagesController', action='pages_edit', page='', class_='btn btn-primary', icon='plus-sign-alt' %} + {% endif %} +{% endblock %} + +{% block primary_content_inner %} +

    {{ _('Pages') }}

    + {% snippet 'ckanext_pages/snippets/pages_list.html', pages=c.pages_dict %} +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/snippets/pages_list.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/snippets/pages_list.html new file mode 100644 index 0000000000..54d1801da6 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/snippets/pages_list.html @@ -0,0 +1,28 @@ +{% set pages_total = pages|length %} +{% set action = '{0}_show'.format(type) %} + +

    {{ _('1 page') if pages_total == 1 else _('{0} pages').format(pages_total) }}

    +
    +{% if pages %} +
      + {% for page in pages %} + {% if type %} + {% set url = h.url_for(controller='ckanext.pages.controller:PagesController', action=action, id=id, page='/' + page.name) %} + {% else %} + {% set url = h.url_for(controller='ckanext.pages.controller:PagesController', action='pages_show', page='/' + page.name) %} + {% endif %} +
    • +

      + {{ page.title }} +

      + {% if page.content %} + {{ h.markdown_extract(page.content) }} + {% else %} +

      {{ _('This page currently has no content') }}

      + {% endif %} +
    • + {% endfor %} +
    +{% else %} +

    {{ _('There are currently no pages here') }}

    +{% endif %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/header.html b/ckanext-pages/ckanext/pages/theme/templates_main/header.html new file mode 100644 index 0000000000..8d085eb770 --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_main/header.html @@ -0,0 +1,10 @@ +{% ckan_extends %} + +{% block header_account_logged %} +
  • + + + +
  • + {{ super() }} +{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_organization/organization/read_base.html b/ckanext-pages/ckanext/pages/theme/templates_organization/organization/read_base.html new file mode 100644 index 0000000000..aba18eda0e --- /dev/null +++ b/ckanext-pages/ckanext/pages/theme/templates_organization/organization/read_base.html @@ -0,0 +1,6 @@ +{% ckan_extends %} + +{% block content_primary_nav %} + {{ super() }} + {{ h.build_nav_icon('organization_pages', _('Pages'), id=c.group_dict.name, page='') }} +{% endblock %} diff --git a/ckanext-pages/setup.py b/ckanext-pages/setup.py new file mode 100644 index 0000000000..1b79a53451 --- /dev/null +++ b/ckanext-pages/setup.py @@ -0,0 +1,29 @@ +from setuptools import setup, find_packages + +version = '0.1' + +setup( + name='ckanext-pages', + version=version, + description='Basic CMS extension for ckan', + long_description='', + classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + keywords='', + author='David Raznick', + author_email='david.raznick@gokfn.org', + url='', + license='', + packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), + namespace_packages=['ckanext', 'ckanext.pages'], + include_package_data=True, + zip_safe=False, + install_requires=[ + # -*- Extra requirements: -*- + ], + entry_points=\ + """ + [ckan.plugins] + pages=ckanext.pages.plugin:PagesPlugin + + """, +) diff --git a/ckanext-sitemap/ckanext/sitemap/controller.py b/ckanext-sitemap/ckanext/sitemap/controller.py index d012879785..52b1e4cc10 100644 --- a/ckanext-sitemap/ckanext/sitemap/controller.py +++ b/ckanext-sitemap/ckanext/sitemap/controller.py @@ -20,7 +20,7 @@ class SitemapController(BaseController): def _render_sitemap(self, page): root = etree.Element("urlset", nsmap={None: SITEMAP_NS}) #pkgs = Session.query(Package).all() - pkgs = Session.query(Package).filter(Package.private == 0).offset(int(page)*25).limit(25) + pkgs = Session.query(Package).filter(Package.private == False).offset(int(page)*25).limit(25) for pkg in pkgs: url = etree.SubElement(root, 'url') loc = etree.SubElement(url, 'loc') @@ -40,7 +40,7 @@ def _render_sitemap(self, page): def view(self): #Sitemap Index root = etree.Element("sitemapindex", nsmap={None: SITEMAP_NS}) - pkgs = Session.query(Package).count() + pkgs = Session.query(Package).filter(Package.private == False).count() count = pkgs/25 for i in range(1,count): sitemap = etree.SubElement(root, 'sitemap') From 608008532748d58f3522ba1e68288d39adc0fcae Mon Sep 17 00:00:00 2001 From: Alexandru Artimon Date: Mon, 3 Nov 2014 18:46:27 +0200 Subject: [PATCH 30/31] fixes #1665 - Change feedback button to link to http://docs.hdx.rwlabs.org/get-involved/ --- ckanext-hdx_theme/ckanext/hdx_theme/templates/header-new.html | 2 +- ckanext-hdx_theme/ckanext/hdx_theme/templates/header.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/header-new.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/header-new.html index a9440e4eb6..a85226effc 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/header-new.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/header-new.html @@ -31,7 +31,7 @@

  • {{ _('About') }}
  • {% endblock %} - + Feedback

    diff --git a/ckanext-hdx_theme/ckanext/hdx_theme/templates/header.html b/ckanext-hdx_theme/ckanext/hdx_theme/templates/header.html index cfcb98daf4..8ec0579e91 100644 --- a/ckanext-hdx_theme/ckanext/hdx_theme/templates/header.html +++ b/ckanext-hdx_theme/ckanext/hdx_theme/templates/header.html @@ -51,7 +51,7 @@

    #} {% endblock %} - + Feedback

    From 904f5d609a4973f6b74265465c8788b47ca0efe2 Mon Sep 17 00:00:00 2001 From: Marianne Bellotti Date: Tue, 4 Nov 2014 01:11:03 -0500 Subject: [PATCH 31/31] removing pages --- ckanext-pages/.gitignore | 10 - ckanext-pages/README.md | 33 --- ckanext-pages/ckanext/__init__.py | 8 - ckanext-pages/ckanext/pages/__init__.py | 7 - ckanext-pages/ckanext/pages/actions.py | 219 -------------- ckanext-pages/ckanext/pages/auth.py | 64 ---- ckanext-pages/ckanext/pages/controller.py | 279 ------------------ ckanext-pages/ckanext/pages/db.py | 123 -------- ckanext-pages/ckanext/pages/plugin.py | 147 --------- .../templates_group/group/read_base.html | 6 - .../templates_main/ckanext_pages/base.html | 17 -- .../ckanext_pages/base_form.html | 117 -------- .../ckanext_pages/confirm_delete.html | 22 -- .../ckanext_pages/edit_base.html | 3 - .../ckanext_pages/group_page.html | 13 - .../ckanext_pages/group_page_edit.html | 7 - .../ckanext_pages/group_page_list.html | 14 - .../ckanext_pages/organization_page.html | 13 - .../ckanext_pages/organization_page_edit.html | 7 - .../ckanext_pages/organization_page_list.html | 14 - .../templates_main/ckanext_pages/page.html | 19 -- .../ckanext_pages/pages_edit.html | 7 - .../ckanext_pages/pages_list.html | 12 - .../ckanext_pages/snippets/pages_list.html | 28 -- .../pages/theme/templates_main/header.html | 10 - .../organization/read_base.html | 6 - ckanext-pages/setup.py | 29 -- 27 files changed, 1234 deletions(-) delete mode 100644 ckanext-pages/.gitignore delete mode 100644 ckanext-pages/README.md delete mode 100644 ckanext-pages/ckanext/__init__.py delete mode 100644 ckanext-pages/ckanext/pages/__init__.py delete mode 100644 ckanext-pages/ckanext/pages/actions.py delete mode 100644 ckanext-pages/ckanext/pages/auth.py delete mode 100644 ckanext-pages/ckanext/pages/controller.py delete mode 100644 ckanext-pages/ckanext/pages/db.py delete mode 100644 ckanext-pages/ckanext/pages/plugin.py delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_group/group/read_base.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base_form.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/confirm_delete.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/edit_base.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_edit.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_list.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_edit.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_list.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/page.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_edit.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_list.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/snippets/pages_list.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_main/header.html delete mode 100644 ckanext-pages/ckanext/pages/theme/templates_organization/organization/read_base.html delete mode 100644 ckanext-pages/setup.py diff --git a/ckanext-pages/.gitignore b/ckanext-pages/.gitignore deleted file mode 100644 index 595975452c..0000000000 --- a/ckanext-pages/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.egg-info -*.pyc -*.swp -*.swo -*~ -#* -.#* -build/ -dist/ -distribute-* \ No newline at end of file diff --git a/ckanext-pages/README.md b/ckanext-pages/README.md deleted file mode 100644 index 30cb98b272..0000000000 --- a/ckanext-pages/README.md +++ /dev/null @@ -1,33 +0,0 @@ -ckanext-pages -============= - -This extension gives you an easy way to add simple pages to CKAN. - -By default you can add pages to the main CKAN menu. - - - -Extra config options allow you to control the creation of extra pages against groups and organizations. - -To swich on this behaviour, to your config add: - -``` -ckanext.pages.organization = True -ckanext.pages.group = True -``` - -These options are False by default and this feature is experimental. - - -This module also gives you a quick way to remove default elements from the CKAN menu and you may need todo this -in order for you to have space for the new items you add. These options are: - -``` -ckanext.pages.about_menu = False -ckanext.pages.group_menu = False -ckanext.pages.organization_menu = False -``` - -By default these are all set to True, like on a default install. - - diff --git a/ckanext-pages/ckanext/__init__.py b/ckanext-pages/ckanext/__init__.py deleted file mode 100644 index bf99a9da02..0000000000 --- a/ckanext-pages/ckanext/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# this is a namespace package -try: - import pkg_resources - pkg_resources.declare_namespace(__name__) -except ImportError: - import pkgutil - __path__ = pkgutil.extend_path(__path__, __name__) - diff --git a/ckanext-pages/ckanext/pages/__init__.py b/ckanext-pages/ckanext/pages/__init__.py deleted file mode 100644 index 2e2033b3c0..0000000000 --- a/ckanext-pages/ckanext/pages/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# this is a namespace package -try: - import pkg_resources - pkg_resources.declare_namespace(__name__) -except ImportError: - import pkgutil - __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/ckanext-pages/ckanext/pages/actions.py b/ckanext-pages/ckanext/pages/actions.py deleted file mode 100644 index a52d37f264..0000000000 --- a/ckanext-pages/ckanext/pages/actions.py +++ /dev/null @@ -1,219 +0,0 @@ -import datetime - -import ckan.plugins as p -import ckan.lib.navl.dictization_functions as df -import ckan.new_authz as new_authz - -import db -def page_name_validator(key, data, errors, context): - session = context['session'] - page = context.get('page') - group_id = context.get('group_id') - if page and page == data[key]: - return - - query = session.query(db.Page.name).filter_by(name=data[key], group_id=group_id) - result = query.first() - if result: - errors[key].append( - p.toolkit._('Page name already exists in database')) - -schema = { - 'id': [p.toolkit.get_validator('ignore_empty'), unicode], - 'title': [p.toolkit.get_validator('not_empty'), unicode], - 'name': [p.toolkit.get_validator('not_empty'), unicode, - p.toolkit.get_validator('name_validator'), page_name_validator], - 'content': [p.toolkit.get_validator('ignore_missing'), unicode], - # 'lang': [p.toolkit.get_validator('not_empty'), unicode], - 'order': [p.toolkit.get_validator('ignore_missing'), - unicode], - 'private': [p.toolkit.get_validator('ignore_missing'), - p.toolkit.get_validator('boolean_validator')], - 'group_id': [p.toolkit.get_validator('ignore_missing'), unicode], - 'user_id': [p.toolkit.get_validator('ignore_missing'), unicode], - 'created': [p.toolkit.get_validator('ignore_missing'), - p.toolkit.get_validator('isodate')], -} - - -def _pages_show(context, data_dict): - if db.pages_table is None: - db.init_db(context['model']) - org_id = data_dict.get('org_id') - page = data_dict.get('page') - out = db.Page.get(group_id=org_id, name=page) - if out: - out = db.table_dictize(out, context) - return out - - -def _pages_list(context, data_dict): - search = {} - if db.pages_table is None: - db.init_db(context['model']) - org_id = data_dict.get('org_id') - ordered = data_dict.get('order') - private = data_dict.get('private', True) - if ordered: - search['order'] = True - if not org_id: - search['group_id'] = None - try: - p.toolkit.check_access('ckanext_pages_update', context, data_dict) - if not private: - search['private'] = False - except p.toolkit.NotAuthorized: - search['private'] = False - else: - group = context['model'].Group.get(org_id) - user = context['user'] - member = new_authz.has_user_permission_for_group_or_org( - group.id, user, 'read') - search['group_id'] = org_id - if not member: - search['private'] = False - out = db.Page.pages(**search) - return [{'title': pg.title, - 'content': pg.content, - 'name': pg.name, - 'group_id': pg.group_id, - } for pg in out] - - -def _pages_delete(context, data_dict): - if db.pages_table is None: - db.init_db(context['model']) - org_id = data_dict.get('org_id') - page = data_dict.get('page') - out = db.Page.get(group_id=org_id, name=page) - if out: - session = context['session'] - session.delete(out) - session.commit() - - -def _pages_update(context, data_dict): - if db.pages_table is None: - db.init_db(context['model']) - org_id = data_dict.get('org_id') - page = data_dict.get('page') - # we need the page in the context for name validation - context['page'] = page - context['group_id'] = org_id - - data, errors = df.validate(data_dict, schema, context) - - if errors: - raise p.toolkit.ValidationError(errors) - - out = db.Page.get(group_id=org_id, name=page) - if not out: - out = db.Page() - out.group_id = org_id - out.name = page - items = ['title', 'content', 'name', 'private', 'order'] - for item in items: - setattr(out, item, data.get(item)) - - out.modified = datetime.datetime.utcnow() - out.user_id = p.toolkit.c.userobj.id - out.save() - session = context['session'] - session.add(out) - session.commit() - - -def pages_show(context, data_dict): - try: - p.toolkit.check_access('ckanext_pages_show', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_show(context, data_dict) - - -def pages_update(context, data_dict): - try: - p.toolkit.check_access('ckanext_pages_update', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_update(context, data_dict) - - -def pages_delete(context, data_dict): - try: - p.toolkit.check_access('ckanext_pages_delete', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_delete(context, data_dict) - - -def pages_list(context, data_dict): - try: - p.toolkit.check_access('ckanext_pages_list', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_list(context, data_dict) - - -def org_pages_show(context, data_dict): - try: - p.toolkit.check_access('ckanext_org_pages_show', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_show(context, data_dict) - - -def org_pages_update(context, data_dict): - try: - p.toolkit.check_access('ckanext_org_pages_update', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_update(context, data_dict) - - -def org_pages_delete(context, data_dict): - try: - p.toolkit.check_access('ckanext_org_pages_delete', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_delete(context, data_dict) - - -def org_pages_list(context, data_dict): - try: - p.toolkit.check_access('ckanext_org_pages_list', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_list(context, data_dict) - - -def group_pages_show(context, data_dict): - try: - p.toolkit.check_access('ckanext_group_pages_show', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_show(context, data_dict) - - -def group_pages_update(context, data_dict): - try: - p.toolkit.check_access('ckanext_group_pages_update', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_update(context, data_dict) - - -def group_pages_delete(context, data_dict): - try: - p.toolkit.check_access('ckanext_group_pages_delete', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_delete(context, data_dict) - - -def group_pages_list(context, data_dict): - try: - p.toolkit.check_access('ckanext_group_pages_list', context, data_dict) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, p.toolkit._('Not authorized to see this page')) - return _pages_list(context, data_dict) diff --git a/ckanext-pages/ckanext/pages/auth.py b/ckanext-pages/ckanext/pages/auth.py deleted file mode 100644 index 7449b78aa2..0000000000 --- a/ckanext-pages/ckanext/pages/auth.py +++ /dev/null @@ -1,64 +0,0 @@ -import ckan.plugins as p -import ckan.new_authz as new_authz - -import db - - -def sysadmin(context, data_dict): - return {'success': False} - -def anyone(context, data_dict): - return {'success': True} - -def group_admin(context, data_dict): - return p.toolkit.check_access('group_update', context, data_dict) - - -def org_admin(context, data_dict): - return p.toolkit.check_access('group_update', context, data_dict) - - -def page_privacy(context, data_dict): - if db.pages_table is None: - db.init_db(context['model']) - org_id = data_dict.get('org_id') - page = data_dict.get('page') - out = db.Page.get(group_id=org_id, name=page) - if out and out.private == False: - return {'success': True} - # no org_id means it's a universal page - if not org_id: - if out and out.private: - return {'success': False} - return {'success': True} - group = context['model'].Group.get(org_id) - user = context['user'] - authorized = new_authz.has_user_permission_for_group_or_org(group.id, - user, - 'read') - if not authorized: - return {'success': False, - 'msg': p.toolkit._( - 'User %s not authorized to read this page') % user} - else: - return {'success': True} - -# Starting from 2.2 you need to explicitly flag auth functions that allow -# anonymous access -if p.toolkit.check_ckan_version(min_version='2.2'): - anyone = p.toolkit.auth_allow_anonymous_access(anyone) - page_privacy = p.toolkit.auth_allow_anonymous_access(page_privacy) - - -pages_show = page_privacy -pages_update = sysadmin -pages_delete = sysadmin -pages_list = anyone -org_pages_show = page_privacy -org_pages_update = org_admin -org_pages_delete = org_admin -org_pages_list = anyone -group_pages_show = page_privacy -group_pages_update = group_admin -group_pages_delete = group_admin -group_pages_list = anyone diff --git a/ckanext-pages/ckanext/pages/controller.py b/ckanext-pages/ckanext/pages/controller.py deleted file mode 100644 index c832883f14..0000000000 --- a/ckanext-pages/ckanext/pages/controller.py +++ /dev/null @@ -1,279 +0,0 @@ -import ckan.plugins as p - -_ = p.toolkit._ - -class PagesController(p.toolkit.BaseController): - controller = 'ckanext.pages.controller:PagesController' - - def _get_group_dict(self, id): - ''' returns the result of group_show action or aborts if there is a - problem ''' - - def _template_setup_org(self, id): - if not id: - return - # we need the org for the rest of the page - context = {'for_view': True} - try: - p.toolkit.c.group_dict = p.toolkit.get_action('organization_show')(context, {'id': id}) - except p.toolkit.ObjectNotFound: - p.toolkit.abort(404, _('Organization not found')) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, _('Unauthorized to read organization %s') % id) - - def org_show(self, id, page=None): - if page: - page = page[1:] - self._template_setup_org(id) - if page is '': - return self._org_list_pages(id) - _page = p.toolkit.get_action('ckanext_pages_show')( - data_dict={'org_id': p.toolkit.c.group_dict['id'], - 'page': page,} - ) - if _page is None: - return self._org_list_pages(id) - p.toolkit.c.page = _page - return p.toolkit.render('ckanext_pages/organization_page.html') - - def _org_list_pages(self, id): - p.toolkit.c.pages_dict = p.toolkit.get_action('ckanext_pages_list')( - data_dict={'org_id': p.toolkit.c.group_dict['id']} - ) - return p.toolkit.render('ckanext_pages/organization_page_list.html') - - - def org_delete(self, id, page): - self._template_setup_org(id) - page = page[1:] - if 'cancel' in p.toolkit.request.params: - p.toolkit.redirect_to(controller=self.controller, action='org_edit', id=p.toolkit.c.group_dict['name'], page='/' + page) - - ## try: - ## self._check_access('group_delete', {}, {'id': id}) - ## except p.toolkit.NotAuthorized: - ## p.toolkit.abort(401, _('Unauthorized to delete page')) - - try: - if p.toolkit.request.method == 'POST': - p.toolkit.get_action('ckanext_pages_delete')({}, {'org_id': p.toolkit.c.group_dict['id'], 'page': page}) - p.toolkit.redirect_to(controller=self.controller, action='org_show', id=id, page='') - else: - p.toolkit.abort(404, _('Page Not Found')) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, _('Unauthorized to delete page')) - except p.toolkit.ObjectNotFound: - p.toolkit.abort(404, _('Group not found')) - return p.toolkit.render('ckanext_pages/confirm_delete.html', {'page': page}) - - - def org_edit(self, id, page=None, data=None, errors=None, error_summary=None): - self._template_setup_org(id) - if page: - page = page[1:] - _page = p.toolkit.get_action('ckanext_pages_show')( - data_dict={'org_id': p.toolkit.c.group_dict['id'], - 'page': page,} - ) - if _page is None: - _page = {} - - if p.toolkit.request.method == 'POST' and not data: - data = p.toolkit.request.POST - items = ['title', 'name', 'content', 'private'] - # update config from form - for item in items: - if item in data: - _page[item] = data[item] - _page['org_id'] = p.toolkit.c.group_dict['id'], - _page['page'] = page - try: - junk = p.toolkit.get_action('ckanext_pages_update')( - data_dict=_page - ) - except p.toolkit.ValidationError, e: - errors = e.error_dict - error_summary = e.error_summary - return self.org_edit(id, '/' + page, data, - errors, error_summary) - p.toolkit.redirect_to(p.toolkit.url_for('organization_pages', id=id, page='/' + _page['name'])) - - if not data: - data = _page - - errors = errors or {} - error_summary = error_summary or {} - - vars = {'data': data, 'errors': errors, - 'error_summary': error_summary, 'page': page} - - return p.toolkit.render('ckanext_pages/organization_page_edit.html', - extra_vars=vars) - - def _template_setup_group(self, id): - if not id: - return - # we need the org for the rest of the page - context = {'for_view': True} - try: - p.toolkit.c.group_dict = p.toolkit.get_action('group_show')(context, {'id': id}) - except p.toolkit.ObjectNotFound: - p.toolkit.abort(404, _('Group not found')) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, _('Unauthorized to read group %s') % id) - - - def group_show(self, id, page=None): - if page: - page = page[1:] - self._template_setup_group(id) - if page is '': - return self._group_list_pages(id) - _page = p.toolkit.get_action('ckanext_pages_show')( - data_dict={'org_id': p.toolkit.c.group_dict['id'], - 'page': page,} - ) - if _page is None: - return self._group_list_pages(id) - p.toolkit.c.page = _page - return p.toolkit.render('ckanext_pages/group_page.html') - - def _group_list_pages(self, id): - p.toolkit.c.pages_dict = p.toolkit.get_action('ckanext_pages_list')( - data_dict={'org_id': p.toolkit.c.group_dict['id']} - ) - return p.toolkit.render('ckanext_pages/group_page_list.html') - - def group_edit(self, id, page=None, data=None, errors=None, error_summary=None): - self._template_setup_group(id) - if page: - page = page[1:] - _page = p.toolkit.get_action('ckanext_pages_show')( - data_dict={'org_id': p.toolkit.c.group_dict['id'], - 'page': page,} - ) - if _page is None: - _page = {} - - if p.toolkit.request.method == 'POST' and not data: - data = p.toolkit.request.POST - items = ['title', 'name', 'content', 'private'] - # update config from form - for item in items: - if item in data: - _page[item] = data[item] - _page['org_id'] = p.toolkit.c.group_dict['id'] - _page['page'] = page - try: - junk = p.toolkit.get_action('ckanext_pages_update')( - data_dict=_page - ) - except p.toolkit.ValidationError, e: - errors = e.error_dict - error_summary = e.error_summary - return self.group_edit(id, '/' + page, data, - errors, error_summary) - p.toolkit.redirect_to(p.toolkit.url_for('group_pages', id=id, page='/' + _page['name'])) - - if not data: - data = _page - - errors = errors or {} - error_summary = error_summary or {} - - vars = {'data': data, 'errors': errors, - 'error_summary': error_summary, 'page': page} - - return p.toolkit.render('ckanext_pages/group_page_edit.html', - extra_vars=vars) - - - def pages_show(self, page=None): - if page: - page = page[1:] - if not page: - return self._pages_list_pages() - _page = p.toolkit.get_action('ckanext_pages_show')( - data_dict={'org_id': None, - 'page': page,} - ) - if _page is None: - return self._pages_list_pages() - p.toolkit.c.page = _page - return p.toolkit.render('ckanext_pages/page.html') - - def _pages_list_pages(self): - p.toolkit.c.pages_dict = p.toolkit.get_action('ckanext_pages_list')( - data_dict={'org_id': None} - ) - return p.toolkit.render('ckanext_pages/pages_list.html') - - def pages_delete(self, page): - page = page[1:] - if 'cancel' in p.toolkit.request.params: - p.toolkit.redirect_to(controller=self.controller, action='pages_edit', page='/' + page) - - - try: - if p.toolkit.request.method == 'POST': - p.toolkit.get_action('ckanext_pages_delete')({}, {'page': page}) - p.toolkit.redirect_to(controller=self.controller, action='pages_show', page='') - else: - p.toolkit.abort(404, _('Page Not Found')) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, _('Unauthorized to delete page')) - except p.toolkit.ObjectNotFound: - p.toolkit.abort(404, _('Group not found')) - return p.toolkit.render('ckanext_pages/confirm_delete.html', {'page': page}) - - - def pages_edit(self, page=None, data=None, errors=None, error_summary=None): - if page: - page = page[1:] - _page = p.toolkit.get_action('ckanext_pages_show')( - data_dict={'org_id': None, - 'page': page,} - ) - if _page is None: - _page = {} - - if p.toolkit.request.method == 'POST' and not data: - data = p.toolkit.request.POST - items = ['title', 'name', 'content', 'private', 'order'] - - # update config from form - for item in items: - if item in data: - _page[item] = data[item] - _page['org_id'] = None - _page['page'] = page - try: - junk = p.toolkit.get_action('ckanext_pages_update')( - data_dict=_page - ) - except p.toolkit.ValidationError, e: - errors = e.error_dict - error_summary = e.error_summary - return self.pages_edit('/' + page, data, - errors, error_summary) - p.toolkit.redirect_to(p.toolkit.url_for('pages_show', page='/' + _page['name'])) - - try: - p.toolkit.check_access('ckanext_pages_update', {'user': p.toolkit.c.user or p.toolkit.c.author}) - except p.toolkit.NotAuthorized: - p.toolkit.abort(401, _('Unauthorized to create or edit a page')) - - if not data: - data = _page - - errors = errors or {} - error_summary = error_summary or {} - - vars = {'data': data, 'errors': errors, - 'error_summary': error_summary, 'page': page} - - return p.toolkit.render('ckanext_pages/pages_edit.html', - extra_vars=vars) - - - diff --git a/ckanext-pages/ckanext/pages/db.py b/ckanext-pages/ckanext/pages/db.py deleted file mode 100644 index 0695c58d55..0000000000 --- a/ckanext-pages/ckanext/pages/db.py +++ /dev/null @@ -1,123 +0,0 @@ -import datetime -import uuid - -import sqlalchemy as sa -from sqlalchemy.orm import class_mapper - - -pages_table = None -Page = None - - -def make_uuid(): - return unicode(uuid.uuid4()) - - -def init_db(model): - class _Page(model.DomainObject): - - @classmethod - def get(cls, **kw): - '''Finds a single entity in the register.''' - query = model.Session.query(cls).autoflush(False) - return query.filter_by(**kw).first() - - @classmethod - def pages(cls, **kw): - '''Finds a single entity in the register.''' - order = kw.pop('order', False) - - query = model.Session.query(cls).autoflush(False) - query = query.filter_by(**kw) - if order: - query = query.order_by(cls.order).filter(cls.order != '') - return query.all() - - global Page - Page = _Page - # We will just try to create the table. If it already exists we get an - # error but we can just skip it and carry on. - sql = ''' - CREATE TABLE ckanext_pages ( - id text NOT NULL, - title text, - name text, - content text, - lang text, - "order" text, - private boolean, - group_id text, - user_id text NOT NULL, - created timestamp without time zone, - modified timestamp without time zone - ); - ''' - conn = model.Session.connection() - try: - conn.execute(sql) - except sa.exc.ProgrammingError: - pass - model.Session.commit() - - types = sa.types - global pages_table - pages_table = sa.Table('ckanext_pages', model.meta.metadata, - sa.Column('id', types.UnicodeText, primary_key=True, default=make_uuid), - sa.Column('title', types.UnicodeText, default=u''), - sa.Column('name', types.UnicodeText, default=u''), - sa.Column('content', types.UnicodeText, default=u''), - sa.Column('lang', types.UnicodeText, default=u''), - sa.Column('order', types.UnicodeText, default=u''), - sa.Column('private',types.Boolean,default=True), - sa.Column('group_id', types.UnicodeText, default=None), - sa.Column('user_id', types.UnicodeText, default=u''), - sa.Column('created', types.DateTime, default=datetime.datetime.utcnow), - sa.Column('modified', types.DateTime, default=datetime.datetime.utcnow), - ) - - model.meta.mapper( - Page, - pages_table, - ) - - -def table_dictize(obj, context, **kw): - '''Get any model object and represent it as a dict''' - result_dict = {} - - if isinstance(obj, sa.engine.base.RowProxy): - fields = obj.keys() - else: - ModelClass = obj.__class__ - table = class_mapper(ModelClass).mapped_table - fields = [field.name for field in table.c] - - for field in fields: - name = field - if name in ('current', 'expired_timestamp', 'expired_id'): - continue - if name == 'continuity_id': - continue - value = getattr(obj, name) - if value is None: - result_dict[name] = value - elif isinstance(value, dict): - result_dict[name] = value - elif isinstance(value, int): - result_dict[name] = value - elif isinstance(value, datetime.datetime): - result_dict[name] = value.isoformat() - elif isinstance(value, list): - result_dict[name] = value - else: - result_dict[name] = unicode(value) - - result_dict.update(kw) - - ##HACK For optimisation to get metadata_modified created faster. - - context['metadata_modified'] = max(result_dict.get('revision_timestamp', ''), - context.get('metadata_modified', '')) - - return result_dict - diff --git a/ckanext-pages/ckanext/pages/plugin.py b/ckanext-pages/ckanext/pages/plugin.py deleted file mode 100644 index 194b89d0cf..0000000000 --- a/ckanext-pages/ckanext/pages/plugin.py +++ /dev/null @@ -1,147 +0,0 @@ -import logging -from pylons import config - -import ckan.plugins as p -import ckan.lib.helpers as h - -import actions -import auth - -log = logging.getLogger(__name__) - -def build_pages_nav_main(*args): - - about_menu = p.toolkit.asbool(config.get('ckanext.pages.about_menu', True)) - group_menu = p.toolkit.asbool(config.get('ckanext.pages.group_menu', True)) - org_menu = p.toolkit.asbool(config.get('ckanext.pages.organization_menu', True)) - - new_args = [] - for arg in args: - if arg[0] == 'about' and not about_menu: - continue - if arg[0] == 'organizations_index' and not org_menu: - continue - if arg[0] == 'group_index' and not group_menu: - continue - new_args.append(arg) - - output = h.build_nav_main(*new_args) - - # do not display any private datasets in menu even for sysadmins - pages_list = p.toolkit.get_action('ckanext_pages_list')(None, {'order': True, 'private': False}) - - page_name = '' - - if (p.toolkit.c.action == 'pages_show' - and p.toolkit.c.controller == 'ckanext.pages.controller:PagesController'): - page_name = p.toolkit.c.environ['routes.url'].current().split('/')[-1] - - for page in pages_list: - link = h.link_to(page.get('title'), - h.url_for('/pages/' + str(page['name']))) - - if page['name'] == page_name: - li = h.literal('
  • ') + link + h.literal('
  • ') - else: - li = h.literal('
  • ') + link + h.literal('
  • ') - output = output + li - - return output - - - -class PagesPlugin(p.SingletonPlugin): - p.implements(p.IConfigurer, inherit=True) - p.implements(p.ITemplateHelpers, inherit=True) - p.implements(p.IConfigurable, inherit=True) - p.implements(p.IRoutes, inherit=True) - p.implements(p.IActions, inherit=True) - p.implements(p.IAuthFunctions, inherit=True) - - def update_config(self, config): - self.organization_pages = p.toolkit.asbool(config.get('ckanext.pages.organization', False)) - self.group_pages = p.toolkit.asbool(config.get('ckanext.pages.group', False)) - - p.toolkit.add_template_directory(config, 'theme/templates_main') - if self.group_pages: - p.toolkit.add_template_directory(config, 'theme/templates_group') - if self.organization_pages: - p.toolkit.add_template_directory(config, 'theme/templates_organization') - - - def configure(self, config): - return - - def get_helpers(self): - return { - 'build_nav_main': build_pages_nav_main - } - - def after_map(self, map): - controller = 'ckanext.pages.controller:PagesController' - - if self.organization_pages: - map.connect('organization_pages_delete', '/organization/pages_delete/{id}{page:/.*|}', - action='org_delete', ckan_icon='delete', controller=controller) - map.connect('organization_pages_edit', '/organization/pages_edit/{id}{page:/.*|}', - action='org_edit', ckan_icon='edit', controller=controller) - map.connect('organization_pages', '/organization/pages/{id}{page:/.*|}', - action='org_show', ckan_icon='file', controller=controller, highlight_actions='org_edit org_show') - - if self.group_pages: - map.connect('group_pages_delete', '/group/pages_delete/{id}{page:/.*|}', - action='group_delete', ckan_icon='delete', controller=controller) - map.connect('group_pages_edit', '/group/pages_edit/{id}{page:/.*|}', - action='group_edit', ckan_icon='edit', controller=controller) - map.connect('group_pages', '/group/pages/{id}{page:/.*|}', - action='group_show', ckan_icon='file', controller=controller, highlight_actions='group_edit group_show') - - - map.connect('pages_delete', '/pages_delete{page:/.*|}', - action='pages_delete', ckan_icon='delete', controller=controller) - map.connect('pages_edit', '/pages_edit{page:/.*|}', - action='pages_edit', ckan_icon='edit', controller=controller) - map.connect('pages_show', '/pages{page:/.*|}', - action='pages_show', ckan_icon='file', controller=controller, highlight_actions='pages_edit pages_show') - return map - - def get_actions(self): - actions_dict = { - 'ckanext_pages_show': actions.pages_show, - 'ckanext_pages_update': actions.pages_update, - 'ckanext_pages_delete': actions.pages_delete, - 'ckanext_pages_list': actions.pages_list, - } - if self.organization_pages: - org_actions={ - 'ckanext_org_pages_show': actions.org_pages_show, - 'ckanext_org_pages_update': actions.org_pages_update, - 'ckanext_org_pages_delete': actions.org_pages_delete, - 'ckanext_org_pages_list': actions.org_pages_list, - } - actions_dict.update(org_actions) - if self.group_pages: - group_actions={ - 'ckanext_group_pages_show': actions.group_pages_show, - 'ckanext_group_pages_update': actions.group_pages_update, - 'ckanext_group_pages_delete': actions.group_pages_delete, - 'ckanext_group_pages_list': actions.group_pages_list, - } - actions_dict.update(group_actions) - return actions_dict - - def get_auth_functions(self): - return { - 'ckanext_pages_show': auth.pages_show, - 'ckanext_pages_update': auth.pages_update, - 'ckanext_pages_delete': auth.pages_delete, - 'ckanext_pages_list': auth.pages_list, - 'ckanext_org_pages_show': auth.org_pages_show, - 'ckanext_org_pages_update': auth.org_pages_update, - 'ckanext_org_pages_delete': auth.org_pages_delete, - 'ckanext_org_pages_list': auth.org_pages_list, - 'ckanext_group_pages_show': auth.group_pages_show, - 'ckanext_group_pages_update': auth.group_pages_update, - 'ckanext_group_pages_delete': auth.group_pages_delete, - 'ckanext_group_pages_list': auth.group_pages_list, - } diff --git a/ckanext-pages/ckanext/pages/theme/templates_group/group/read_base.html b/ckanext-pages/ckanext/pages/theme/templates_group/group/read_base.html deleted file mode 100644 index 62c2bffa3d..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_group/group/read_base.html +++ /dev/null @@ -1,6 +0,0 @@ -{% ckan_extends %} - -{% block content_primary_nav %} - {{ super() }} - {{ h.build_nav_icon('group_pages', _('Pages'), id=c.group_dict.name, page='') }} -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base.html deleted file mode 100644 index a639da7682..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base.html +++ /dev/null @@ -1,17 +0,0 @@ -{% extends 'page.html' %} - -{% block page_header %}{% endblock %} - -{% block secondary_content %} -
    -

    - - {{ _('What are Pages?') }} -

    -
    - {% trans %} -

    Pages are are simple way to add extra pages to your ckan instance. You can assign an order to them.

    - {% endtrans %} -
    -
    -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base_form.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base_form.html deleted file mode 100644 index 8ebc0dc4ef..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/base_form.html +++ /dev/null @@ -1,117 +0,0 @@ -{% import 'macros/form.html' as form %} - -{% if type == 'org' %} - {% set action_url = h.url_for('organization_pages_edit', id=id, page='/' + page) %} - {% set cancel_url = h.url_for('organization_pages', id=id, page='') %} - {% set slug_prefix = cancel_url ~ '/' %} - {% set slug_domain = h.url_for('organization_pages', id=id, page='', qualified=true) %} - {% set hide_field_order = true %} -{% elif type == 'group' %} - {% set action_url = h.url_for('group_pages_edit', id=id, page='/' + page) %} - {% set cancel_url = h.url_for('group_pages', id=id, page='') %} - {% set slug_prefix = cancel_url ~ '/' %} - {% set slug_domain = h.url_for('group_pages', id=id, page='', qualified=true) %} - {% set hide_field_order = true %} -{% else %} - {% set action_url = h.url_for('pages_edit', page='/' + page) %} - {% set cancel_url = h.url_for('pages_show', page='') %} - {% set slug_prefix = cancel_url ~ '/' %} - {% set slug_domain = h.url_for('pages_show', page='', qualified=true) %} -{% endif %} - -{% set data = data or {} %} -{% set errors = errors or {} %} - -{% if not page %} -

    {{ _('Add page') }}

    -{% else %} -

    {{ _('Edit page') }}

    -{% endif %} - -
    - - {{ form.input('title', id='field-title', label=_('Title'), placeholder=_('eg. Page Title'), value=data.title, error=errors.title, classes=['control-full', 'control-large'], attrs={'data-module': 'slug-preview-target'}) }} - - {% set domain = slug_domain|replace("http://", "")|replace("https://", "") %} - {% set attrs = {'data-module': 'slug-preview-slug', 'data-module-prefix': domain~'/', 'data-module-placeholder': ''} %} - {{ form.prepend('name', id='field-name', label=_('URL'), prepend=slug_prefix, placeholder=_('eg. my-page'), value=data.name, error=errors.name, attrs=attrs) }} - - {#{{ form.input('name', id='field-name', label=_('Name'), placeholder=_('my-name'), value=data.name, error=errors.name, classes=['control-full']) }}#} - -
    - -
    - -
    -
    - - {% if not hide_field_order %} -
    - -
    - -
    -
    - - {% endif %} -{# data.content #} - - - - - {{ form.input('search', id='search', label=_('Search for Datasets'), placeholder=_('eg. ebola'), classes=['control-full', 'control-large']) }} - -
    - - {{ form.markdown('content', id='field-content', label=_('Content'), placeholder=_('My content'), value=data.content, error=errors.content) }} - -
    - {% if not page %} - {{ _('Cancel') }} - - {% else %} - - {% block delete_button %} - {% if h.check_access('ckanext_pages_delete', {'id': data.id}) %} - {% set locale = h.dump_json({'content': _('Are you sure you want to delete this Page?')}) %} - {% block delete_button_text %}{{ _('Delete') }}{% endblock %} - {% endif %} - {% endblock %} - - - {% endif %} -
    - - diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/confirm_delete.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/confirm_delete.html deleted file mode 100644 index 6ab5f92814..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/confirm_delete.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "page.html" %} - -{% block subtitle %}{{ _("Confirm Delete") }}{% endblock %} - -{% block maintag %}
    {% endblock %} - -{% block main_content %} -
    -
    - {% block form %} -

    {{ _('Are you sure you want to delete page - {name}?').format(name=c.page_dict.name) }}

    -

    - {% set action = form_action or h.url_for('organization_pages_delete', id=c.group_dict.name, page='/' + page) %} -

    - - -
    -

    - {% endblock %} -
    -
    -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/edit_base.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/edit_base.html deleted file mode 100644 index c17a16c476..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/edit_base.html +++ /dev/null @@ -1,3 +0,0 @@ -{% extends 'ckanext_pages/base.html' %} - -{% block subtitle %}{{ _('Pages') }}{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page.html deleted file mode 100644 index 300178c48e..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends 'group/read_base.html' %} - -{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} - -{% block primary_content_inner %} - {% link_for _('Edit page'), controller='ckanext.pages.controller:PagesController', action='group_edit', id=c.group_dict.name, page='/' + c.page.name, class_='btn btn-primary pull-right', icon='edit' %} -

    {{ c.page.title }}

    - {% if c.page.content %} - {{ h.render_markdown(c.page.content) }} - {% else %} -

    {{ _('This page currently has no content') }}

    - {% endif %} -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_edit.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_edit.html deleted file mode 100644 index 2bcc1790c8..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_edit.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'group/read_base.html' %} - -{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} - -{% block primary_content_inner %} - {% snippet 'ckanext_pages/base_form.html', type='group', id=c.group_dict.name, page=page, data=data, errors=errors %} -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_list.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_list.html deleted file mode 100644 index bfc1b7ccc9..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/group_page_list.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends "group/read_base.html" %} - -{% block page_primary_action %} - {% if h.check_access('package_create', {'group_id': c.group_dict.id}) %} - {% link_for _('Add page'), controller='ckanext.pages.controller:PagesController', action='group_edit', id=c.group_dict.name, page='', class_='btn btn-primary', icon='plus-sign-alt' %} - {% endif %} -{% endblock %} - -{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} - -{% block primary_content_inner %} -

    {{ _('Pages') }}

    - {% snippet 'ckanext_pages/snippets/pages_list.html', pages=c.pages_dict, type='group', id=c.group_dict.name %} -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page.html deleted file mode 100644 index b6976d7599..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends 'organization/read_base.html' %} - -{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} - -{% block primary_content_inner %} - {% link_for _('Edit page'), controller='ckanext.pages.controller:PagesController', action='org_edit', id=c.group_dict.name, page='/' + c.page.name, class_='btn btn-primary pull-right', icon='edit' %} -

    {{ c.page.title }}

    - {% if c.page.content %} - {{ h.render_markdown(c.page.content) }} - {% else %} -

    {{ _('This page currently has no content') }}

    - {% endif %} -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_edit.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_edit.html deleted file mode 100644 index c2d9740aec..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_edit.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'organization/read_base.html' %} - -{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} - -{% block primary_content_inner %} - {% snippet 'ckanext_pages/base_form.html', type='org', id=c.group_dict.name, page=page, data=data, errors=errors %} -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_list.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_list.html deleted file mode 100644 index 7c0745f955..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/organization_page_list.html +++ /dev/null @@ -1,14 +0,0 @@ -{% extends 'organization/read_base.html' %} - -{% block page_primary_action %} - {% if h.check_access('package_create', {'group_id': c.group_dict.id}) %} - {% link_for _('Add page'), controller='ckanext.pages.controller:PagesController', action='org_edit', id=c.group_dict.name, page='', class_='btn btn-primary', icon='plus-sign-alt' %} - {% endif %} -{% endblock %} - -{% block subtitle %}{{ _('Pages') }} - {{ c.group_dict.display_name }}{% endblock %} - -{% block primary_content_inner %} -

    {{ _('Pages') }}

    - {% snippet 'ckanext_pages/snippets/pages_list.html', pages=c.pages_dict, type='org', id=c.group_dict.name %} -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/page.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/page.html deleted file mode 100644 index c5d2a3a253..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/page.html +++ /dev/null @@ -1,19 +0,0 @@ -{% extends 'page.html' %} - -{% block subtitle %}{{ c.page.title }}{% endblock %} - -{% block primary %} -
    - {% if h.check_access('ckanext_pages_update') %} - {% link_for _('Edit'), controller='ckanext.pages.controller:PagesController', action='pages_edit', page='/' + c.page.name, class_='btn btn-primary pull-right', icon='edit' %} - {% endif %} -

    {{ c.page.title }}

    - {% if c.page.content %} - {{ h.render_markdown(c.page.content) }} - {% else %} -

    {{ _('This page currently has no content') }}

    - {% endif %} -
    -{% endblock %} - -{% block secondary %}{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_edit.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_edit.html deleted file mode 100644 index 85bac8c597..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_edit.html +++ /dev/null @@ -1,7 +0,0 @@ -{% extends 'ckanext_pages/edit_base.html' %} - -{% block subtitle %}{{ _('Edit Page')}} {% endblock %} - -{% block primary_content_inner %} - {% snippet 'ckanext_pages/base_form.html', page=page, data=data, errors=errors %} -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_list.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_list.html deleted file mode 100644 index 2423ed2c7a..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/pages_list.html +++ /dev/null @@ -1,12 +0,0 @@ -{% extends 'ckanext_pages/edit_base.html' %} - -{% block page_primary_action %} - {% if h.check_access('ckanext_pages_update', {}) %} - {% link_for _('Add page'), controller='ckanext.pages.controller:PagesController', action='pages_edit', page='', class_='btn btn-primary', icon='plus-sign-alt' %} - {% endif %} -{% endblock %} - -{% block primary_content_inner %} -

    {{ _('Pages') }}

    - {% snippet 'ckanext_pages/snippets/pages_list.html', pages=c.pages_dict %} -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/snippets/pages_list.html b/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/snippets/pages_list.html deleted file mode 100644 index 54d1801da6..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/ckanext_pages/snippets/pages_list.html +++ /dev/null @@ -1,28 +0,0 @@ -{% set pages_total = pages|length %} -{% set action = '{0}_show'.format(type) %} - -

    {{ _('1 page') if pages_total == 1 else _('{0} pages').format(pages_total) }}

    -
    -{% if pages %} -
      - {% for page in pages %} - {% if type %} - {% set url = h.url_for(controller='ckanext.pages.controller:PagesController', action=action, id=id, page='/' + page.name) %} - {% else %} - {% set url = h.url_for(controller='ckanext.pages.controller:PagesController', action='pages_show', page='/' + page.name) %} - {% endif %} -
    • -

      - {{ page.title }} -

      - {% if page.content %} - {{ h.markdown_extract(page.content) }} - {% else %} -

      {{ _('This page currently has no content') }}

      - {% endif %} -
    • - {% endfor %} -
    -{% else %} -

    {{ _('There are currently no pages here') }}

    -{% endif %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_main/header.html b/ckanext-pages/ckanext/pages/theme/templates_main/header.html deleted file mode 100644 index 8d085eb770..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_main/header.html +++ /dev/null @@ -1,10 +0,0 @@ -{% ckan_extends %} - -{% block header_account_logged %} -
  • - - - -
  • - {{ super() }} -{% endblock %} diff --git a/ckanext-pages/ckanext/pages/theme/templates_organization/organization/read_base.html b/ckanext-pages/ckanext/pages/theme/templates_organization/organization/read_base.html deleted file mode 100644 index aba18eda0e..0000000000 --- a/ckanext-pages/ckanext/pages/theme/templates_organization/organization/read_base.html +++ /dev/null @@ -1,6 +0,0 @@ -{% ckan_extends %} - -{% block content_primary_nav %} - {{ super() }} - {{ h.build_nav_icon('organization_pages', _('Pages'), id=c.group_dict.name, page='') }} -{% endblock %} diff --git a/ckanext-pages/setup.py b/ckanext-pages/setup.py deleted file mode 100644 index 1b79a53451..0000000000 --- a/ckanext-pages/setup.py +++ /dev/null @@ -1,29 +0,0 @@ -from setuptools import setup, find_packages - -version = '0.1' - -setup( - name='ckanext-pages', - version=version, - description='Basic CMS extension for ckan', - long_description='', - classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers - keywords='', - author='David Raznick', - author_email='david.raznick@gokfn.org', - url='', - license='', - packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), - namespace_packages=['ckanext', 'ckanext.pages'], - include_package_data=True, - zip_safe=False, - install_requires=[ - # -*- Extra requirements: -*- - ], - entry_points=\ - """ - [ckan.plugins] - pages=ckanext.pages.plugin:PagesPlugin - - """, -)