Introduction
============
``plone.resource`` publishes directories of static files via the ZPublisher.
These directories may be located either in the ZODB (as OFS folders and files), or on the filesystem.
Each resource directory has a type and a name. When combined, these are used to traverse to the resource directory.
For example::
    /++theme++mytheme/<subpath>
    /++sitelayout++mylayout/<subpath>
    /++templatelayout++mylayout<subpath>
Where resources can be stored
-----------------------------
Resource directory contents can be found by the traverser in several different places.
The following locations are tried in order.
Files in the ZODB
^^^^^^^^^^^^^^^^^
Installing ``plone.resource`` creates a Zope-folder called ``portal_resources``.
It can be used to store resource directories persistently.
By convention:
- the top-level folders under this folder correspond to resource types,
- the second-level folders correspond to the resource directory name.
So, the file traversable at ``/++theme++mytheme/myfile`` could be physically located at ``some_site/++etc++site/resources/theme/mytheme``
.. TODO (XXX: provide a helper to upload a tarball/zip)
Files in Python distributions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A folder in a Python distribution (e.g. egg) can be registered as a resource directory of a particular type and name using the ``plone:static`` ZCML directive.
For example, this registers a directory named "theme" as a resource directory of type "theme" under the name "mytheme".
It would be accessible at ``++theme++mytheme``::
    <plone:static
        directory="theme"
        type="theme"
        name="mytheme"
    />
  .. note::
     You must do ``<include package="plone.resource" file="meta.zcml"/>``
     before you can use the plone:static directive.
The name of the resource directory defaults to the name of the package, so can be omitted.
E.g. the following directive in a package named "mytheme" would result in the same registration as above::
    <plone:static
        directory="resources"
        type="theme"
    />
Traversing upward in directory paths using ``..`` is not supported for security reasons, as it could allow unwanted file access.
Minimum zcml config example
^^^^^^^^^^^^^^^^^^^^^^^^^^^
::
    <configure xmlns:plone="http://namespaces.plone.org/plone">
      <include package="plone.resource" file="meta.zcml"/>
      <plone:static
          directory="resources"
          type="theme"
          name="myproject"
        />
    </configure>
    ..
Files in a central resource directory
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If the ``plone:static`` directive is used from ``site.zcml`` (i.e., with no active package in the ZCML import context),
then it may specify the absolute path to a top-level resources directory.
This directory should have the same sub-directory structure as explained above (in-ZODB resources directory):
- the top-level folders under this folder correspond to resource types,
- the second-level folders correspond to the resource directory name.
In addition, in order for resources to be available, the top-level directories *require a traverser* to be registered!
For example, the following in ``site.zcml`` registers the given path within the buildout root::
    <plone:static
        directory="/path/to/buildout/resources"
    />
In order to automate this at buildout time, `plone.recipe.zope2instance`_  recipe has the option ``resources``.
It injects the above zcml snippet with into ``site.zcml`` by specifying the option like this::
      [instance]
      ...
      resources = ${buildout:directory}/resources
      ...
Example:
Using ``plone.app.theming`` - which provides the ``++theme++`` traverser - given an image file located in filesystem at::
    ${buildout:directory}/resources/theme/my.project/logo.png``
This would be traversable at a URL like so::
    http://localhost:8080/Plone/++theme++my.project/logo.png
.. _`plone.recipe.zope2instance`: http://pypi.python.org/pypi/plone.recipe.zope2instance
Additional traversers
---------------------
Custom traversers can be registered via ZCML using an adapter like so::
    <adapter
        name="demo"
        for="* zope.publisher.interfaces.IRequest"
        provides="zope.traversing.interfaces.ITraversable"
        factory="my.project.traversal.MyTraverser"
    />
with a corresponding simple factory definition of::
    from plone.resource.traversal import ResourceTraverser
    class MyTraverser(ResourceTraverser):
        name = 'demo'
This, when coupled with configuration like that in the `Files in a central resource directory`_ section above, would mean that resources located at::
    ${buildout:directory}/resources/demo/my.project/logo.png
would be traversable at a URL like so::
    http://localhost:8080/Plone/++demo++my.project/logo.png
.. TODO: What types of resources can be stored
Changelog
=========
.. You should *NOT* be adding new change log entries to this file.
   You should create a file in the news directory instead.
   For helpful instructions, please see:
   https://github.com/plone/plone.releaser/blob/master/ADD-A-NEWS-ITEM.rst
.. towncrier release notes start
3.0.3 (2025-09-10)
------------------
Internal:
- Move distribution to src layout [gforcada] (#4217)
3.0.2 (2024-04-23)
------------------
Bug fixes:
- Import IPloneSiteRoot from plone.base. @davisagli (#45)
3.0.1 (2024-01-22)
------------------
Internal:
- Update configuration files.
  [plone devs] (047ec50d, 6e36bcc4)
3.0.0 (2023-04-27)
------------------
Breaking changes:
- Drop Plone 5.2 and Python 2 support.
  [gforcada] (#6)
Internal:
- Update configuration files.
  [plone devs] (2a4ba395)
2.1.4 (2021-06-14)
------------------
Bug fixes:
- Do not throw an error when traversing to a FilesystemResourceDirectory (#31)
2.1.3 (2020-09-28)
------------------
Bug fixes:
- Fixed various warnings.
  [maurits] (#3130)
2.1.2 (2020-04-22)
------------------
Bug fixes:
- Minor packaging updates. (#1)
2.1.1 (2019-02-08)
------------------
Bug fixes:
- Fix deprecation and resource warnings. [gforcada] (#29)
2.1.0 (2018-11-02)
------------------
Bug fixes:
- Fix tests in py3.
  [pbauer, jensens]
- Change name of IResourceDirectoryDirective to TextLine to work with zope.configuration >= 4.2.
  See https://github.com/plone/Products.CMFPlone/issues/2591
  [pbauer]
2.0.2 (2018-06-04)
------------------
Bug fixes:
- More Python 3 fixes.
  [ale, pbauer]
2.0.1 (2018-02-05)
------------------
New features:
- Add python 2 / 3 compatibility
2.0.0 (2018-01-17)
------------------
Breaking changes:
- Remove Python2.6 support.
  [ale-rt]
Bug fixes:
- Fixed 'ValueError: substring not found' in ``FilesystemResourceDirectory`` representation.
  This happens when you register a directory with a name that differs from the directory name.
  Visiting the ``/++theme++myname`` url would then give this error.
  We also avoid listing a longer part of the path in case the directory name happens to be in the path multiple times.
  [maurits]
1.2.1 (2016-12-30)
------------------
Bug fixes:
- 'unittest2' is a test dependency, make this explicit in setup.py.
  [jensens]
1.2 (2016-11-09)
----------------
New features:
- Fire events on resources creation/modification
  [jpgimenez, ebrehault]
1.1 (2016-10-04)
----------------
New features:
- Use ``mimetypes_registry`` utility to determine mimetype if available.
  [jensens]
Bug fixes:
- Remove duplicate import
  [jensens]
- Add coding headers on python files.
  [gforcada]
1.0.7 (2016-09-08)
------------------
Bug fixes:
- Applied 20160830 security hotfix.  [maurits]
1.0.6 (2016-08-10)
------------------
Fixes:
- Do not leave an ``.svn`` file behind when running the tests.  [maurits]
- Use zope.interface decorator.
  [gforcada]
1.0.5 (2016-02-26)
------------------
Fixes:
- Test fix: ``clearZCML`` was removed from ``zope.component.tests``.
  [thet]
- Cleanup: PEP8, plone-coding conventions, ReST fixes, documentation
  overhaul, et al.
  [jensens]
1.0.4 (2015-03-21)
------------------
- use utf-8 encoding when writing more than just text/html
  [vangheem]
- provides a proper __contains__ method in FilesystemResourceDirectory
  [ebrehault]
1.0.3 (2014-10-13)
------------------
- security hardening: we don't want the anonymous user to look at our fs
  [giacomos]
1.0.2 (2013-01-01)
------------------
- Nothing changed yet.
1.0.1 (2012-05-25)
------------------
- Make sure text/html files imported as persistent files will be
  served with a utf-8 encoding. This fixes
  https://dev.plone.org/ticket/12838
  [davisagli]
1.0 (2012-04-15)
----------------
- Add __setitem__() support for writeable resource directories.
  [optilude]
1.0b6 (2011-11-24)
------------------
- Added rename() method for writable resource directories
  [optilude]
- Added cloneResourceDirectory() helper method in the utils module
  [optilude]
- Add a ++unique++ resource traverser for resource directories to cache as
  'plone.stableResource'.
  [elro]
1.0b5 (2011-06-08)
------------------
- Ensure any files are skipped in iterDirectoriesOfType.
  [elro]
1.0b4 (2011-05-29)
------------------
- Add queryResourceDirectory() helper method.
  [optilude]
1.0b3 (2011-05-23)
------------------
- Fix resource directory download bug with subdirectories.
  [elro]
1.0b2 (2011-05-16)
------------------
- Add a more compatible filestream iterator for filesystem files that allows
  coercion to string or unicode. This fixes possible compatibility issues
  with resource merging through Resource Registries.
  [optilude]
1.0b1 (2011-04-22)
------------------
- Initial release
            
         
        Raw data
        
            {
    "_id": null,
    "home_page": "https://pypi.org/project/plone.resource",
    "name": "plone.resource",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.8",
    "maintainer_email": null,
    "keywords": "plone resource",
    "author": "David Glick, Plone Foundation",
    "author_email": "davidglick@groundwire.org",
    "download_url": "https://files.pythonhosted.org/packages/18/65/6e000f251c8dda740f86472ca2db6b87a1b376183f3913f53cd787f161e9/plone_resource-3.0.3.tar.gz",
    "platform": null,
    "description": "Introduction\n============\n\n``plone.resource`` publishes directories of static files via the ZPublisher.\nThese directories may be located either in the ZODB (as OFS folders and files), or on the filesystem.\n\nEach resource directory has a type and a name. When combined, these are used to traverse to the resource directory.\nFor example::\n\n    /++theme++mytheme/<subpath>\n    /++sitelayout++mylayout/<subpath>\n    /++templatelayout++mylayout<subpath>\n\n\nWhere resources can be stored\n-----------------------------\n\nResource directory contents can be found by the traverser in several different places.\nThe following locations are tried in order.\n\nFiles in the ZODB\n^^^^^^^^^^^^^^^^^\n\nInstalling ``plone.resource`` creates a Zope-folder called ``portal_resources``.\nIt can be used to store resource directories persistently.\nBy convention:\n\n- the top-level folders under this folder correspond to resource types,\n- the second-level folders correspond to the resource directory name.\n\nSo, the file traversable at ``/++theme++mytheme/myfile`` could be physically located at ``some_site/++etc++site/resources/theme/mytheme``\n\n.. TODO (XXX: provide a helper to upload a tarball/zip)\n\n\nFiles in Python distributions\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nA folder in a Python distribution (e.g. egg) can be registered as a resource directory of a particular type and name using the ``plone:static`` ZCML directive.\nFor example, this registers a directory named \"theme\" as a resource directory of type \"theme\" under the name \"mytheme\".\nIt would be accessible at ``++theme++mytheme``::\n\n    <plone:static\n        directory=\"theme\"\n        type=\"theme\"\n        name=\"mytheme\"\n    />\n\n  .. note::\n     You must do ``<include package=\"plone.resource\" file=\"meta.zcml\"/>``\n     before you can use the plone:static directive.\n\nThe name of the resource directory defaults to the name of the package, so can be omitted.\nE.g. the following directive in a package named \"mytheme\" would result in the same registration as above::\n\n    <plone:static\n        directory=\"resources\"\n        type=\"theme\"\n    />\n\nTraversing upward in directory paths using ``..`` is not supported for security reasons, as it could allow unwanted file access.\n\nMinimum zcml config example\n^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n::\n\n    <configure xmlns:plone=\"http://namespaces.plone.org/plone\">\n      <include package=\"plone.resource\" file=\"meta.zcml\"/>\n      <plone:static\n          directory=\"resources\"\n          type=\"theme\"\n          name=\"myproject\"\n        />\n    </configure>\n\n    ..\n\nFiles in a central resource directory\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nIf the ``plone:static`` directive is used from ``site.zcml`` (i.e., with no active package in the ZCML import context),\nthen it may specify the absolute path to a top-level resources directory.\n\nThis directory should have the same sub-directory structure as explained above (in-ZODB resources directory):\n\n- the top-level folders under this folder correspond to resource types,\n- the second-level folders correspond to the resource directory name.\n\nIn addition, in order for resources to be available, the top-level directories *require a traverser* to be registered!\n\nFor example, the following in ``site.zcml`` registers the given path within the buildout root::\n\n    <plone:static\n        directory=\"/path/to/buildout/resources\"\n    />\n\nIn order to automate this at buildout time, `plone.recipe.zope2instance`_  recipe has the option ``resources``.\nIt injects the above zcml snippet with into ``site.zcml`` by specifying the option like this::\n\n      [instance]\n      ...\n      resources = ${buildout:directory}/resources\n      ...\n\nExample:\nUsing ``plone.app.theming`` - which provides the ``++theme++`` traverser - given an image file located in filesystem at::\n\n    ${buildout:directory}/resources/theme/my.project/logo.png``\n\nThis would be traversable at a URL like so::\n\n    http://localhost:8080/Plone/++theme++my.project/logo.png\n\n.. _`plone.recipe.zope2instance`: http://pypi.python.org/pypi/plone.recipe.zope2instance\n\nAdditional traversers\n---------------------\n\nCustom traversers can be registered via ZCML using an adapter like so::\n\n    <adapter\n        name=\"demo\"\n        for=\"* zope.publisher.interfaces.IRequest\"\n        provides=\"zope.traversing.interfaces.ITraversable\"\n        factory=\"my.project.traversal.MyTraverser\"\n    />\n\nwith a corresponding simple factory definition of::\n\n    from plone.resource.traversal import ResourceTraverser\n    class MyTraverser(ResourceTraverser):\n        name = 'demo'\n\nThis, when coupled with configuration like that in the `Files in a central resource directory`_ section above, would mean that resources located at::\n\n    ${buildout:directory}/resources/demo/my.project/logo.png\n\nwould be traversable at a URL like so::\n\n    http://localhost:8080/Plone/++demo++my.project/logo.png\n\n.. TODO: What types of resources can be stored\n\n\nChangelog\n=========\n\n.. You should *NOT* be adding new change log entries to this file.\n   You should create a file in the news directory instead.\n   For helpful instructions, please see:\n   https://github.com/plone/plone.releaser/blob/master/ADD-A-NEWS-ITEM.rst\n\n.. towncrier release notes start\n\n3.0.3 (2025-09-10)\n------------------\n\nInternal:\n\n\n- Move distribution to src layout [gforcada] (#4217)\n\n\n3.0.2 (2024-04-23)\n------------------\n\nBug fixes:\n\n\n- Import IPloneSiteRoot from plone.base. @davisagli (#45)\n\n\n3.0.1 (2024-01-22)\n------------------\n\nInternal:\n\n\n- Update configuration files.\n  [plone devs] (047ec50d, 6e36bcc4)\n\n\n3.0.0 (2023-04-27)\n------------------\n\nBreaking changes:\n\n\n- Drop Plone 5.2 and Python 2 support.\n  [gforcada] (#6)\n\n\nInternal:\n\n\n- Update configuration files.\n  [plone devs] (2a4ba395)\n\n\n2.1.4 (2021-06-14)\n------------------\n\nBug fixes:\n\n\n- Do not throw an error when traversing to a FilesystemResourceDirectory (#31)\n\n\n2.1.3 (2020-09-28)\n------------------\n\nBug fixes:\n\n\n- Fixed various warnings.\n  [maurits] (#3130)\n\n\n2.1.2 (2020-04-22)\n------------------\n\nBug fixes:\n\n\n- Minor packaging updates. (#1)\n\n\n2.1.1 (2019-02-08)\n------------------\n\nBug fixes:\n\n\n- Fix deprecation and resource warnings. [gforcada] (#29)\n\n\n2.1.0 (2018-11-02)\n------------------\n\nBug fixes:\n\n- Fix tests in py3.\n  [pbauer, jensens]\n\n- Change name of IResourceDirectoryDirective to TextLine to work with zope.configuration >= 4.2.\n  See https://github.com/plone/Products.CMFPlone/issues/2591\n  [pbauer]\n\n2.0.2 (2018-06-04)\n------------------\n\nBug fixes:\n\n- More Python 3 fixes.\n  [ale, pbauer]\n\n\n2.0.1 (2018-02-05)\n------------------\n\nNew features:\n\n- Add python 2 / 3 compatibility\n\n\n2.0.0 (2018-01-17)\n------------------\n\nBreaking changes:\n\n- Remove Python2.6 support.\n  [ale-rt]\n\nBug fixes:\n\n- Fixed 'ValueError: substring not found' in ``FilesystemResourceDirectory`` representation.\n  This happens when you register a directory with a name that differs from the directory name.\n  Visiting the ``/++theme++myname`` url would then give this error.\n  We also avoid listing a longer part of the path in case the directory name happens to be in the path multiple times.\n  [maurits]\n\n\n1.2.1 (2016-12-30)\n------------------\n\nBug fixes:\n\n- 'unittest2' is a test dependency, make this explicit in setup.py.\n  [jensens]\n\n\n1.2 (2016-11-09)\n----------------\n\nNew features:\n\n- Fire events on resources creation/modification\n  [jpgimenez, ebrehault]\n\n\n1.1 (2016-10-04)\n----------------\n\nNew features:\n\n- Use ``mimetypes_registry`` utility to determine mimetype if available.\n  [jensens]\n\nBug fixes:\n\n- Remove duplicate import\n  [jensens]\n\n- Add coding headers on python files.\n  [gforcada]\n\n1.0.7 (2016-09-08)\n------------------\n\nBug fixes:\n\n- Applied 20160830 security hotfix.  [maurits]\n\n\n1.0.6 (2016-08-10)\n------------------\n\nFixes:\n\n- Do not leave an ``.svn`` file behind when running the tests.  [maurits]\n\n- Use zope.interface decorator.\n  [gforcada]\n\n\n1.0.5 (2016-02-26)\n------------------\n\nFixes:\n\n- Test fix: ``clearZCML`` was removed from ``zope.component.tests``.\n  [thet]\n\n- Cleanup: PEP8, plone-coding conventions, ReST fixes, documentation\n  overhaul, et al.\n  [jensens]\n\n\n1.0.4 (2015-03-21)\n------------------\n\n- use utf-8 encoding when writing more than just text/html\n  [vangheem]\n\n- provides a proper __contains__ method in FilesystemResourceDirectory\n  [ebrehault]\n\n\n1.0.3 (2014-10-13)\n------------------\n\n- security hardening: we don't want the anonymous user to look at our fs\n  [giacomos]\n\n\n1.0.2 (2013-01-01)\n------------------\n\n- Nothing changed yet.\n\n\n1.0.1 (2012-05-25)\n------------------\n\n- Make sure text/html files imported as persistent files will be\n  served with a utf-8 encoding. This fixes\n  https://dev.plone.org/ticket/12838\n  [davisagli]\n\n1.0 (2012-04-15)\n----------------\n\n- Add __setitem__() support for writeable resource directories.\n  [optilude]\n\n1.0b6 (2011-11-24)\n------------------\n\n- Added rename() method for writable resource directories\n  [optilude]\n\n- Added cloneResourceDirectory() helper method in the utils module\n  [optilude]\n\n- Add a ++unique++ resource traverser for resource directories to cache as\n  'plone.stableResource'.\n  [elro]\n\n1.0b5 (2011-06-08)\n------------------\n\n- Ensure any files are skipped in iterDirectoriesOfType.\n  [elro]\n\n1.0b4 (2011-05-29)\n------------------\n\n- Add queryResourceDirectory() helper method.\n  [optilude]\n\n1.0b3 (2011-05-23)\n------------------\n\n- Fix resource directory download bug with subdirectories.\n  [elro]\n\n1.0b2 (2011-05-16)\n------------------\n\n- Add a more compatible filestream iterator for filesystem files that allows\n  coercion to string or unicode. This fixes possible compatibility issues\n  with resource merging through Resource Registries.\n  [optilude]\n\n1.0b1 (2011-04-22)\n------------------\n\n- Initial release\n",
    "bugtrack_url": null,
    "license": "GPL version 2 or later",
    "summary": "Static files for Plone",
    "version": "3.0.3",
    "project_urls": {
        "Homepage": "https://pypi.org/project/plone.resource"
    },
    "split_keywords": [
        "plone",
        "resource"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "82b77e1f5ae009937efa16daaa46b33bb2e8f4b29672238543419f95dd35c156",
                "md5": "ec6b6a934db4cc1426add8e86757da6c",
                "sha256": "6e428a45be01cfef0d303ea8bc284a727605f4507e4383314d421599dd0be2d6"
            },
            "downloads": -1,
            "filename": "plone_resource-3.0.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "ec6b6a934db4cc1426add8e86757da6c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.8",
            "size": 35983,
            "upload_time": "2025-09-10T15:25:04",
            "upload_time_iso_8601": "2025-09-10T15:25:04.945174Z",
            "url": "https://files.pythonhosted.org/packages/82/b7/7e1f5ae009937efa16daaa46b33bb2e8f4b29672238543419f95dd35c156/plone_resource-3.0.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "18656e000f251c8dda740f86472ca2db6b87a1b376183f3913f53cd787f161e9",
                "md5": "ff2775791a48dfdd5d6be359176a0f5e",
                "sha256": "03ba941fb1d01fe418c65f0eeb41707fb0f3241137c2155d9cfd790ad0cf6c83"
            },
            "downloads": -1,
            "filename": "plone_resource-3.0.3.tar.gz",
            "has_sig": false,
            "md5_digest": "ff2775791a48dfdd5d6be359176a0f5e",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.8",
            "size": 37137,
            "upload_time": "2025-09-10T15:25:06",
            "upload_time_iso_8601": "2025-09-10T15:25:06.160731Z",
            "url": "https://files.pythonhosted.org/packages/18/65/6e000f251c8dda740f86472ca2db6b87a1b376183f3913f53cd787f161e9/plone_resource-3.0.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-10 15:25:06",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "plone.resource"
}