From 3810309443899e92d640fb0c893018ef82b786ee Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Wed, 8 May 2013 14:35:31 -0500 Subject: [PATCH 01/11] The beginning of context hooks. Not the working solution, but getting there conceptually. Basically we'll have a key with the view and the template as a tuple which is the context hook that anyone can attach to. However, some changes have still to be made: - The unit test doesn't work yet and contains a set_trace ;) - We'll probably switch the "view" component from being the callable to the "urlgen"'able name per Elrond's suggestion - Found a bug in unit tests related to running custom apps for different configs... hm. I need to fix this! Nonetheless, making progress. This commit sponsored by... wait a minute... Christopher Webber?! --- mediagoblin/app.py | 3 +++ mediagoblin/tests/test_pluginapi.py | 12 ++++++++++++ mediagoblin/tools/template.py | 9 ++++++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/mediagoblin/app.py b/mediagoblin/app.py index bf0e0f13..dc2900a9 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -201,6 +201,9 @@ class MediaGoblinApp(object): exc.get_description(environ))(environ, start_response) controller = endpoint_to_controller(found_rule) + # Make a reference to the controller on the request... + # used for lazy context modification + request.controller = controller # pass the request through our meddleware classes try: diff --git a/mediagoblin/tests/test_pluginapi.py b/mediagoblin/tests/test_pluginapi.py index 809b5ce9..308151a7 100644 --- a/mediagoblin/tests/test_pluginapi.py +++ b/mediagoblin/tests/test_pluginapi.py @@ -25,6 +25,7 @@ from mediagoblin import mg_globals from mediagoblin.init.plugins import setup_plugins from mediagoblin.init.config import read_mediagoblin_config from mediagoblin.tools import pluginapi +from mediagoblin.tests.tools import get_app def with_cleanup(*modules_to_delete): @@ -323,3 +324,14 @@ def test_plugin_config(): # the callables thing shouldn't really have anything though. assert len(config['plugins'][ 'mediagoblin.tests.testplugins.callables1']) == 0 + + +@pytest.fixture() +def context_modified_app(request): + get_app( + request, + mgoblin_config=pkg_resources.resource_filename( + 'mediagoblin.tests', 'appconfig_context_modified.ini')) + +def test_modify_context(context_modified_app): + pytest.set_trace() diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py index 54aeac92..84fdabf2 100644 --- a/mediagoblin/tools/template.py +++ b/mediagoblin/tools/template.py @@ -27,7 +27,8 @@ from mediagoblin import messages from mediagoblin import _version from mediagoblin.tools import common from mediagoblin.tools.translate import set_thread_locale -from mediagoblin.tools.pluginapi import get_hook_templates +from mediagoblin.tools.pluginapi import ( + get_hook_templates, hook_transform) from mediagoblin.tools.timesince import timesince from mediagoblin.meddleware.csrf import render_csrf_form_token @@ -103,6 +104,12 @@ def render_template(request, template_path, context): rendered_csrf_token = render_csrf_form_token(request) if rendered_csrf_token is not None: context['csrf_token'] = render_csrf_form_token(request) + + # allow plugins to do things to the context + context = hook_transform( + (request.controller, template_path), + context) + rendered = template.render(context) if common.TESTS_ENABLED: From 829f5f9371b033a689067caffa91a03989006ce1 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Wed, 8 May 2013 14:38:13 -0500 Subject: [PATCH 02/11] Ah right, and here's the config we intend to use for these context modified tests :) This commit sponsored by Xavier Gulliot. Thanks Xavier! --- .../tests/appconfig_context_modified.ini | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 mediagoblin/tests/appconfig_context_modified.ini diff --git a/mediagoblin/tests/appconfig_context_modified.ini b/mediagoblin/tests/appconfig_context_modified.ini new file mode 100644 index 00000000..e93797df --- /dev/null +++ b/mediagoblin/tests/appconfig_context_modified.ini @@ -0,0 +1,26 @@ +[mediagoblin] +direct_remote_path = /test_static/ +email_sender_address = "notice@mediagoblin.example.org" +email_debug_mode = true + +# TODO: Switch to using an in-memory database +sql_engine = "sqlite:///%(here)s/test_user_dev/mediagoblin.db" + +# Celery shouldn't be set up by the application as it's setup via +# mediagoblin.init.celery.from_celery +celery_setup_elsewhere = true + +[storage:publicstore] +base_dir = %(here)s/test_user_dev/media/public +base_url = /mgoblin_media/ + +[storage:queuestore] +base_dir = %(here)s/test_user_dev/media/queue + +[celery] +CELERY_ALWAYS_EAGER = true +CELERY_RESULT_DBURI = "sqlite:///%(here)s/test_user_dev/celery.db" +BROKER_HOST = "sqlite:///%(here)s/test_user_dev/kombu.db" + +[plugins] +[[mediagoblin.tests.testplugins.modify_context]] From 98dacfe67e40eb3c575b2fb9a5a80ced3e284ddc Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 10 May 2013 20:26:55 -0500 Subject: [PATCH 03/11] Use the controller's symbolic/lookup name as part of the key for context hooks This commit sponsored by David Collins. Thank you! --- mediagoblin/app.py | 4 ++-- mediagoblin/tools/template.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mediagoblin/app.py b/mediagoblin/app.py index dc2900a9..3ebaa45b 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -201,9 +201,9 @@ class MediaGoblinApp(object): exc.get_description(environ))(environ, start_response) controller = endpoint_to_controller(found_rule) - # Make a reference to the controller on the request... + # Make a reference to the controller's symbolic name on the request... # used for lazy context modification - request.controller = controller + request.controller_name = found_rule.endpoint # pass the request through our meddleware classes try: diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py index 84fdabf2..950fb5da 100644 --- a/mediagoblin/tools/template.py +++ b/mediagoblin/tools/template.py @@ -107,7 +107,7 @@ def render_template(request, template_path, context): # allow plugins to do things to the context context = hook_transform( - (request.controller, template_path), + (request.controller_name, template_path), context) rendered = template.render(context) From f7a5c7c78c6dcf3dcb3b81efbedc9a333df49fb7 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Tue, 14 May 2013 14:24:27 -0500 Subject: [PATCH 04/11] Fully working context hooks, both template/view and global level, with tests Needs documentation though... that's coming next :) This commit sponsored by Luca Tius. Thanks Luca! --- mediagoblin/app.py | 1 + mediagoblin/tests/test_pluginapi.py | 18 ++++++- .../testplugins/modify_context/__init__.py | 49 +++++++++++++++++++ .../templates/contextplugin/general.html | 4 ++ .../templates/contextplugin/specific.html | 5 ++ .../tests/testplugins/modify_context/views.py | 31 ++++++++++++ mediagoblin/tools/template.py | 13 +++-- 7 files changed, 114 insertions(+), 7 deletions(-) create mode 100644 mediagoblin/tests/testplugins/modify_context/__init__.py create mode 100644 mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html create mode 100644 mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html create mode 100644 mediagoblin/tests/testplugins/modify_context/views.py diff --git a/mediagoblin/app.py b/mediagoblin/app.py index 3ebaa45b..1984ce77 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -188,6 +188,7 @@ class MediaGoblinApp(object): mg_request.setup_user_in_request(request) + request.controller_name = None try: found_rule, url_values = map_adapter.match(return_rule=True) request.matchdict = url_values diff --git a/mediagoblin/tests/test_pluginapi.py b/mediagoblin/tests/test_pluginapi.py index 308151a7..de43534f 100644 --- a/mediagoblin/tests/test_pluginapi.py +++ b/mediagoblin/tests/test_pluginapi.py @@ -328,10 +328,24 @@ def test_plugin_config(): @pytest.fixture() def context_modified_app(request): - get_app( + return get_app( request, mgoblin_config=pkg_resources.resource_filename( 'mediagoblin.tests', 'appconfig_context_modified.ini')) + def test_modify_context(context_modified_app): - pytest.set_trace() + # Specific thing passed into a page + result = context_modified_app.get("/modify_context/specific/") + assert result.body.strip() == """Specific page! + +specific thing: in yer specificpage +global thing: globally appended! +something: orother""" + + # General test, should have global context variable only + result = context_modified_app.get("/modify_context/") + assert result.body.strip() == """General page! + +global thing: globally appended! +lol: cats""" diff --git a/mediagoblin/tests/testplugins/modify_context/__init__.py b/mediagoblin/tests/testplugins/modify_context/__init__.py new file mode 100644 index 00000000..6ddcd652 --- /dev/null +++ b/mediagoblin/tests/testplugins/modify_context/__init__.py @@ -0,0 +1,49 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from mediagoblin.tools import pluginapi +import pkg_resources + + +def append_to_specific_context(context): + context['specific_page_append'] = 'in yer specificpage' + return context + +def append_to_global_context(context): + context['global_append'] = 'globally appended!' + return context + + +def setup_plugin(): + routes = [ + ('modify_context.specific_page', + '/modify_context/specific/', + 'mediagoblin.tests.testplugins.modify_context.views:specific'), + ('modify_context.general_page', + '/modify_context/', + 'mediagoblin.tests.testplugins.modify_context.views:general')] + + pluginapi.register_routes(routes) + pluginapi.register_template_path( + pkg_resources.resource_filename( + 'mediagoblin.tests.testplugins.modify_context', 'templates')) + + +hooks = { + 'setup': setup_plugin, + ('modify_context.specific_page', + 'contextplugin/specific.html'): append_to_specific_context, + 'template_global_context': append_to_global_context} diff --git a/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html new file mode 100644 index 00000000..7b7261c6 --- /dev/null +++ b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html @@ -0,0 +1,4 @@ +General page! + +global thing: {{ global_append }} +lol: {{ lol }} diff --git a/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html new file mode 100644 index 00000000..25bea3e2 --- /dev/null +++ b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html @@ -0,0 +1,5 @@ +Specific page! + +specific thing: {{ specific_page_append }} +global thing: {{ global_append }} +something: {{ something }} diff --git a/mediagoblin/tests/testplugins/modify_context/views.py b/mediagoblin/tests/testplugins/modify_context/views.py new file mode 100644 index 00000000..025c84d6 --- /dev/null +++ b/mediagoblin/tests/testplugins/modify_context/views.py @@ -0,0 +1,31 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from mediagoblin.tools.response import render_to_response + + +def specific(request): + return render_to_response( + request, + 'contextplugin/specific.html', + {"something": "orother"}) + + +def general(request): + return render_to_response( + request, + 'contextplugin/general.html', + {"lol": "cats"}) diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py index 950fb5da..aab571f0 100644 --- a/mediagoblin/tools/template.py +++ b/mediagoblin/tools/template.py @@ -27,8 +27,7 @@ from mediagoblin import messages from mediagoblin import _version from mediagoblin.tools import common from mediagoblin.tools.translate import set_thread_locale -from mediagoblin.tools.pluginapi import ( - get_hook_templates, hook_transform) +from mediagoblin.tools.pluginapi import get_hook_templates, hook_transform from mediagoblin.tools.timesince import timesince from mediagoblin.meddleware.csrf import render_csrf_form_token @@ -81,6 +80,9 @@ def get_jinja_env(template_loader, locale): # allow for hooking up plugin templates template_env.globals['get_hook_templates'] = get_hook_templates + template_env.globals = hook_transform( + 'template_global_context', template_env.globals) + if exists(locale): SETUP_JINJA_ENVS[locale] = template_env @@ -106,9 +108,10 @@ def render_template(request, template_path, context): context['csrf_token'] = render_csrf_form_token(request) # allow plugins to do things to the context - context = hook_transform( - (request.controller_name, template_path), - context) + if request.controller_name: + context = hook_transform( + (request.controller_name, template_path), + context) rendered = template.render(context) From 5046ca24337cadff9b95782101f0a8c4d456e15e Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Tue, 14 May 2013 14:29:23 -0500 Subject: [PATCH 05/11] Documenting the test_modify_context and context_modified_app methods --- mediagoblin/tests/test_pluginapi.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mediagoblin/tests/test_pluginapi.py b/mediagoblin/tests/test_pluginapi.py index de43534f..74a00ce0 100644 --- a/mediagoblin/tests/test_pluginapi.py +++ b/mediagoblin/tests/test_pluginapi.py @@ -328,6 +328,9 @@ def test_plugin_config(): @pytest.fixture() def context_modified_app(request): + """ + Get a MediaGoblin app fixture using appconfig_context_modified.ini + """ return get_app( request, mgoblin_config=pkg_resources.resource_filename( @@ -335,6 +338,10 @@ def context_modified_app(request): def test_modify_context(context_modified_app): + """ + Test that we can modify both the view/template specific and + global contexts for templates. + """ # Specific thing passed into a page result = context_modified_app.get("/modify_context/specific/") assert result.body.strip() == """Specific page! From b312d2cd83dbbfb32adc30c5eb3a9a4cc6ae9295 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Tue, 14 May 2013 16:09:55 -0500 Subject: [PATCH 06/11] Added documentation on view specific hooks This commit sponsored by Matthew Woodward. Thank you! --- docs/source/pluginwriter/api.rst | 62 ++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/docs/source/pluginwriter/api.rst b/docs/source/pluginwriter/api.rst index df933511..0d5c82d8 100644 --- a/docs/source/pluginwriter/api.rst +++ b/docs/source/pluginwriter/api.rst @@ -48,3 +48,65 @@ example might look like:: This means that when people enable your plugin in their config you'll be able to provide defaults as well as type validation. + +Context Hooks +------------- + +View specific hooks ++++++++++++++++++++ + +You can hook up to almost any template called by any specific view +fairly easily. As long as the view directly or indirectly uses the +method ``render_to_response`` you can access the context via a hook +that has a key in the format of the tuple:: + + (view_symbolic_name, view_template_path) + +Where the "view symbolic name" is the same parameter used in +``request.urlgen()`` to look up the test. So say we're wanting to add +something to the context of the user's homepage. We look in +mediagoblin/user_pages/routing.py and see:: + + add_route('mediagoblin.user_pages.user_home', + '/u//', + 'mediagoblin.user_pages.views:user_home') + +Aha! That means that the name is ``mediagoblin.user_pages.user_home``. +Okay, so then we look at the view at the +``mediagoblin.user_pages.views:user_home`` method:: + + @uses_pagination + def user_home(request, page): + # [...] whole bunch of stuff here + return render_to_response( + request, + 'mediagoblin/user_pages/user.html', + {'user': user, + 'user_gallery_url': user_gallery_url, + 'media_entries': media_entries, + 'pagination': pagination}) + +Nice! So the template appears to be +``mediagoblin/user_pages/user.html``. Cool, that means that the key +is:: + + ("mediagoblin.user_pages.views:user_home", + "mediagoblin/user_pages/user.html") + +The context hook uses ``hook_transform()`` so that means that if we're +hooking into it, our hook will both accept one argument, ``context``, +and should return that modified object, like so:: + + def add_to_user_home_context(context): + context['foo'] = 'bar' + return context + + hooks = { + ("mediagoblin.user_pages.views:user_home", + "mediagoblin/user_pages/user.html"): add_to_user_home_context} + + +Global context hook ++++++++++++++++++++ + + From 1344c561a0da28290bab860e7e628998463fca15 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Wed, 15 May 2013 10:37:41 -0500 Subject: [PATCH 07/11] Adding global context hooks & fixing method names->symbolic view names in docs This commit sponsored by Sheila Miguez. Thanks Sheila! --- docs/source/pluginwriter/api.rst | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/source/pluginwriter/api.rst b/docs/source/pluginwriter/api.rst index 0d5c82d8..b411fa4d 100644 --- a/docs/source/pluginwriter/api.rst +++ b/docs/source/pluginwriter/api.rst @@ -73,7 +73,7 @@ mediagoblin/user_pages/routing.py and see:: Aha! That means that the name is ``mediagoblin.user_pages.user_home``. Okay, so then we look at the view at the -``mediagoblin.user_pages.views:user_home`` method:: +``mediagoblin.user_pages.user_home`` method:: @uses_pagination def user_home(request, page): @@ -90,7 +90,7 @@ Nice! So the template appears to be ``mediagoblin/user_pages/user.html``. Cool, that means that the key is:: - ("mediagoblin.user_pages.views:user_home", + ("mediagoblin.user_pages.user_home", "mediagoblin/user_pages/user.html") The context hook uses ``hook_transform()`` so that means that if we're @@ -102,11 +102,26 @@ and should return that modified object, like so:: return context hooks = { - ("mediagoblin.user_pages.views:user_home", + ("mediagoblin.user_pages.user_home", "mediagoblin/user_pages/user.html"): add_to_user_home_context} Global context hook +++++++++++++++++++ +If you need to add something to the context of *every* view, it is not +hard; there are two hooks hook that also uses hook_transform (like the +above) but make available what you are providing to *every* view. +Note that there is a slight, but critical, difference between the two. + +The most general one is the ``'template_global_context'`` hook. This +one is run only once, and is read into the global context... all views +will get access to what are in this dict. + +The slightly more expensive but more powerful one is +``'template_context_prerender'``. This one is not added to the global +context... it is added to the actual context of each individual +template render right before it is run! Because of this you also can +do some powerful and crazy things, such as checking the request object +or other parts of the context before passing them on. From 0553976187a4ec870f944d2d4d17a4951075d2a8 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Wed, 15 May 2013 11:10:25 -0500 Subject: [PATCH 08/11] Hook->hooks since there's more than one of them :) --- docs/source/pluginwriter/api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/pluginwriter/api.rst b/docs/source/pluginwriter/api.rst index b411fa4d..56aaac77 100644 --- a/docs/source/pluginwriter/api.rst +++ b/docs/source/pluginwriter/api.rst @@ -106,8 +106,8 @@ and should return that modified object, like so:: "mediagoblin/user_pages/user.html"): add_to_user_home_context} -Global context hook -+++++++++++++++++++ +Global context hooks +++++++++++++++++++++ If you need to add something to the context of *every* view, it is not hard; there are two hooks hook that also uses hook_transform (like the From 1c6d2e87f7e0051f33b043e6e0de41ee66ae304b Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Wed, 15 May 2013 11:11:24 -0500 Subject: [PATCH 09/11] Oh right, actually add that hook we just documented, "template_context_prerender" :) This commit sponsored by William Goudie. Thanks Bill! :) --- mediagoblin/tools/template.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mediagoblin/tools/template.py b/mediagoblin/tools/template.py index aab571f0..3d651a6e 100644 --- a/mediagoblin/tools/template.py +++ b/mediagoblin/tools/template.py @@ -113,6 +113,13 @@ def render_template(request, template_path, context): (request.controller_name, template_path), context) + # More evil: allow plugins to possibly do something to the context + # in every request ever with access to the request and other + # variables. Note: this is slower than using + # template_global_context + context = hook_transform( + 'template_context_prerender', context) + rendered = template.render(context) if common.TESTS_ENABLED: From 38ebd05d1a759c3a057ab041124c313cf5724dc4 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Wed, 15 May 2013 11:29:43 -0500 Subject: [PATCH 10/11] Simple tyop, view->test... I was writing too many tests at the time :) --- docs/source/pluginwriter/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/pluginwriter/api.rst b/docs/source/pluginwriter/api.rst index 56aaac77..5e0568fd 100644 --- a/docs/source/pluginwriter/api.rst +++ b/docs/source/pluginwriter/api.rst @@ -63,7 +63,7 @@ that has a key in the format of the tuple:: (view_symbolic_name, view_template_path) Where the "view symbolic name" is the same parameter used in -``request.urlgen()`` to look up the test. So say we're wanting to add +``request.urlgen()`` to look up the view. So say we're wanting to add something to the context of the user's homepage. We look in mediagoblin/user_pages/routing.py and see:: From a1099bba79077c1258e586e2e2cbfe0094f10118 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Wed, 15 May 2013 11:40:28 -0500 Subject: [PATCH 11/11] Testing the template_context_prerender hook This allows for modifying any context *right before render*, including access to the variables that are passed in. This test takes advantage of that and takes one of the variables, "doubleme", and modifies it (doubles it!) In our case it turns "happy" and "joy" into "happyhappy" and "joyjoy". This commit sponsored by Mark Holmquist. Thank you! --- mediagoblin/tests/test_pluginapi.py | 6 ++++-- mediagoblin/tests/testplugins/modify_context/__init__.py | 8 +++++++- .../modify_context/templates/contextplugin/general.html | 1 + .../modify_context/templates/contextplugin/specific.html | 1 + mediagoblin/tests/testplugins/modify_context/views.py | 6 ++++-- 5 files changed, 17 insertions(+), 5 deletions(-) diff --git a/mediagoblin/tests/test_pluginapi.py b/mediagoblin/tests/test_pluginapi.py index 74a00ce0..73ad235e 100644 --- a/mediagoblin/tests/test_pluginapi.py +++ b/mediagoblin/tests/test_pluginapi.py @@ -348,11 +348,13 @@ def test_modify_context(context_modified_app): specific thing: in yer specificpage global thing: globally appended! -something: orother""" +something: orother +doubleme: happyhappy""" # General test, should have global context variable only result = context_modified_app.get("/modify_context/") assert result.body.strip() == """General page! global thing: globally appended! -lol: cats""" +lol: cats +doubleme: joyjoy""" diff --git a/mediagoblin/tests/testplugins/modify_context/__init__.py b/mediagoblin/tests/testplugins/modify_context/__init__.py index 6ddcd652..164e66c1 100644 --- a/mediagoblin/tests/testplugins/modify_context/__init__.py +++ b/mediagoblin/tests/testplugins/modify_context/__init__.py @@ -26,6 +26,11 @@ def append_to_global_context(context): context['global_append'] = 'globally appended!' return context +def double_doubleme(context): + if 'doubleme' in context: + context['doubleme'] = context['doubleme'] * 2 + return context + def setup_plugin(): routes = [ @@ -46,4 +51,5 @@ hooks = { 'setup': setup_plugin, ('modify_context.specific_page', 'contextplugin/specific.html'): append_to_specific_context, - 'template_global_context': append_to_global_context} + 'template_global_context': append_to_global_context, + 'template_context_prerender': double_doubleme} diff --git a/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html index 7b7261c6..9cf96d3e 100644 --- a/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html +++ b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/general.html @@ -2,3 +2,4 @@ General page! global thing: {{ global_append }} lol: {{ lol }} +doubleme: {{ doubleme }} diff --git a/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html index 25bea3e2..5b1b4c4a 100644 --- a/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html +++ b/mediagoblin/tests/testplugins/modify_context/templates/contextplugin/specific.html @@ -3,3 +3,4 @@ Specific page! specific thing: {{ specific_page_append }} global thing: {{ global_append }} something: {{ something }} +doubleme: {{ doubleme }} diff --git a/mediagoblin/tests/testplugins/modify_context/views.py b/mediagoblin/tests/testplugins/modify_context/views.py index 025c84d6..701ec6f9 100644 --- a/mediagoblin/tests/testplugins/modify_context/views.py +++ b/mediagoblin/tests/testplugins/modify_context/views.py @@ -21,11 +21,13 @@ def specific(request): return render_to_response( request, 'contextplugin/specific.html', - {"something": "orother"}) + {"something": "orother", + "doubleme": "happy"}) def general(request): return render_to_response( request, 'contextplugin/general.html', - {"lol": "cats"}) + {"lol": "cats", + "doubleme": "joy"})