.. This README is meant for consumption by humans and pypi. Pypi can render rst files so please do not use Sphinx features.
   If you want to learn more about writing documentation, please check out: http://docs.plone.org/about/documentation_styleguide.html
   This text does not appear on pypi or github. It is a comment.

.. image::
   https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336
       :target: https://pycqa.github.io/isort/

====================
visaplan.plone.tools
====================

General tools modules for Plone_.

We don't claim ultimate Plone wisdom (yet);
this package is one of the parts a big monolithic classic Zope product
was split into.

It is part of the footing of the "Unitracc family" of Plone sites
which are maintained by `visaplan GmbH`_, Bochum, Germany.

Some modules of this package might still contain some resources
(e.g. type names)
which are specific to our "Unitracc family" of sites;
this is likely to change in future releases.


Features
--------

This add-on can be seen in action at the following sites:

- https://www.unitracc.de
- https://www.unitracc.com

Modules in version 1.1.4+:

- ``attools`` module

  several tools for Archetypes-based content

- ``brains`` module

  currently one ``make_collector`` function, e.g. for address fields

- ``cfg`` module

  Read "product" configuration, and detect development mode

- ``context`` module

  Several tools for processing the request.
  Some need some modernization ...

- ``forms`` module

  Several tools for forms

- ``functions`` module

  Some functions, e.g. ``is_uid_shaped``

- ``indexes`` module (new in v1.1.4) 

  - Function ``getSortableTitle`` for title conversion.

    This converts umlauts etc. to sort them
    as equal to their corresponding base vocals,
    according to German lexical usage.

- ``log`` module

  Automatically named loggers

- ``mock`` module

  - a few small classes for use in doctests

  - the same module as ``visaplan.tools.mock``

- ``mock_cfg`` module

  A rudimentary mock module for ``cfg``

- ``search`` module

  A few functions to support creation of ZODB catalog search queries
  (quite proprietary, I'm afraid; might go away in future versions)

- ``setup`` module (since v1.1)

  Functions for use in migration scripts

- ``zcmlgen`` module (since v1.1.1)

  - Generates ``configure.zcml`` files, if

    - changes are detected, and

    - development mode is active, and

    - the source is in an development package.

- ``decorators`` module (since v1.1.6)

  - ``@returns_json``:

    Wraps the function call and returns the JSON_-encoded result,
    including HTTP headers.

    Uses simplejson_ if available.

Documentation
-------------

Sorry, we don't have real user documentation yet.

Most functions are documented by doctests, anyway;
it helps to understand some German.


Installation
------------

Since ``visaplan.plone.tools`` is a package for Plone instances,
it is not normally installed using ``pip``;
instead, install it by adding it to your buildout::

    [buildout]
    ...

    eggs =
        visaplan.plone.tools


and then running ``bin/buildout``


Contribute
----------

- Issue Tracker: https://github.com/visaplan/plone.tools/issues
- Source Code: https://github.com/visaplan/plone.tools


Support
-------

If you are having issues, please let us know;
please use the `issue tracker`_ mentioned above.


License
-------

The project is licensed under the GPLv2.

.. _`issue tracker`: https://github.com/visaplan/plone.tools/issues
.. _JSON: https://json.org/
.. _Plone: https://plone.org/
.. _simplejson: https://pypi.org/project/simplejson
.. _`visaplan GmbH`: http://visaplan.com

.. vim: tw=79 cc=+1 sw=4 sts=4 si et


Contributors
============

- Tobias Herp, tobias.herp@visaplan.com


Changelog
=========


2.0.0 (estimated)
-----------------

- Breaking changes:

  - ``forms.tryagain_url``:

    - all options (which are all arguments except the request)
      will `need to` be given by name
      (which is possible and `recommended already`).


1.4.9 (2021-12-13)
------------------

Improvements:

- If collective.metadataversion_ is installed, use the configured default set of
  indexes (if no `idxs` explicitly given but metadata recreation is requested)

[tobiasherp]


1.4.8 (2021-11-29)
------------------

New features: 

- New ``.setup`` function `load_and_cook`, for use in GenericSetup upgrade steps

[tobiasherp]


1.4.7 (2021-11-17)
------------------

Bugfixes:

- When detecting the currently active language (``.context.getActiveLanguage[_unchecked]``),
  we now check for the ``I18N_LANGUAGE`` cookie first.

[tobiasherp]


1.4.6 (2021-10-28)
------------------

Bugfixes:

- Fixed an error for the new functions in the ``.attools`` and ``.dxtools`` modules
  when giving the schema as positional argument
  (which to use isn't implemented yet for ``.dxtools`` anyway).

[tobiasherp]


1.4.5 (2021-10-27)
------------------

(If using the new functions in the .axtools  module, please use release
1.4.6+ instead).

Breaking changes:

- Removed the .metadata module which had been added in release 1.4.2;
  we have collective.metadataversion_ now to replace it,
  storing the `metadata_version`_ value persistently in the registry.

New features: 

- New .attools functions:

  - `get_first_text_as_html`
  - `get_all_texts`
  - `generate_all_texts`

- New .dxtools module, containing the functions:

  - `get_first_text_as_html`
  - `get_all_texts`
  - `generate_all_texts`

Profile changes:

- Removed the ``default`` profile;
  there is currently no point in installing this package as a Plone plugin.
  Just add it to your required eggs, and import from the modules.

  We keep the the ``uninstall`` profile *for now;*
  it will be removed in an near-future version.

  So, *don't "install"* this package (Quick-Installer, Plone add-ons);
  just use it in Python_ code!

  We keep the ``configure.zcml`` file and the autoinclude entry point, though;
  we can image to use e.g. the Plone registry for some settings.

[tobiasherp]


1.4.4 (2021-08-31)
------------------

Bugfixes:

- .setup.make_object_getter() didn't update the Language index when the language was changed

Improvements:

- .setup.make_object_getter() now additionally updates the following indexes
  when the .title attribute is changed:

  - sortable_title
  - SearchableText
  - getEffectiveIndex

[tobiasherp]


1.4.3 (2021-08-27)
------------------

New features: 

- ``.search`` module:

  - New conversion utilities ...

    - `make_querystring_mangle`, a factory, to create
    - `mangleQueryString`, using
    - `mangle_umlauts`

Miscellaneous:

- `normalizeQueryString` (as well as the new `mangleQueryString`)
   now auto-inserts asterisks at word ends *only*

[tobiasherp]


1.4.2 (2021-08-25)
------------------

New utilities:

- ``.context.getActiveLanguage_unchecked``: like `getActiveLanguage`,
  but not checking against the supported languages, and thus faster
  (e.g. for cache key functions)

Temporary changes:

- New ``.metadata`` module to support conditional metadata updates.

  **Note:** this is removed in release 1.4.5.
  If you need the `metadata_version`_ metadata column, please use collective.metadataversion_ instead.

[tobiasherp]


1.4.1 (2021-06-30)
------------------

Bugfixes:

- Bugfix for ``.setup.handle_subportal``

Hints:

- visaplan.plone.search contains a `make_input_text` function
  in it's ``.utils`` module
  which re-implements `make_input` without using BeautifulSoup.
  This will probably replace our present `make_input` function and then
  disregard any keyword options which are currently passed on to the
  BeautifulSoup_ constructor, i.e. the `factory` option.

  Perhaps we'll create a new visaplan.zope.tools package and move this
  functionality there, though.

[tobiasherp]


1.4.0 (2021-03-26)
------------------

Breaking changes:

- `.setup.switch_menu_item` ...

  - won't change anything if the `on` argument is `None`
  - won't accept (other) non-boolean arguments for `on`,
    unless `strict=False` is specified (new keyword-only argument)

Improvements:

- Working doctests for ``search`` module
- `zcmlgen` constructors support `skip` option

Requirements:

- visaplan.tools_ v1.3.1+

[tobiasherp]


1.3.0 (2020-12-16)
------------------

New Features:

- New module ``groups``

- New `.context` functions

  - `getMessenger` (factory):

    creates a `message` function which doesn't require
    (nor accept) a `context` argument

  - `getPath`
  - `get_parent`
  - `parents`
  - `parent_brains`
  - `make_brainGetter`
  - `make_pathByUIDGetter`
  - `make_translator`
  - `get_published_templateid`
  - `getSupportedLanguageTuples`

- New function ``setup.safe_context_id``

- New function ``search.normalizeQueryString`` (unicode, asterisks)

- `POSKeyError` rescue facility, *for now* provided here:

  Inspired by the  five.grok_-based ``@@fix-blobs`` view by Mikko Ohtamaa,
  we have two views:

  - ``@@check-blobs`` scans the site object tree for
    (Archetypes or Dexterity) objects with broken BLOB attachments
    (images or files) and shows them in an HTML list with checkboxes;

  - ``@@check-blobs-delete-selected`` allows to delete the objects
    found be be affected.

  *Note:* this functionality will likely be moved to a dedicated add-on package;
  don't rely on it to exist in *any* other release of this package!

- Optional functionality, depending on

  - visaplan.plone.search v1.2.1+
  - visaplan.plone.subportals

  (both currently not yet on PyPI)

Improvements:

- ``setup`` module:

  - If the ``reindex`` function, which was created by the ``make_reindexer`` factory,
    was given an object both by `brain` and by itself, it compared those two by identity,
    which wouldn't ever match.  Now checking for equality.

  - New function ``clone_tree`` (from release 1.2.0) now works recursively

  - When ``clone_tree`` moves objects from one folder to another, it tries to preserve a useful order;
    both functions ``_clone_tree_inner`` and ``_move_objects`` use the new helper ``apply_move_order_options``
    to inject a ``sort_on`` key into the query.

- ``context`` module:

  - ``message`` function (non-generated; with `context` argument):

    The default `mapping` is `None` now.

  - `make_permissionChecker` doesn't require the ``checkperm``
    adapter any more to be useful

  - `make_userdetector` doesn't require the ``auth``
    adapter any more to be useful

- Working doctests for ``search`` module

- ``zcmlgen`` module:

  - "Constructors" of the generator classes support an optional `skip` argument
    (keyword-only)

Hard dependencies removed:

- Products.Archetypes_

  if it is not installed, parts of the `.attools` module simply won't work

- visaplan.kitchen_

- visaplan.plone.infohubs_

  If not installed, `.forms.form_changes` *requires* a `form` argument
  (but it is a stub anyway).

[tobiasherp]


1.2.0 (2020-05-13)
------------------

New utilities:

- ``setup`` module:

  - New function ``clone_tree``, using
  - function factory ``make_object_getter``
    and
  - function factory ``make_subfolder_creator``

  Both factories have overlapping functionality and might become unified in a future version;
  their initial purposes were:

  ``make_object_getter`` creates a function (usually called ``get_object``)
  which tries to *find* a (possibly moved and/or renamed) object,
  and then is able to apply a few changes;

  ``make_subfolder_creator`` creates a function (usually called ``new_folder``)
  which creates a new *folder* (unless already present),
  and then is able to apply a few changes.

[tobiasherp]


1.1.6 (2019-11-27)
------------------

New modules:

- ``decorators`` module:

  - ``@returns_json``
    (uses simplejson_ if available)

New utilities:

- ``context`` module:

  - function factory ``make_timeformatter``

Bugfixes:

- Typo in README corrected.

[tobiasherp]


1.1.5 (2019-07-18)
------------------

Bugfixes:

- ``getConfiguration`` might fail; in such cases, log a warning and use the default
- Missing requirements:

  - visaplan.kitchen_

[tobiasherp]


1.1.4 (2019-05-09)
------------------

- ``indexes`` module added:

  - Function ``getSortableTitle`` for title conversion.

    This converts umlauts etc. to sort them
    as equal to their corresponding base vocals,
    according to German lexical usage.

- ``attools`` module:

  - New function ``notifyedit(context)``

- ``forms`` module:

  - ``tryagain_url`` function supports ``var_items`` argument

  - bugfix for ``make_input`` function (suppression of ``type`` attribute)

- ``zcmlgen`` module:

  - changes detection improved to explicitly ignore added/removed blank lines

- ``context`` module:

  - new functions ``message`` and ``getbrain``,
    as replacement for some adapters named alike

[tobiasherp]


1.1.3 (2019-01-29)
------------------

- ``setup.make_renamer()``: generated ``rename`` function improved:
  existing positional options default to ``None``; instead of ``uid``,
  ``o`` (object) or ``brain`` can be specified (by name).

- ``setup.make_query_extractor()``, generated ``extract_query`` function improved:
  don't convert a ``Language`` string to a list if it's value is ``all``

- ``zcmlgen`` module:

  - Bugfix for changes detection

  - If changes are found but disallowed (non-development setup),
    and if ``sys.stdout`` is connected to a terminal,
    start the debugger

  [tobiasherp]


1.1.2 (2018-11-21)
------------------

- Corrections for the documentation

- (currently) unused dependencies removed
  [tobiasherp]


1.1.1 (2018-09-27)
------------------

- ``zcmlgen`` module added:

  - Generates ``configure.zcml`` files, if

    - changes are detected (*buggy*; see v1.1.3), and

    - development mode is active, and

    - the source is in a development package.


1.1 (2018-09-17)
----------------

- ``attools`` module added:

  - a brown bag of tools for Archetypes

- ``brains`` module added:

  - ``make_collector``, e.g. for address fields

- ``forms`` module added:

  - a brown bag of modules to support forms in a Zope/Plone system

- ``mock`` module added:

  - a few small classes for use in doctests

  - the same module as visaplan.tools_ .mock

- ``mock_cfg`` module added:

  - accompanies ``cfg``, for testing only

- ``search`` module added:

  - tools for creation of catalog queries

- ``setup`` module added: functions for use in migration scripts

- Module changes:

  - ``context`` module:

    - new function ``decorated_tool``

  - ``functions`` module:

    - new function ``looksLikeAUID`` (for historical reasons)


1.0 (2018-07-11)
----------------

- Initial release.
  [tobiasherp]

.. _BeautifulSoup: https://pypi.org/project/beautifulsoup4/
.. _collective.metadataversion: https://pypi.org/project/collective.metadataversion
.. _five.grok: https://pypi.org/project/five.grok
.. _`metadata_version`: https://community.plone.org/t/metadata-column-metadata-version-for-conditional-metadata-refresh/14194/3
.. _Products.Archetypes: https://pypi.org/project/Products.Archetypes
.. _Python: https://www.python.org
.. _simplejson: https://pypi.org/project/simplejson
.. _visaplan.kitchen: https://pypi.org/project/visaplan.kitchen
.. _visaplan.plone.infohubs: https://pypi.org/project/visaplan.plone.infohubs
.. _visaplan.tools: https://pypi.org/project/visaplan.tools

