{ "info": { "author": "Souheil Chelfouh", "author_email": "souheil@chelfouh.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Environment :: Web Environment", "Framework :: Zope3", "Intended Audience :: Other Audience", "License :: OSI Approved :: GNU General Public License (GPL)", "Operating System :: OS Independent", "Programming Language :: Python" ], "description": "The package ``dolmen.app.viewselector`` is an extension for `Dolmen`\napplications, allowing a basic management of alternative views.\n\n\nAbout\n=====\n\nIn a CMS, it's often very useful to be able to design and provide several\nviews for a single item. These views can be relevant, according to a given\ncontext and situation. `dolmen.app.viewselector` allows you to define a\nview as being an \"alternate\" option to render a given context. A menu then\nprovides you the machinery to select the most relevant view for your\nusecase.\n\n\nA quick overview\n================\n\nTo know that a component can provide alternative views, we need to\nexplicitly specify it. An interface defines the \"selector\" capability::\n\n >>> from dolmen.app.viewselector import IViewSelector\n >>> list(IViewSelector)\n ['selected_view']\n\n >>> IViewSelector['selected_view']\n <...TextLine...>\n\nThe IViewSelector interface defines a single field, known as\n'selected_view'. The field value is merely the name of the Page\ncomponent currently used::\n\n >>> IViewSelector['selected_view'].default\n u'base_view'\n\nOut of the box, the default value is set to 'base_view'.\n\n\nDefining the content\n====================\n\nTo demonstrate the alternative views, we first need a context that is\naware of the views selection::\n\n >>> from zope.location import Location\n >>> from zope.interface import implements\n\n >>> class Bear(Location):\n ... implements(IViewSelector)\n ... selected_view = u\"sleeping\"\n\nWe defined the default view to the view named \"sleeping\".\n\n\nDefining alternate views\n========================\n\nThe alternative views are 'pages' (see ``megrok.layout`` and\n``dolmen.app.layout``) that are registered onto a dedicated menu.\nTo define an alternative view, we inherit from the ``AlternativeView``\nbase class::\n\n >>> import grokcore.view as grok\n >>> from grokcore.component import testing\n >>> from dolmen.app.viewselector import AlternativeView\n\n >>> class Sleeping(AlternativeView):\n ... grok.context(Bear)\n ... grok.title(\"Sleeping bear\")\n ...\n ... def render(self):\n ... return u\"RRrrr...\"\n\n >>> testing.grok_component('sleeping', Sleeping)\n True\n\nThe \"sleeping\" view that we defined as a default value for our IViewSelector\nis now defined and registered. Let's register 2 other views, to populate\nthe menu and provide a \"realistic\" usecase::\n\n >>> class PolarFur(AlternativeView):\n ... grok.context(Bear)\n ... grok.title(\"Polar bear\")\n ...\n ... def render(self):\n ... return u\"I'm white !\"\n\n >>> testing.grok_component('polar', PolarFur)\n True\n\n >>> class SpringFur(AlternativeView):\n ... grok.context(Bear)\n ... grok.title(\"Spring bear\")\n ... grok.require(\"dolmen.content.Edit\")\n ...\n ... def render(self):\n ... return u\"I'm brown !\"\n\n >>> testing.grok_component('spring', SpringFur)\n True\n\n\nDefault dynamic index\n=====================\n\nIn order to render the selected view, another view is used. We may call it a \n\"routing\" view, as it's used to lookup and render the desired component.\n\nWe first need to instance the two needed components, the content and\nthe request ::\n\n >>> from zope.publisher.browser import TestRequest\n\n >>> herman = Bear()\n >>> request = TestRequest()\n\nThe content provides IViewSelector, the interface for which the \"routing\"\nview is registered::\n\n >>> IViewSelector.providedBy(herman)\n True\n\nThe \"routing\" view is by convention called \"index\" and can be looked up\nas a basic view::\n\n >>> from zope.component import getMultiAdapter\n >>> index = getMultiAdapter((herman, request), name=\"index\")\n >>> index\n \n\nThis view, when rendered, will look up and render the view named as the\n`selected_view` attribute, registered for the same content and request::\n\n >>> herman.selected_view\n u'sleeping'\n\n >>> index.render()\n u'RRrrr...'\n\nIf we set a different value for the `selected_view` attribute, the looked up\nview changes accordingly::\n \n >>> herman.selected_view = u\"polarfur\"\n >>> index.render()\n u\"I'm white !\"\n\n >>> herman.selected_view = u\"springfur\"\n >>> index.render()\n u\"I'm brown !\"\n\nIf the view doesn't exist, a base message is returned::\n\n >>> herman.selected_view = u\"nothing\"\n >>> index.render()\n u'The selected view is not a valid IPage component.'\n\n\nApplying the view via the User interface\n========================================\n\nThe selected view can be chosen from a list of available alternative view.\nThis choice is made via a menu, for which the views are registered.\n\nMenu\n----\n\nLet's render the menu, to have a look at its structure.\nBefore we can get a functional menu, which requires a located content, we need\nto persist our content in a functional site::\n\n >>> from zope.component.hooks import getSite\n >>> site = getSite()\n\n >>> herman = site['herman'] = herman\n >>> herman.__name__\n u'herman'\n\nThe content located, we can instanciate the menu. The menu is handled by\n``megrok.menu`` and is a ``zope.browsermenu.IBrowserMenu`` component.\n\nA viewlet is registered in order to render this menu is a conventional way::\n\n >>> baseview = Sleeping(herman, request)\n\n >>> from dolmen.app.layout.master import AboveBody\n >>> from dolmen.app.viewselector.select import SelectableViews\n\n >>> manager = AboveBody(herman, request, baseview)\n >>> menu = SelectableViews(herman, request, baseview, manager)\n\nThe alternate views do use a security declaration and therefore, we need to\nlogin as a particular user, to test the rendering. Here, the `SpringFur`\nview requires the `dolmen.content.Edit` permission.\n\nLet's login as a used that doesn't have this permission granted::\n\n >>> login('zope.user')\n\nWhen rendering the menu, the `SpringFur` component will, therefore,\nbe omitted::\n\n >>> menu.update()\n >>> print menu.render()\n
\n
Content display
\n
\n \n
\n
\n\n >>> logout()\n\nIf we now log in with a user with the right permission granted, we see\nthat the component is correctly included::\n\n >>> login('zope.mgr')\n >>> menu.update()\n >>> print menu.render()\n
\n
Content display
\n
\n \n
\n
\n\n >>> logout()\n\n\nApply\n-----\n\nThe menu above exposes the view 'viewselector', registered for a \nIViewSelector content. This view is the component that effectively\nchanges the `selected_view` attribute to the clicked value.\n\nLet's simulate a click to test that view. The current value of the \n`selected_view` attribute is inconsistant::\n\n >>> herman.selected_view\n u'nothing'\n\nWe want it changed to something existing, like the `PolarFur` view::\n\n >>> request = TestRequest(form={'name': u'polarfur'})\n >>> handler = getMultiAdapter((herman, request), name=\"viewselector\")\n >>> handler\n \n\nLogged in as an admin user, we can apply the selected view::\n\n >>> login('zope.mgr', request)\n >>> handler()\n 'http://127.0.0.1/herman'\n\nThe view redirects you to the base view of the content. The value is\nnow changed::\n\n >>> herman.selected_view\n u'polarfur'\n\nChanges\n=======\n\n0.2.1 (2010-05-31)\n------------------\n\n - Fixed the egg dist, by removing the zip-safe flag.\n\n0.2 (2010-03-26)\n----------------\n\n - Fixed missing MANIFEST.\n\n\n0.1 (2010-03-25)\n----------------\n\n - Initial release.", "description_content_type": null, "docs_url": null, "download_url": "http://pypi.python.org/pypi/dolmen.app.viewselector", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://tracker.trollfot.org/", "keywords": "Grok Zope3 CMS Dolmen", "license": "GPL", "maintainer": null, "maintainer_email": null, "name": "dolmen.app.viewselector", "package_url": "https://pypi.org/project/dolmen.app.viewselector/", "platform": "Any", "project_url": "https://pypi.org/project/dolmen.app.viewselector/", "project_urls": { "Download": "http://pypi.python.org/pypi/dolmen.app.viewselector", "Homepage": "http://tracker.trollfot.org/" }, "release_url": "https://pypi.org/project/dolmen.app.viewselector/0.2.1/", "requires_dist": null, "requires_python": null, "summary": "Dolmen Layout/View Selector", "version": "0.2.1" }, "last_serial": 791324, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "26f99e2b30ce117f4dfc01d3ce474696", "sha256": "c28530b8069246f0759a008ecbb1b57d88a38f1a4ab24ba76da5d382b1e48938" }, "downloads": -1, "filename": "dolmen.app.viewselector-0.1.tar.gz", "has_sig": false, "md5_digest": "26f99e2b30ce117f4dfc01d3ce474696", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6133, "upload_time": "2010-03-25T01:24:06", "url": "https://files.pythonhosted.org/packages/0f/be/794b13f38bce651002d3c2abc9f8d0e06355e74890786219bbab2f9e4fbb/dolmen.app.viewselector-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "3217db9652efe282cf28d391323e9f28", "sha256": "9269b90377b3f063db546aa4563d6d3b3965a71414a39328630bca8384b3181c" }, "downloads": -1, "filename": "dolmen.app.viewselector-0.2.tar.gz", "has_sig": false, "md5_digest": "3217db9652efe282cf28d391323e9f28", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8662, "upload_time": "2010-03-26T10:50:08", "url": "https://files.pythonhosted.org/packages/33/25/a41ec4861a6b5aac290cc36b15d49ee55c04afba3c35006512afe2d22729/dolmen.app.viewselector-0.2.tar.gz" } ], "0.2.1": [ { "comment_text": "", "digests": { "md5": "efbc228f9a67de1ebc9233fd06490b2e", "sha256": "0cdb745c696325b0f8d5befc12703ac38d145126ad7f52336150e51b3a50ec67" }, "downloads": -1, "filename": "dolmen.app.viewselector-0.2.1.tar.gz", "has_sig": false, "md5_digest": "efbc228f9a67de1ebc9233fd06490b2e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8820, "upload_time": "2010-05-31T01:05:07", "url": "https://files.pythonhosted.org/packages/b8/3b/01ae6e4f0aee56c9f3407f9ceaadb16f75680b741118bcab1f8bc8dd30c0/dolmen.app.viewselector-0.2.1.tar.gz" } ], "1.0a1": [ { "comment_text": "", "digests": { "md5": "5fcf5a84a8e06d6e185310a2c098db06", "sha256": "9a87e768526967e27940f876e8aace8571c371fbf787a68c191eb0e15c82f55c" }, "downloads": -1, "filename": "dolmen.app.viewselector-1.0a1.tar.gz", "has_sig": false, "md5_digest": "5fcf5a84a8e06d6e185310a2c098db06", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8550, "upload_time": "2010-06-04T18:06:20", "url": "https://files.pythonhosted.org/packages/79/9d/cb6d819713a123713abc2fff49f7d0cab187ba5ffd88db1fb584b6e7ce57/dolmen.app.viewselector-1.0a1.tar.gz" } ], "1.0b1": [ { "comment_text": "", "digests": { "md5": "ff487a304f1327d0850314062520d933", "sha256": "88ae96a907a002aae60aa491df6638b9cfde6c6678fa71d78cf168f0a484cacb" }, "downloads": -1, "filename": "dolmen.app.viewselector-1.0b1.tar.gz", "has_sig": false, "md5_digest": "ff487a304f1327d0850314062520d933", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8743, "upload_time": "2011-02-15T00:39:49", "url": "https://files.pythonhosted.org/packages/71/37/7872a774c13b7e3dfd3b59a373039387e9f43c40e325535621560de27269/dolmen.app.viewselector-1.0b1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "efbc228f9a67de1ebc9233fd06490b2e", "sha256": "0cdb745c696325b0f8d5befc12703ac38d145126ad7f52336150e51b3a50ec67" }, "downloads": -1, "filename": "dolmen.app.viewselector-0.2.1.tar.gz", "has_sig": false, "md5_digest": "efbc228f9a67de1ebc9233fd06490b2e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8820, "upload_time": "2010-05-31T01:05:07", "url": "https://files.pythonhosted.org/packages/b8/3b/01ae6e4f0aee56c9f3407f9ceaadb16f75680b741118bcab1f8bc8dd30c0/dolmen.app.viewselector-0.2.1.tar.gz" } ] }