Welcome, guest | Sign In | My Account | Store | Cart

Notice! PyPM is being replaced with the ActiveState Platform, which enhances PyPM’s build and deploy capabilities. Create your free Platform account to download ActivePython or customize Python with the packages you require and get automatic updates.

Download
ActivePython
INSTALL>
pypm install megrok.resourcelibrary

How to install megrok.resourcelibrary

  1. Download and install ActivePython
  2. Open Command Prompt
  3. Type pypm install megrok.resourcelibrary
 Python 2.7Python 3.2Python 3.3
Windows (32-bit)
0.9.2 Available View build log
Windows (64-bit)
0.9.2 Available View build log
Mac OS X (10.5+)
0.9.2 Available View build log
Linux (32-bit)
0.9.2 Available View build log
Linux (64-bit)
0.9.2 Available View build log
 
Author
License
ZPL
Lastest release
version 0.9.2 on Jan 5th, 2011

megrok.resourcelibrary: Resources in Grok

Introduction

Grok already comes equipped with a simple way to expose static file resources, the static directory.

megrok.resourcelibrary allows the more flexible inclusion of static file resources in Grok. It uses the zc.resourcelibrary package to do this.

A resource library is essentially like a directory like the static directory of a package, full of static resources, such as CSS files, javascript files and images. Resources are intended to be used from HTML pages, as additional resources to help display a particular layout or user interface.

How is megrok.resourcelibrary more flexible than Grok's default static directory?

  • A resource library can be in a layer.
  • A resource library can have a non-public permission.
  • A resource library can more easily be packaged for reuse by other

System Message: WARNING/2 (<string>, line 28)

Bullet list ends without a blank line; unexpected unindent.

libraries. Resource libraries have unique names under the control of the developer.

  • A resource library can automatically include some resources (such as

System Message: WARNING/2 (<string>, line 32)

Bullet list ends without a blank line; unexpected unindent.

javascript or css) in the head section of a web page whenever a particular widget needs it.

  • A resource library can also depend on other libraries.
Basic example

Let's see how this all works. First we need to grok this package itself (this is normally done from ZCML):

>>> from grok.testing import grok
>>> grok('megrok.resourcelibrary.meta')

Now we can set up a simple resource library:

>>> import grok
>>> import megrok.resourcelibrary
>>> class SomeLibrary(megrok.resourcelibrary.ResourceLibrary):

System Message: ERROR/3 (<string>, line 51)

Inconsistent literal block quoting.

... megrok.resourcelibrary.directory('tests/example')

We need to grok this to make it available (in normal use this is done automatically for you):

>>> from grok.testing import grok_component
>>> grok_component('SomeLibrary', SomeLibrary)

System Message: ERROR/3 (<string>, line 58)

Inconsistent literal block quoting.

True

The resources in this directory are now published, by default under the class name of the library, lower cased (therefore somelibrary):

>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
>>> browser.open('http://localhost/@@/somelibrary/my-lib/included.js')
>>> print browser.contents

System Message: ERROR/3 (<string>, line 68)

Inconsistent literal block quoting.

function be_annoying() { alert('Hi there!'); }

The default name can be overridden by using the grok.name directive:

>>> class SomeLibrary2(megrok.resourcelibrary.ResourceLibrary):

System Message: ERROR/3 (<string>, line 76)

Inconsistent literal block quoting.

... grok.name('some-library') ... megrok.resourcelibrary.directory('tests/example') >>> grok_component('SomeLibrary2', SomeLibrary2) True >>> browser.open('http://localhost/@@/some-library/my-lib/included.js') >>> print browser.contents function be_annoying() { alert('Hi there!'); }

It's an error to point to a directory that doesn't exist:

>>> class WrongDirectory(megrok.resourcelibrary.ResourceLibrary):

System Message: ERROR/3 (<string>, line 89)

Inconsistent literal block quoting.

... grok.name('wrong-directory') ... megrok.resourcelibrary.directory('tests/doesnt_exist') >>> grok_component('WrongDirectory', WrongDirectory) Traceback (most recent call last): ... GrokError: Directory 'tests/doesnt_exist' is not a valid directory passed to the 'wrong-directory' directive.

Automactic inclusion of resources

We now set up a resource library that automatically includes two resources whenever it is used in a web page, namely included.js and included.css:

>>> class MyLib(megrok.resourcelibrary.ResourceLibrary):

System Message: ERROR/3 (<string>, line 104)

Inconsistent literal block quoting.

... grok.name('my-lib') ... megrok.resourcelibrary.directory('tests/example/my-lib') ... megrok.resourcelibrary.include('included.js') ... megrok.resourcelibrary.include('included.css') >>> grok_component('MyLib', MyLib) True

This is how you require the library to be loaded in a particular page template:

<tal:block replace="resource_library:my-lib"/>

test_template_2 makes this requirement, so the included Javascript should be included:

>>> browser.open('http://localhost/zc.resourcelibrary.test_template_2')
>>> '/@@/my-lib/included.js' in browser.contents

System Message: ERROR/3 (<string>, line 121)

Inconsistent literal block quoting.

True

And the resource is also published:

>>> browser.open('/@@/my-lib/included.js')
>>> print browser.contents

System Message: ERROR/3 (<string>, line 127)

Inconsistent literal block quoting.

function be_annoying() { alert('Hi there!'); }

A reference to the CSS is also inserted into the HTML:

>>> browser.open('http://localhost/zc.resourcelibrary.test_template_2')
>>> '/@@/my-lib/included.css' in browser.contents

System Message: ERROR/3 (<string>, line 135)

Inconsistent literal block quoting.

True

And the CSS is available from the URL referenced:

>>> browser.open('/@@/my-lib/included.css')
>>> print browser.contents

System Message: ERROR/3 (<string>, line 141)

Inconsistent literal block quoting.

div .border { border: 1px silid black; }

Programmatically signalling resource requirements

Above we've demonstrated the use of the resource_library namespace in ZPT. Library usage can also be signalled programmatically, for instance in a view:

>>> import grok
>>> from zope.interface import Interface
>>> class View(grok.View):

System Message: ERROR/3 (<string>, line 155)

Inconsistent literal block quoting.

... grok.context(Interface) ... def render(self): ... MyLib.need() ... return '<html><head></head><body>Example</body></html>' >>> grok_component('View', View) True

>>> browser.open('http://localhost/view')
>>> '/@@/my-lib/included.js' in browser.contents
True

This also works for libraries which don't have an explicit grok.name:

>>> class MyLib2(megrok.resourcelibrary.ResourceLibrary):

System Message: ERROR/3 (<string>, line 169)

Inconsistent literal block quoting.

... megrok.resourcelibrary.directory('tests/example/my-lib') ... megrok.resourcelibrary.include('included.js') ... megrok.resourcelibrary.include('included.css') >>> grok_component('MyLib2', MyLib2) True

>>> class View2(grok.View):
...   grok.context(Interface)
...   def render(self):
...      MyLib2.need()
...      return '<html><head></head><body>Example</body></html>'
>>> grok_component('View2', View2)
True
>>> browser.open('http://localhost/view2')
>>> '/@@/mylib2/included.js' in browser.contents
True

You can also signal inclusion by library name instead (like is done in page templates):

>>> class View3(grok.View):

System Message: ERROR/3 (<string>, line 190)

Inconsistent literal block quoting.

... grok.context(Interface) ... def render(self): ... megrok.resourcelibrary.need('my-lib') ... return '<html><head></head><body>Example</body></html>'

>>> grok_component('View3', View3)
True
>>> browser.open('http://localhost/view3')
>>> '/@@/my-lib/included.js' in browser.contents
True
Making resource libraries depend on other ones

We can make a resource library depend on another one:

>>> class Dependency(megrok.resourcelibrary.ResourceLibrary):

System Message: ERROR/3 (<string>, line 208)

Inconsistent literal block quoting.

... megrok.resourcelibrary.directory('tests/example') ... megrok.resourcelibrary.include('1.js') >>> grok_component('Dependency', Dependency) True

>>> class Dependent(megrok.resourcelibrary.ResourceLibrary):
...    megrok.resourcelibrary.directory('tests/example')
...    megrok.resourcelibrary.include('2.css')
...    megrok.resourcelibrary.depend(Dependency)
>>> grok_component('Dependent', Dependent)
True

Let's make a view that needs Dependent:

>>> class DependentView(grok.View):

System Message: ERROR/3 (<string>, line 223)

Inconsistent literal block quoting.

... grok.context(Interface) ... def render(self): ... Dependent.need() ... return '<html><head></head><body>Example</body></html>' >>> grok_component('DependentView', DependentView) True

The included code of both the original and the dependency will now show up:

>>> browser.open('http://localhost/dependentview')
>>> '/@@/dependency/1.js' in browser.contents

System Message: ERROR/3 (<string>, line 235)

Inconsistent literal block quoting.

True >>> '/@@/dependent/2.css' in browser.contents True

Protecting resources

It's possible to give a resource a permission:

>>> class MyPermission(grok.Permission):

System Message: ERROR/3 (<string>, line 245)

Inconsistent literal block quoting.

... grok.name("my.permission") >>> grok_component('MyPermission', MyPermission) True

>>> class MyLib3(megrok.resourcelibrary.ResourceLibrary):
...    megrok.resourcelibrary.directory('tests/example/my-lib')
...    grok.require(MyPermission)
>>> grok_component('MyLib3', MyLib3)
True

XXX This doesn't work yet, as resources don't do their own security checks but rely on proxies, which Grok has removed... Need to introduce new resources/factories to do checks by hand.

Changes

0.9.2 (2008-08-08)
  • Grokker mistakenly relied on (not imported) GrokImportError in failure

System Message: WARNING/2 (<string>, line 266)

Bullet list ends without a blank line; unexpected unindent.

case. Corrected this to GrokError and added a test for it.

  • Rename use directive to depend and make it take a class

System Message: WARNING/2 (<string>, line 269)

Bullet list ends without a blank line; unexpected unindent.

argument instead of a library name.

0.9.1 (2008-08-06)
  • Turn off zip-safeness.
  • Actually add a meta.zcml that loads up the grokker!
0.9 (2008-08-06)
  • Initial public release.

Subscribe to package updates

Last updated Jan 5th, 2011

Download Stats

Last month:2

What does the lock icon mean?

Builds marked with a lock icon are only available via PyPM to users with a current ActivePython Business Edition subscription.

Need custom builds or support?

ActivePython Enterprise Edition guarantees priority access to technical support, indemnification, expert consulting and quality-assured language builds.

Plan on re-distributing ActivePython?

Get re-distribution rights and eliminate legal risks with ActivePython OEM Edition.