{ "info": { "author": "Souheil Chelfouh", "author_email": "trollfot@gmail.com", "bugtrack_url": null, "classifiers": [ "License :: OSI Approved :: Zope Public License", "Programming Language :: Python", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "===============\nmegrok.resource\n===============\n\n`megrok.resource` is a package destined to integrate `hurry.resource`\nand `z3c.hashedresource` into Grok applications. \n\nSetup\n=====\n\nLet's import and init the necessary work environment::\n\n >>> import grokcore.component as grok\n >>> from zope.testbrowser.testing import Browser\n\n >>> browser = Browser()\n >>> browser.handleErrors = False \n\n\nLibrary\n=======\n\nA Library is a component meant to expose a folder containing\nresources::\n\n >>> from megrok import resource\n\n >>> class SomeCSS(resource.Library):\n ... resource.path('ftests/css')\n\n >>> grok.testing.grok_component('somecss', SomeCSS)\n True\n\nOnce grokked, the library provides the ILibrary interface and gets an\naccessible name::\n\n >>> from megrok.resource import ILibrary\n >>> ILibrary.providedBy(SomeCSS)\n True\n\n >>> SomeCSS.name\n 'somecss'\n\nAt this point, it should be accessible via the component architecture\nas a named adapter::\n\n >>> from zope.component import getAdapter\n >>> from zope.publisher.browser import TestRequest\n >>> library = getAdapter(TestRequest(), name='somecss')\n >>> library\n \n\n\nResources\n=========\n\nSimple resources\n----------------\n\nResources can be declared as part of their library, with their\ndependencies::\n\n >>> css_a = resource.ResourceInclusion(SomeCSS, 'a.css')\n >>> css_b = resource.ResourceInclusion(SomeCSS, 'b.css')\n\nGrouping resources\n------------------\n\nSometimes, resources need to be grouped logically. They can be\ndeclared in a group inclusion::\n\n >>> css_group = resource.GroupInclusion([css_a, css_b])\n >>> css_group.inclusions()\n [,\n ]\n\nLibrary resource\n----------------\n\nSometimes, it can be too cumbersome to declare the resources and the\nlibrary separatly. When the resource is not destined to be re-used, it\ncan be tempting to register everything with a single declaration. The\nResourceLibrary component is what you need in these situations.\n\nA Resource library is a mix between a library and a group\ninclusion. You need to define the usual path and name and then, the\nlinked resources::\n\n >>> class EasyResources(resource.ResourceLibrary):\n ... resource.path('ftests/css')\n ... resource.resource('a.css')\n ... resource.resource('b.css')\n\n >>> grok.testing.grok_component('someresources', EasyResources)\n True\n\nOnce the component has been grokked, the resources are available::\n\n >>> EasyResources.inclusions()\n [,\n ]\n\n\nIncluding resources in components\n=================================\n\nWhen rendering a web page we want to be able to include the resources\nwhere we need them. \n\nThere are several ways to include them. It can be done automatically\nupon traversal on any IResourcesIncluder component, or manually specified.\n\n\nTraversal inclusion\n-------------------\n\nFor this example, we'll create a view and use the automatic inclusion,\nusing the `include` directive::\n\n >>> from grokcore import view\n >>> from zope.interface import Interface\n\n >>> class MyView(view.View):\n ... grok.context(Interface)\n ... resource.include(css_a)\n ...\n ... def render(self): return \"\"\n\nFor the resources to be automatically included during the traversal,\nwe need to inform the publishing machinery that our component (the\nview), is a IResourcesIncluder. This is done automatically, when using\nthe \"include\" directive::\n\n >>> resource.IResourcesIncluder.implementedBy(MyView)\n True\n\nOf course, this should not remove the existing interfaces\nimplementations::\n\n >>> from zope.interface import Interface\n >>> class IMySuperIface(Interface): pass\n\n >>> class MyView(view.View):\n ... grok.context(Interface)\n ... grok.implements(IMySuperIface)\n ... resource.include(css_a)\n ...\n ... def render(self): return \"\"\n\n >>> resource.IResourcesIncluder.implementedBy(MyView)\n True\n >>> IMySuperIface.implementedBy(MyView)\n True\n\nThe `include` directive can be stacked, if several resources are to be\nincluded::\n\n >>> class AnotherView(MyView):\n ... resource.include(css_a)\n ... resource.include(css_b)\n\n >>> grok.testing.grok_component('AnotherView', AnotherView)\n True\n\n >>> browser.open('http://localhost/@@anotherview')\n >>> print browser.contents\n \n \n \n \n\nA ResourceLibrary component can be included just like a normal resource::\n\n >>> class YetAnotherView(view.View):\n ... grok.context(Interface)\n ... resource.include(EasyResources)\n ...\n ... def render(self):\n ...\t return u\"\"\n\n >>> grok.testing.grok_component('yav', YetAnotherView)\n True\n\n >>> browser.open('http://localhost/@@yetanotherview')\n >>> print browser.contents\n \n \n \n \n\n\nInclude validation\n------------------\n\nThe `include` directive will raise an error if the provided value is\nnot a valid inclusion object::\n\n >>> sneaky = object()\n\n >>> class FailingView(view.View):\n ... grok.context(Interface)\n ... resource.include(sneaky)\n ...\n ... def render(self):\n ...\t return u\"\"\n Traceback (most recent call last):\n ...\n ValueError: You can only include IInclusion or ResourceLibrary components.\n\nIt should accept non-grokked ResourceLibraries as valid inclusions::\n\n >>> class OtherResources(resource.ResourceLibrary):\n ... resource.path('ftests/css')\n ... resource.resource('a.css')\n\n >>> class TolerantView(view.View):\n ... grok.context(Interface)\n ... resource.include(OtherResources)\n ...\n ... def render(self):\n ...\t return u\"\"\n \n\nRemote inclusion\n-----------------\n\nUntil now, we've seen that the resource inclusion could be made using\nthe `include` directive. However, it can be very useful to be able to\nset inclusion on classes we don't \"own\". This \"remote\" inclusion is\ndone using the `component_includes` function.\n\nWe first register a view that includes no resources::\n\n >>> class DummyView(view.View):\n ... grok.context(Interface)\n ...\n ... def render(self):\n ...\t return u\"\"\n\n >>> grok.testing.grok_component('dummy', DummyView)\n True\n\nThe view class doesn't implement the needed interface::\n\n >>> resource.IResourcesIncluder.implementedBy(DummyView)\n False\n\nNow, we can use the remote inclusion function, to enable resources::\n\n >>> resource.component_includes(DummyView, css_group)\n >>> resource.IResourcesIncluder.implementedBy(DummyView)\n True\n >>> resource.include.bind().get(DummyView)\n []\n\nThis function can be used either on a class or an instance::\n\n >>> class UselessView(view.View):\n ... grok.context(Interface)\n ...\n ... def render(self): return u\"\"\n\n >>> grok.testing.grok_component('useless', UselessView)\n True\n\n >>> from zope.component import getMultiAdapter\n >>> useless = getMultiAdapter(\n ... (object(), TestRequest()), name=\"uselessview\")\n >>> useless\n \n\n >>> resource.component_includes(useless, css_group)\n >>> resource.IResourcesIncluder.providedBy(useless)\n True\n >>> resource.include.bind().get(useless)\n (,)\n\n\nCache and hash\n==============\n\nYou probably noticed the \"++noop++\" traverser, in the resource\nURL. This is used to provide a hash and therefore, a unique URL. It\ncan be very useful to work with caches and avoid outdated resources to\nbe served.\n\nHowever, it can happen that this behavior (by default) is unwanted. To\ndisable the use of the hashed URL, we can use the `use_hash` directive\nand set its value to False. This can be done either in the class\ndefinition or by using the directive `set` method::\n\n >>> from megrok.resource import use_hash\n >>> use_hash.set(SomeCSS, False)\n \n >>> browser.open('http://localhost/@@anotherview')\n >>> print browser.contents\n \n \n \n \n\nChangelog\n=========\n\n0.5 (2010-07-24)\n----------------\n\n* Removed specific ILibrary interface and now use the one from hurry.resource\n so the ILibraryUrl adapter found is the same for megrok.resource.Library and\n hurry.resource.Library. You need hurry.zoperesource 0.5 to have hashed\n resource for hurry.resource.Library instances.\n\n0.4.1 (2010-02-19)\n------------------\n\n* Fixed the case where a ResourceLibrary is included using the\n \"include\" directive, in the same package. It was triggering an error\n because a non-grokked ResourceLibrary does not provide\n `IInclusion`. The directive now checks the subclass of the value to\n determine if the given inclusion is a valid `IInclusion` or a\n ResourceLibrary sub-class.\n\n0.4 (2010-02-18)\n----------------\n\n* Cleaned the dependencies : everything is declared as it\n should. `zope.site` is now a main and not test dependency.\n\n* Renamed module \"traversal\" to \"url\", to describe accurately what the\n module is about : url computation.\n\n* \"mode\" from `hurry.resource` is now exposed by the package.\n\n0.3 (2009-12-23)\n----------------\n\n* The IResourcesIncluder interface is now automatically implemented\n by the class while using the `include` directive. This makes the\n whole system a lot more natural.\n\n* The interfaces have been moved to a dedicated module. If you used\n to import from `components`, please, correct your code.\n\n0.2 (2009-12-22)\n----------------\n\n* Added a ResourceLibrary component that is a mix between a Library\n and a GroupInclusion. It allows to declare both the Library and the\n Resources in a single class but impacts the re-usability.\n\n* Library now directly inherits from grokcore.view.DirectoryResource,\n to inherit the `get` method behavior. This inheritance was avoided\n to prevent grokkers clash (grokcore.view.DirectoryResource grokker\n doesn't have a fallback for the `name` directive.). Our grokker has\n now the priority and explicitly set the `name` directive value.\n\n0.1 (2009-12-21)\n----------------\n\n* Initial release", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pypi.python.org/pypi/megrok.resource", "keywords": "Grok Resources", "license": "ZPL 2.1", "maintainer": null, "maintainer_email": null, "name": "megrok.resource", "package_url": "https://pypi.org/project/megrok.resource/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/megrok.resource/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://pypi.python.org/pypi/megrok.resource" }, "release_url": "https://pypi.org/project/megrok.resource/0.5/", "requires_dist": null, "requires_python": null, "summary": "Grok Resources based on hurry.resource", "version": "0.5" }, "last_serial": 794652, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "e3a8d680bfbcec03b4c418d7a75aaa29", "sha256": "1d94f95cae97889c26cb3ac59e2679a74ff49571d437d3d8a0f2037b9c2b0ded" }, "downloads": -1, "filename": "megrok.resource-0.1.tar.gz", "has_sig": false, "md5_digest": "e3a8d680bfbcec03b4c418d7a75aaa29", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9476, "upload_time": "2009-12-21T00:58:08", "url": "https://files.pythonhosted.org/packages/22/e4/c875602065a8fed6e5562d260246659a30f350c62ae63b327731a70f1784/megrok.resource-0.1.tar.gz" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "6a54aa190003ac8c51624acca843df7d", "sha256": "8ce2fd39c977707872ea5b824275b95270130db8c00ca3b94eb9ddda958fcf5b" }, "downloads": -1, "filename": "megrok.resource-0.2.tar.gz", "has_sig": false, "md5_digest": "6a54aa190003ac8c51624acca843df7d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10764, "upload_time": "2009-12-23T00:49:01", "url": "https://files.pythonhosted.org/packages/85/cf/a4f96383986628c2ee0576ceb10f6dee59262bb261253d2e1b2cda30821b/megrok.resource-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "d95d1aa84c77916135ff12277e2993da", "sha256": "df6b8b41a04203098fb2843c42793c22a296b025ae3e6404a0e8d1ffa7623a20" }, "downloads": -1, "filename": "megrok.resource-0.3.tar.gz", "has_sig": false, "md5_digest": "d95d1aa84c77916135ff12277e2993da", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 11136, "upload_time": "2009-12-23T17:17:28", "url": "https://files.pythonhosted.org/packages/89/6f/42c16f08a4641f37530fc1866590de07fc518917be25d9f19aa477f87e57/megrok.resource-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "e48f0d63c3c9fe46a00e61b889155097", "sha256": "223bf0712c0e613178ac0c6448d58174815808fc9721f37524ac5fe2631d3bfd" }, "downloads": -1, "filename": "megrok.resource-0.4.tar.gz", "has_sig": false, "md5_digest": "e48f0d63c3c9fe46a00e61b889155097", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15115, "upload_time": "2010-02-18T14:40:53", "url": "https://files.pythonhosted.org/packages/c7/b0/f01ba68b62d8b18f6a6c2e56d32c523d1ac8ffb1fc046d7e3c0ac60d68c6/megrok.resource-0.4.tar.gz" } ], "0.4.1": [ { "comment_text": "", "digests": { "md5": "d9225b1f699afd771810deca02615d83", "sha256": "1e637a502eb5cf4af27f348b07ec396054ae4edfd69a3891300466ab440537e9" }, "downloads": -1, "filename": "megrok.resource-0.4.1.tar.gz", "has_sig": false, "md5_digest": "d9225b1f699afd771810deca02615d83", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15556, "upload_time": "2010-02-19T10:51:27", "url": "https://files.pythonhosted.org/packages/51/11/9326bd7b2a6cdbc6467e2345f97f01931bc323f51411dadc7864aeb32e10/megrok.resource-0.4.1.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "2062d2d761e3c72b838c7e9ac64ff765", "sha256": "07934ec4c0082e3a583de045bc910ce47ed153f6b39543d28956779fed75deae" }, "downloads": -1, "filename": "megrok.resource-0.5.zip", "has_sig": false, "md5_digest": "2062d2d761e3c72b838c7e9ac64ff765", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25462, "upload_time": "2010-07-24T15:27:55", "url": "https://files.pythonhosted.org/packages/4c/87/4ed20aed4749809aacec0c8860c84429ac9238042f26d2ca0fb9efab6699/megrok.resource-0.5.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "2062d2d761e3c72b838c7e9ac64ff765", "sha256": "07934ec4c0082e3a583de045bc910ce47ed153f6b39543d28956779fed75deae" }, "downloads": -1, "filename": "megrok.resource-0.5.zip", "has_sig": false, "md5_digest": "2062d2d761e3c72b838c7e9ac64ff765", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 25462, "upload_time": "2010-07-24T15:27:55", "url": "https://files.pythonhosted.org/packages/4c/87/4ed20aed4749809aacec0c8860c84429ac9238042f26d2ca0fb9efab6699/megrok.resource-0.5.zip" } ] }