Introduction
============
The problem with “acquisition” and publishTraverse is that the current method returns too many different URLs for the same content.
For instance here is some potential url for the “kb” page of the plone.org website
- https://plone.org/documentation/kb
- https://plone.org/documentation/manual/kb
- https://plone.org/documentation/kb/manual/kb
- https://plone.org/documentation/manual/spinner.gif/kb
- ...
and here is a generic "Plone" site with two content items "a" and "b" (folderish or not)
- http://example.com/Plone/a
- http://example.com/Plone/a/b/a
- http://example.com/Plone/a
- http://example.com/Plone/b/a
- ...
All the urls above returns 200 with the same content,
while I would like the "canonical url" to return 200 and the other to return 404.
The behaviour described above constitute a problem because:
* multiple url for the same content is a problem for SEO and is confusing to people.
For SEO, in the latest versions Plone introduced the canonical META,
but IMHO it's just a workaround.
People are confused.
For example: sometimes some of my editors ask me:
"I can't remove the http://example.com/Plone/a/b/a/page. Can you do it for me?"
* the page doesn’t seem really the same on all urls:
if you open
https://plone.org/documentation/kb and
https://plone.org/documentation/manual/kb the second has a portlet that the first is missing
* removing page from external cache (varnish or squid), for example after a
content modification, will be a pain.
This is because for the same content there could be multiple urls without any control or rules
(``collective.purgebyid`` solves this)
* when using subsite (or multiple plone site on the same zope app) the problem is even more annoying:
suppose that "a" is a subsite (marked with INavigationRoot) for http://a.example.org and "b" for http://b.example.org.
Opening the url http://a.example.org/b will probably show the homepage of site "a" inside the "b" site.
``collective.siteisolation`` and probably ``collective.lineage`` do something to isolate subsite,
but IMHO again are only workarounds.
Usage
=====
This is a monkey patch for publishTraverse method of Zope2's
``ZPublisher.BaseRequest.DefaultPublishTraverse`` and a monkey patch
for ``Products.Archetypes.BaseObject.BaseObject.__bobo_traverse__``
By default invalid traverse is only logged as warning.
For enable raising exceptions, you need to manually modify ``config.py`` changing ``DRYRUN`` to ``False``.
Or using ``plone.recipe.zope2instance >= 4.2.14``, e.g.::
[instance]
recipe = plone.recipe.zope2instance
eggs =
experimental.noacquisition
...
initialization =
from experimental.noacquisition import config
config.DRYRUN = False
Warning
=======
**USE AT YOUR OWN RISK**
Don't use it, if you don't know exactly what are you doing... at least use leaving ``DRYRUN = True``.
Tests
=====
This add-on is tested using Travis CI. The current status of the add-on is :
.. image:: https://secure.travis-ci.org/collective/experimental.noacquisition.png
:target: http://travis-ci.org/collective/experimental.noacquisition
Other solutions
===============
There is a more elegant solution in a branch of Products.CMFPlone, that makes use of IPubAfterTraversal event instead of a monkey patch.
But seems that currently it doesn't works for all cases, at least when there is a custom traversal at the end of the request (take a look at the tests inside this package).
https://github.com/plone/Products.CMFPlone/tree/publication-through-explicit-acquisition
There is also other packages with same approach as CMFPlone's branch:
`collective.explicitacquisition <https://github.com/collective/collective.explicitacquisition>`_ and
`collective.redirectacquired <https://github.com/collective/collective.redirectacquired>`_
Changelog
=========
1.0.0b10 (2023-02-09)
---------------------
- Zope < 6 (no changes)
[daniele-andreotti]
1.0.0b9 (2020-07-02)
--------------------
- Zope < 5 (no changes)
[mamico]
1.0.0b7 (2019-12-10)
--------------------
- Zope < 4.2 (no changes)
[mamico]
1.0.0b6 (2019-11-07)
--------------------
- Python3 Plone 5.2
[mamico]
1.0.0b5 (2019-06-05)
--------------------
- Zope2 2.13.28 (no changes)
[mamico]
1.0.0b4 (2018-05-14)
--------------------
- Zope2 2.13.27 (no changes)
[mamico]
1.0.0b3 (2017-05-09)
--------------------
- Zope2 2.13.26 (no changes)
[mamico]
1.0.0b2 (2016-06-10)
--------------------
- Zope2 2.13.24
[mamico]
1.0.0b1 (2015-10-23)
--------------------
- Zope2 2.13.23 (Plone 4.3.7/5.0)
[mamico]
1.0.0a5 (2014-10-31)
--------------------
- Nothing changed yet.
1.0.0a4 (2014-10-31)
--------------------
- Initial release
Raw data
{
"_id": null,
"home_page": "http://pypi.org/pypi/collective/experimental.noacquisition",
"name": "experimental.noacquisition",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "monkeypatch traverse",
"author": "Mauro Amico",
"author_email": "mauro.amico@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/06/c7/eb8bd38ce976fb2d853e89ceaf6c2f7f301296bb1487415d2f81f6be8610/experimental.noacquisition-1.0.0b10.tar.gz",
"platform": null,
"description": "Introduction\n============\n\nThe problem with \u201cacquisition\u201d and publishTraverse is that the current method returns too many different URLs for the same content. \nFor instance here is some potential url for the \u201ckb\u201d page of the plone.org website\n\n- https://plone.org/documentation/kb\n- https://plone.org/documentation/manual/kb\n- https://plone.org/documentation/kb/manual/kb\n- https://plone.org/documentation/manual/spinner.gif/kb\n- ...\n\nand here is a generic \"Plone\" site with two content items \"a\" and \"b\" (folderish or not)\n\n- http://example.com/Plone/a\n- http://example.com/Plone/a/b/a\n- http://example.com/Plone/a\n- http://example.com/Plone/b/a\n- ...\n\nAll the urls above returns 200 with the same content, \nwhile I would like the \"canonical url\" to return 200 and the other to return 404.\n\nThe behaviour described above constitute a problem because:\n\n* multiple url for the same content is a problem for SEO and is confusing to people. \n For SEO, in the latest versions Plone introduced the canonical META,\n but IMHO it's just a workaround. \n People are confused. \n For example: sometimes some of my editors ask me: \n \"I can't remove the http://example.com/Plone/a/b/a/page. Can you do it for me?\"\n\n* the page doesn\u2019t seem really the same on all urls: \n if you open\n https://plone.org/documentation/kb and\n https://plone.org/documentation/manual/kb the second has a portlet that the first is missing\n\n* removing page from external cache (varnish or squid), for example after a\n content modification, will be a pain. \n This is because for the same content there could be multiple urls without any control or rules \n (``collective.purgebyid`` solves this)\n\n* when using subsite (or multiple plone site on the same zope app) the problem is even more annoying: \n suppose that \"a\" is a subsite (marked with INavigationRoot) for http://a.example.org and \"b\" for http://b.example.org.\n Opening the url http://a.example.org/b will probably show the homepage of site \"a\" inside the \"b\" site.\n ``collective.siteisolation`` and probably ``collective.lineage`` do something to isolate subsite, \n but IMHO again are only workarounds.\n\nUsage\n=====\n\nThis is a monkey patch for publishTraverse method of Zope2's\n``ZPublisher.BaseRequest.DefaultPublishTraverse`` and a monkey patch\nfor ``Products.Archetypes.BaseObject.BaseObject.__bobo_traverse__``\n\nBy default invalid traverse is only logged as warning.\n\nFor enable raising exceptions, you need to manually modify ``config.py`` changing ``DRYRUN`` to ``False``. \n\nOr using ``plone.recipe.zope2instance >= 4.2.14``, e.g.::\n\n [instance]\n recipe = plone.recipe.zope2instance\n eggs =\n experimental.noacquisition\n ...\n initialization =\n from experimental.noacquisition import config\n config.DRYRUN = False\n\n\nWarning\n=======\n\n**USE AT YOUR OWN RISK**\n\nDon't use it, if you don't know exactly what are you doing... at least use leaving ``DRYRUN = True``.\n\nTests\n=====\n\nThis add-on is tested using Travis CI. The current status of the add-on is :\n\n.. image:: https://secure.travis-ci.org/collective/experimental.noacquisition.png\n :target: http://travis-ci.org/collective/experimental.noacquisition\n\n\nOther solutions\n===============\n\nThere is a more elegant solution in a branch of Products.CMFPlone, that makes use of IPubAfterTraversal event instead of a monkey patch. \nBut seems that currently it doesn't works for all cases, at least when there is a custom traversal at the end of the request (take a look at the tests inside this package).\nhttps://github.com/plone/Products.CMFPlone/tree/publication-through-explicit-acquisition\n\nThere is also other packages with same approach as CMFPlone's branch:\n`collective.explicitacquisition <https://github.com/collective/collective.explicitacquisition>`_ and\n`collective.redirectacquired <https://github.com/collective/collective.redirectacquired>`_\n\nChangelog\n=========\n\n1.0.0b10 (2023-02-09)\n---------------------\n\n- Zope < 6 (no changes)\n [daniele-andreotti]\n\n1.0.0b9 (2020-07-02)\n--------------------\n\n- Zope < 5 (no changes)\n [mamico]\n\n1.0.0b7 (2019-12-10)\n--------------------\n\n- Zope < 4.2 (no changes)\n [mamico]\n\n\n1.0.0b6 (2019-11-07)\n--------------------\n\n- Python3 Plone 5.2\n [mamico]\n\n\n1.0.0b5 (2019-06-05)\n--------------------\n\n- Zope2 2.13.28 (no changes)\n [mamico]\n\n\n1.0.0b4 (2018-05-14)\n--------------------\n\n- Zope2 2.13.27 (no changes)\n [mamico]\n\n\n1.0.0b3 (2017-05-09)\n--------------------\n\n- Zope2 2.13.26 (no changes)\n [mamico]\n\n1.0.0b2 (2016-06-10)\n--------------------\n\n- Zope2 2.13.24\n [mamico]\n\n1.0.0b1 (2015-10-23)\n--------------------\n\n- Zope2 2.13.23 (Plone 4.3.7/5.0)\n [mamico]\n\n1.0.0a5 (2014-10-31)\n--------------------\n\n- Nothing changed yet.\n\n\n1.0.0a4 (2014-10-31)\n--------------------\n\n- Initial release\n",
"bugtrack_url": null,
"license": "BSD",
"summary": "No acquistion during publish traverse",
"version": "1.0.0b10",
"split_keywords": [
"monkeypatch",
"traverse"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "06c7eb8bd38ce976fb2d853e89ceaf6c2f7f301296bb1487415d2f81f6be8610",
"md5": "e4d8980ee22acc8f6ef7524c2abef63a",
"sha256": "41898ff6a4cf0c4ce37f003b62902f8b22a46620b78f38e1b22256a17f2d4eef"
},
"downloads": -1,
"filename": "experimental.noacquisition-1.0.0b10.tar.gz",
"has_sig": false,
"md5_digest": "e4d8980ee22acc8f6ef7524c2abef63a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 12581,
"upload_time": "2023-02-09T12:40:12",
"upload_time_iso_8601": "2023-02-09T12:40:12.060300Z",
"url": "https://files.pythonhosted.org/packages/06/c7/eb8bd38ce976fb2d853e89ceaf6c2f7f301296bb1487415d2f81f6be8610/experimental.noacquisition-1.0.0b10.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-02-09 12:40:12",
"github": false,
"gitlab": false,
"bitbucket": false,
"lcname": "experimental.noacquisition"
}