Skip to content

Commit

Permalink
Merge pull request #186 from collective/i18n_support
Browse files Browse the repository at this point in the history
  • Loading branch information
pbauer authored Feb 17, 2023
2 parents 1d3f5d3 + ca3878c commit 8a47e3a
Show file tree
Hide file tree
Showing 25 changed files with 1,567 additions and 184 deletions.
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ Changelog
1.8 (unreleased)
----------------

- Add Spanish translation.
[macagua]

- Add i18n support.
[macagua]

- Fix html: improve mapping from scale to picture variant. [maurits]

- Allow overriding the fallback variant in img_variant_fixer.
Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ Contributors

- Maurits van Rees, [email protected]

- Fred van Dijk, [email protected]
- Fred van Dijk, [email protected]

- Leonardo J. Caballero G., [email protected]
40 changes: 23 additions & 17 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Export and import all kinds of data from and to Plone sites using a intermediate
The main use-case is migrations since it enables you to for example migrate from Plone 4 with Archetypes and Python 2 to Plone 6 with Dexterity and Python 3 in one step.
Most features use `plone.restapi` to serialize and deserialize data.

See also the training on migrating with exportimport: https://training.plone.org/migrations/exportimport.html
See also the training on migrating with ``exportimport``: https://training.plone.org/migrations/exportimport.html

.. contents:: Contents
:local:
Expand Down Expand Up @@ -96,7 +96,7 @@ When a in-place-migration is not required you can choose this addon to migrate t

* Export content from a Plone site (it supports Plone 4 and 5, Archetypes and Dexterity, Python 2 and 3).
* Import the exported content into a new site (Plone 5.2+, Dexterity, Python 3)
* Export and import relations, users and groups with their roles, translations, local roles, ordering, dedault-pages, comments, portlets and redirects.
* Export and import relations, users and groups with their roles, translations, local roles, ordering, default-pages, comments, portlets and redirects.

How to migrate additional features like Annotations or Marker Interfaces is discussed in the FAQ section.

Expand All @@ -107,7 +107,7 @@ You can use this addon to

* Archive your content as json
* Export data to prepare a migration to another system
* Combine content from mutiple plone-sites into one.
* Combine content from multiple plone-sites into one.
* Import a plone-site as a subsite into another.
* Import content from other systems as long as it fits the required format.
* Update or replace existing data
Expand Down Expand Up @@ -156,8 +156,8 @@ To fix this you can check the checkbox "Modify exported data for migrations".
This will modify the data during export:

* Drop unused data (e.g. `next_item` and `components`)
* Remove all relationfields
* Change some fieldnames that changed between AT and DX
* Remove all relation fields
* Change some field names that changed between Archetypes and Dexterity

* ``excludeFromNav`` → ``exclude_from_nav``
* ``allowDiscussion`` → ``allow_discussion``
Expand All @@ -174,8 +174,8 @@ This will modify the data during export:
* ``contactName`` → ``contact_name``
* ``contactPhone`` → ``contact_phone``

* Update view names on Folders and Collection thet changed since Plone 4.
* Export ATTopic and their criteria to Collections with querystrings.
* Update view names on Folders and Collection that changed since Plone 4.
* Export ``ATTopic`` and their criteria to Collections with querystrings.
* Update Collection-criteria.
* Links and images in Richtext-Fields of content and portlets have changes since Plone 4.
the view ``/@@fix_html`` allows you to fix these.
Expand All @@ -191,8 +191,8 @@ You can choose between four options how to deal with content that already exists
* Update: Reuse and only overwrite imported data
* Ignore: Create with a new id

Imported content is initially created with ``invokeFactory`` using portal_type and id of the exported item before deserialing the rest of the data.
You can set additional values by specifying a dict ``factory_kwargs`` that will be passed to the facory.
Imported content is initially created with ``invokeFactory`` using portal_type and id of the exported item before deserializing the rest of the data.
You can set additional values by specifying a dict ``factory_kwargs`` that will be passed to the factory.
Like this you can set values on the imported object that are expected to be there by subscribers to IObjectAddedEvent.


Expand Down Expand Up @@ -558,7 +558,7 @@ Here we drop empty lines from the creators:
item["creators"] = [i for i in item.get("creators", []) if i]
return item
This example migrates a PloneHelpCenter to a simple folder/document structure during import.
This example migrates a ``PloneHelpCenter`` to a simple folder/document structure during import.
There are a couple more types to handle (as folder or document) but you get the idea, don't you?

.. code-block:: python
Expand Down Expand Up @@ -834,7 +834,7 @@ It may also happen, when you have validators that rely on content or configurati

.. note::

For relationfields this is not necessary since relations are imported after content anyway!
For relation fields this is not necessary since relations are imported after content anyway!

There are two ways to handle these issues:

Expand Down Expand Up @@ -1279,7 +1279,7 @@ This custom export exports and imports some selected settings and addons from a
**Import:**

The import installs the addons and load the settings in the registry.
Since Plone 5 portal_properties is no longer used.
Since Plone 5 ``portal_properties`` is no longer used.

.. code-block:: python
Expand Down Expand Up @@ -1450,7 +1450,7 @@ Export:
)
return actions
Import exported PloneFormGen data into Easyform:
Import exported ``PloneFormGen`` data into ``Easyform``:

.. code-block:: python
Expand Down Expand Up @@ -2131,6 +2131,13 @@ Written by
:alt: Starzel.de


Translations
============

This product has been translated into

- Spanish


Installation
============
Expand All @@ -2147,14 +2154,14 @@ Install collective.exportimport by adding it to your buildout::

and then running ``bin/buildout``

You don't need to activate the add-on in the Site Setup Add-ons control panel to be able to use the forms @@export_content and @@import_content in your site.
You don't need to activate the add-on in the Site Setup Add-ons control panel to be able to use the forms ``@@export_content`` and ``@@import_content`` in your site.

You do need to add it to your buildout configuration and run buildout to make these features available at all. See https://docs.plone.org/manage/installing/installing_addons.html for details.

Installing in Plone 4
---------------------

collective.exportimport depends on plone.restapi . For Plone 4, you need to pin plone.restapi to 7.x . When installing plone.restapi version 7.x.x in Plone 4 you may need to add the following version pins to your buildout::
``collective.exportimport`` depends on ``plone.restapi``. For Plone 4, you need to pin ``plone.restapi`` to 7.x . When installing ``plone.restapi`` version 7.x.x in Plone 4 you may need to add the following version pins to your buildout::

[versions]
PyJWT = 1.7.1
Expand Down Expand Up @@ -2191,8 +2198,7 @@ collective.exportimport depends on plone.restapi . For Plone 4, you need to pin
contextlib2 = 0.6.0.post1


These versions are taken from the plone.restapi 7.x README: https://pypi.org/project/plone.restapi/7.8.1/

These versions are taken from the ``plone.restapi`` 7.x README: https://pypi.org/project/plone.restapi/7.8.1/


Contribute
Expand Down
15 changes: 8 additions & 7 deletions src/collective/exportimport/export_content.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from Acquisition import aq_base
from App.config import getConfiguration
from collective.exportimport import _
from collective.exportimport import config
from collective.exportimport.interfaces import IBase64BlobsMarker
from collective.exportimport.interfaces import IMigrationMarker
Expand Down Expand Up @@ -119,7 +120,7 @@ def __call__(

self.depth = int(depth)
self.depth_options = (
("-1", "unlimited"),
("-1", _(u"unlimited")),
("0", "0"),
("1", "1"),
("2", "2"),
Expand All @@ -134,9 +135,9 @@ def __call__(
)
self.include_blobs = int(include_blobs)
self.include_blobs_options = (
("0", "as download urls"),
("1", "as base-64 encoded strings"),
("2", "as blob paths"),
("0", _(u"as download urls")),
("1", _(u"as base-64 encoded strings")),
("2", _(u"as blob paths")),
)
self.include_revisions = include_revisions

Expand All @@ -146,7 +147,7 @@ def __call__(
return self.template()

if not self.portal_type:
api.portal.show_message(u"Select at least one type to export", self.request)
api.portal.show_message(_(u"Select at least one type to export"), self.request)
return self.template()

if self.include_blobs == 1:
Expand Down Expand Up @@ -194,7 +195,7 @@ def __call__(
json.dump(datum, f, sort_keys=True, indent=4)
if number:
f.write("]")
msg = u"Exported {} items ({}) as {} to {}".format(
msg = _(u"Exported {} items ({}) as {} to {}").format(
number, ", ".join(self.portal_type), filename, filepath
)
logger.info(msg)
Expand All @@ -218,7 +219,7 @@ def __call__(
json.dump(datum, f, sort_keys=True, indent=4)
if number:
f.write("]")
msg = u"Exported {} {}".format(number, self.portal_type)
msg = _(u"Exported {} {}").format(number, self.portal_type)
logger.info(msg)
api.portal.show_message(msg, self.request)
response = self.request.response
Expand Down
23 changes: 12 additions & 11 deletions src/collective/exportimport/export_other.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from Acquisition import aq_base
from App.config import getConfiguration
from collective.exportimport import _
from collective.exportimport import config
from OFS.interfaces import IOrderedContainer
from operator import itemgetter
Expand Down Expand Up @@ -80,7 +81,7 @@ class BaseExport(BrowserView):
def download(self, data):
filename = u"{}.json".format(self.__name__)
if not data:
msg = u"No data to export for {}".format(self.__name__)
msg = _(u"No data to export for {}").format(self.__name__)
logger.info(msg)
api.portal.show_message(msg, self.request)
return self.request.response.redirect(self.request["ACTUAL_URL"])
Expand All @@ -97,7 +98,7 @@ def download(self, data):
filepath = os.path.join(directory, filename)
with open(filepath, "w") as f:
json.dump(data, f, sort_keys=True, indent=4)
msg = u"Exported to {}".format(filepath)
msg = _(u"Exported to {}").format(filepath)
logger.info(msg)
api.portal.show_message(msg, self.request)
return self.request.response.redirect(self.request["ACTUAL_URL"])
Expand All @@ -121,7 +122,7 @@ class ExportRelations(BaseExport):
def __call__(
self, download_to_server=False, debug=False, include_linkintegrity=False
):
self.title = "Export relations"
self.title = _(u"Export relations")
self.download_to_server = download_to_server
if not self.request.form.get("form.submitted", False):
return self.index()
Expand Down Expand Up @@ -229,7 +230,7 @@ class ExportMembers(BaseExport):
def __init__(self, context, request):
super(ExportMembers, self).__init__(context, request)
self.pms = api.portal.get_tool("portal_membership")
self.title = "Export members, groups and roles"
self.title = _(u"Export members, groups and roles")
self.group_roles = {}

def __call__(self, download_to_server=False):
Expand Down Expand Up @@ -327,7 +328,7 @@ class ExportTranslations(BaseExport):
DROP_PATH = []

def __call__(self, download_to_server=False):
self.title = "Export translations"
self.title = _(u"Export translations")
self.download_to_server = download_to_server
if not self.request.form.get("form.submitted", False):
return self.index()
Expand Down Expand Up @@ -409,7 +410,7 @@ class ExportLocalRoles(BaseExport):
"""Export all local roles"""

def __call__(self, download_to_server=False):
self.title = "Export local roles"
self.title = _(u"Export local roles")
self.download_to_server = download_to_server
if not self.request.form.get("form.submitted", False):
return self.index()
Expand Down Expand Up @@ -466,7 +467,7 @@ class ExportOrdering(BaseExport):
"""Export all local roles"""

def __call__(self, download_to_server=False):
self.title = "Export ordering"
self.title = _(u"Export ordering")
self.download_to_server = download_to_server
if not self.request.form.get("form.submitted", False):
return self.index()
Expand Down Expand Up @@ -502,7 +503,7 @@ class ExportDefaultPages(BaseExport):
"""Export all default_page settings."""

def __call__(self, download_to_server=False):
self.title = "Export default pages"
self.title = _(u"Export default pages")
self.download_to_server = download_to_server
if not self.request.form.get("form.submitted", False):
return self.index()
Expand Down Expand Up @@ -581,7 +582,7 @@ def get_default_page_info(self, obj):

class ExportDiscussion(BaseExport):
def __call__(self, download_to_server=False):
self.title = "Export comments"
self.title = _(u"Export comments")
self.download_to_server = download_to_server
if not self.request.form.get("form.submitted", False):
return self.index()
Expand Down Expand Up @@ -620,7 +621,7 @@ def all_discussions(self):

class ExportPortlets(BaseExport):
def __call__(self, download_to_server=False):
self.title = "Export portlets"
self.title = _(u"Export portlets")
self.download_to_server = download_to_server
if not self.request.form.get("form.submitted", False):
return self.index()
Expand Down Expand Up @@ -755,7 +756,7 @@ def export_plone_redirects():

class ExportRedirects(BaseExport):
def __call__(self, download_to_server=False):
self.title = "Export redirects"
self.title = _(u"Export redirects")
self.download_to_server = download_to_server
if not self.request.form.get("form.submitted", False):
return self.index()
Expand Down
7 changes: 4 additions & 3 deletions src/collective/exportimport/fix_html.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: UTF-8 -*-
from Acquisition import aq_parent
from bs4 import BeautifulSoup
from collective.exportimport import _
from collections import defaultdict
from logging import getLogger
from plone import api
Expand Down Expand Up @@ -39,19 +40,19 @@

class FixHTML(BrowserView):
def __call__(self):
self.title = "Fix links to content and images in richtext"
self.title = _(u"Fix links to content and images in richtext")
if not self.request.form.get("form.submitted", False):
return self.index()
commit = self.request.form.get("form.commit", True)

msg = []

fix_count = fix_html_in_content_fields(context=self.context, commit=commit)
msg.append(u"Fixed HTML for {} fields in content items".format(fix_count))
msg.append(_(u"Fixed HTML for {} fields in content items").format(fix_count))
logger.info(msg[-1])

fix_count = fix_html_in_portlets(context=self.context)
msg.append(u"Fixed HTML for {} portlets".format(fix_count))
msg.append(_(u"Fixed HTML for {} portlets").format(fix_count))
logger.info(msg[-1])

# TODO: Fix html in tiles
Expand Down
Loading

0 comments on commit 8a47e3a

Please sign in to comment.