diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d4cdeb..62cb132 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,6 +28,21 @@ jobs: python-version: ${{ needs.config.outputs.python-version }} plone-version: ${{ needs.config.outputs.plone-version }} + i18n: + name: "Missing i18n:translate" + runs-on: ubuntu-latest + needs: + - config + + steps: + - uses: actions/checkout@v5 + - name: Install uv + uses: astral-sh/setup-uv@v6 + + - name: Check for untranslated strings + shell: bash + run: | + uvx i18ndude find-untranslated -n src/ test: name: "Backend: Test" needs: @@ -35,8 +50,8 @@ jobs: uses: plone/meta/.github/workflows/backend-pytest.yml@2.x strategy: matrix: - python-version: ['3.10', '3.11', '3.12', '3.13'] - plone-version: ['6.1-latest', '6.0-latest'] + python-version: ["3.10", "3.11", "3.12", "3.13"] + plone-version: ["6.1-latest", "6.0-latest"] with: python-version: ${{ matrix.python-version }} plone-version: ${{ matrix.plone-version }} diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 0e9306f..b23c262 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -1,3 +1,4 @@ # Contributors - Lur Ibargutxi [libargutxi@codesyntax.com] +- Mikel Larreategi [mlarreategi@codesyntax.com] diff --git a/LICENSE.md b/LICENSE.md index a3a620a..055bde9 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -cs_dynamicpages Copyright 2025, Lur Ibargutxi +cs_dynamicpages Copyright 2025, CodeSyntax This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 diff --git a/Makefile b/Makefile index fef1930..72b1955 100644 --- a/Makefile +++ b/Makefile @@ -54,7 +54,7 @@ requirements-mxdev.txt: pyproject.toml mx.ini ## Generate constraints file $(VENV_FOLDER): requirements-mxdev.txt ## Install dependencies @echo "$(GREEN)==> Install environment$(RESET)" - @uv venv --python=3.10 $(VENV_FOLDER) + @uv venv $(VENV_FOLDER) @uv pip install -r requirements-mxdev.txt .PHONY: sync @@ -131,4 +131,10 @@ test-coverage: $(VENV_FOLDER) ## run tests with coverage ## Add bobtemplates features (check bobtemplates.plone's documentation to get the list of available features) add: $(VENV_FOLDER) - /home/lur/plonecli_azkena/bin/plonecli add $(filter-out $@,$(MAKECMDGOALS)) + @uvx plonecli add -b .mrbob.ini $(filter-out $@,$(MAKECMDGOALS)) + +.PHONY: release +release: $(VENV_FOLDER) ## Create a release + @echo "$(GREEN)==> Create a release$(RESET)" + @uv pip install -e ".[release]" + @uv run fullrelease \ No newline at end of file diff --git a/README.md b/README.md index 99e93b6..5ff6edc 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,53 @@ # cs_dynamicpages -An addon to create dynamic pages for Plone +A new addon for Plone to create web-based dynamic pages. -## Features +The concept is pretty similar that of Volto blocks: -TODO: List our awesome features +- You can build a page using reusable items. +- Each item can have different fields +- Each item can have different views + +## Provided Content Types + +- DynamicPageFolder: this content type will be created in a given folder, and will be the container + where all the rows will be added. + +- DynamicPageRow: this content type will be the one that will be rendered in a separate row in the view + +- DynamicPageRowFeatured: this content type can be used to save static information that can be shown in a + row. For instance: each of the items of a slider need a title, a description or an image. They can be added + using this content-type + +## Provided View + +There is just one view `dynamic_view` registered for Folders and Naviation roots + +### Different fields + +To provide different fields, you should register standard `behaviors` to the `DynamicPageRow` +content type. + +### Custom views + +To provide different views, you should register standard views (using `zcml`). + +Those views must be registered for implementers of `cs_dynamicpages.content.dynamic_page_row.IDynamicPageRow` +and their name _must_ start by `cs_dynamicpages-`. + +To ease installation of such views in your products, `cs_dynamicpages.utils` contains 2 utility functions: + +- `add_custom_view`: function to add a given view to the list of available row types +- `enable_behavior`: function to enable the given behavior in the `DynamicPageRow` content type + +### Restrict fields in the row edit view + +You may register several behaviors for `DynamicPageRow` objects but only use some of the fields +provided by them in a given view. + +You can restrict which fields are shown in the edit form of the `DynamicPageRow` going to the +Dynamic Pages Controlpanel, and setting there the list of fields that will be shown when editing +each of the row types. ## Installation @@ -22,23 +65,23 @@ make create-site ## Contribute -- [Issue tracker](https://github.com/cs/cs_dynamicpages/issues) -- [Source code](https://github.com/cs/cs_dynamicpages/) +- [Issue tracker](https://github.com/codesyntax/cs_dynamicpages/issues) +- [Source code](https://github.com/codesyntax/cs_dynamicpages/) ### Prerequisites ✅ -- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned. -- [uv](https://6.docs.plone.org/install/create-project-cookieplone.html#uv) -- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make) -- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git) -- [Docker](https://docs.docker.com/get-started/get-docker/) (optional) +- An [operating system](https://6.docs.plone.org/install/create-project-cookieplone.html#prerequisites-for-installation) that runs all the requirements mentioned. +- [uv](https://6.docs.plone.org/install/create-project-cookieplone.html#uv) +- [Make](https://6.docs.plone.org/install/create-project-cookieplone.html#make) +- [Git](https://6.docs.plone.org/install/create-project-cookieplone.html#git) +- [Docker](https://docs.docker.com/get-started/get-docker/) (optional) ### Installation 🔧 1. Clone this repository, then change your working directory. ```shell - git clone git@github.com:cs/cs_dynamicpages.git + git clone git@github.com:codesyntax/cs_dynamicpages.git cd cs_dynamicpages ``` @@ -48,7 +91,6 @@ make create-site make install ``` - ### Add features using `plonecli` or `bobtemplates.plone` This package provides markers as strings (``) that are compatible with [`plonecli`](https://github.com/plone/plonecli) and [`bobtemplates.plone`](https://github.com/plone/bobtemplates.plone). @@ -83,4 +125,4 @@ The project is licensed under GPLv2. ## Credits and acknowledgements 🙏 -Generated using [Cookieplone (0.9.7)](https://github.com/plone/cookieplone) and [cookieplone-templates (6782781)](https://github.com/plone/cookieplone-templates/commit/6782781dae4bafb227467828066ab16b84c23750) on 2025-07-07 09:25:15.108762. A special thanks to all contributors and supporters! +Generated using [Cookieplone (0.9.7)](https://github.com/plone/cookieplone) and [cookieplone-templates (4d55553)](https://github.com/plone/cookieplone-templates/commit/4d55553d61416df56b3360914b398d675b3f72a6) on 2025-07-17 11:59:12.982862. A special thanks to all contributors and supporters! diff --git a/news/+1.internal b/news/+1.internal new file mode 100644 index 0000000..dba1d83 --- /dev/null +++ b/news/+1.internal @@ -0,0 +1 @@ +Initial release @codesyntax \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 601e8cd..e8d1739 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,49 +1,55 @@ [project] name = "cs_dynamicpages" dynamic = ["version"] -description = "An addon to create dynamic pages for Plone" +description = "A new addon for Plone" readme = "README.md" -license = "GPL-2.0-only" requires-python = ">=3.10" -authors = [ - { name = "Lur Ibargutxi", email = "libargutxi@codesyntax.com" }, -] -keywords = [ - "CMS", - "Plone", - "Python", -] +authors = [{ name = "CodeSyntax", email = "plone@codesyntax.com" }] +keywords = ["CMS", "Plone", "Python"] classifiers = [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", - "Framework :: Plone","Framework :: Plone :: 6.0","Framework :: Plone :: 6.1", + "Framework :: Plone", + "Framework :: Plone :: 6.0", + "Framework :: Plone :: 6.1", "Framework :: Plone :: Addon", "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "Operating System :: OS Independent", - "Programming Language :: Python","Programming Language :: Python :: 3.10","Programming Language :: Python :: 3.11","Programming Language :: Python :: 3.12","Programming Language :: Python :: 3.13", + "Programming Language :: Python", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", ] dependencies = [ "Products.CMFPlone", "plone.api", - "z3c.jbot", "collective.z3cform.datagridfield", + "plone.app.upgrade", ] [project.optional-dependencies] test = [ "horse-with-no-namespace", "plone.app.testing", - "plone.classicui","plone.restapi[test]", + "plone.app.contenttypes[test]", + "plone.classicui", + "plone.restapi[test]", "pytest", "pytest-cov", "pytest-plone>=0.5.0", ] +release = [ + "zest.releaser[recommended]", + "zestreleaser.towncrier", + "zest.pocompile", +] [project.urls] -Homepage = "https://github.com/cs/cs_dynamicpages" +Homepage = "https://github.com/codesyntax/cs_dynamicpages" PyPI = "https://pypi.org/project/cs_dynamicpages" -Source = "https://github.com/cs/cs_dynamicpages" -Tracker = "https://github.com/cs/cs_dynamicpages/issues" +Source = "https://github.com/codesyntax/cs_dynamicpages" +Tracker = "https://github.com/codesyntax/cs_dynamicpages/issues" [project.entry-points."plone.autoinclude.plugin"] @@ -63,9 +69,7 @@ build-backend = "hatchling.build" strict-naming = true [tool.hatch.build.targets.sdist] -exclude = [ - "/.github", -] +exclude = ["/.github"] [tool.hatch.build.targets.wheel] packages = ["src/cs_dynamicpages"] @@ -76,7 +80,7 @@ filename = "CHANGELOG.md" start_string = "\n" title_format = "## {version} ({project_date})" template = "news/.changelog_template.jinja" -issue_format = "[#{issue}](https://github.com/cs/cs_dynamicpages/issues/{issue})" +issue_format = "[#{issue}](https://github.com/collective/cs_dynamicpages/issues/{issue})" underlines = ["", "", ""] [[tool.towncrier.type]] @@ -131,7 +135,8 @@ lint.select = [ # mccabe "C90", # pycodestyle - "E", "W", + "E", + "W", # pyflakes "F", # pygrep-hooks @@ -168,6 +173,8 @@ testpaths = ["tests"] source_pkgs = ["cs_dynamicpages", "tests"] branch = true parallel = true -omit = [ - "src/cs_dynamicpages/locales/*.py", -] \ No newline at end of file +omit = ["src/cs_dynamicpages/locales/*.py"] + + +[tool.zest-releaser] +python-file-with-version = "src/cs_dynamicpages/__init__.py" diff --git a/src/cs_dynamicpages/behaviors/configure.zcml b/src/cs_dynamicpages/behaviors/configure.zcml index f6fdb95..1adb6ce 100644 --- a/src/cs_dynamicpages/behaviors/configure.zcml +++ b/src/cs_dynamicpages/behaviors/configure.zcml @@ -13,24 +13,33 @@ - - - - + + + + + + - - - - + + - - - @@ -38,7 +36,6 @@ - diff --git a/src/cs_dynamicpages/content/dynamic_page_folder.py b/src/cs_dynamicpages/content/dynamic_page_folder.py index 2150ff6..6feeffa 100644 --- a/src/cs_dynamicpages/content/dynamic_page_folder.py +++ b/src/cs_dynamicpages/content/dynamic_page_folder.py @@ -20,4 +20,4 @@ class IDynamicPageFolder(model.Schema): @implementer(IDynamicPageFolder) class DynamicPageFolder(Container): - """Content-type class for IDynamicPageFolder""" \ No newline at end of file + """Content-type class for IDynamicPageFolder""" diff --git a/src/cs_dynamicpages/content/dynamic_page_row.py b/src/cs_dynamicpages/content/dynamic_page_row.py index aed9969..e118f1e 100644 --- a/src/cs_dynamicpages/content/dynamic_page_row.py +++ b/src/cs_dynamicpages/content/dynamic_page_row.py @@ -11,7 +11,7 @@ # from z3c.form.browser.radio import RadioFieldWidget from zope import schema from zope.interface import implementer -from plone import api + log = getLogger(__name__) @@ -52,10 +52,12 @@ def featured_list(self): def show_featured_add_button(self): row_type = self.row_type - row_type_fields = api.portal.get_registry_record('cs_dynamicpages.dynamica_pages_control_panel.row_type_fields') + row_type_fields = api.portal.get_registry_record( + "cs_dynamicpages.dynamic_pages_control_panel.row_type_fields" + ) for row_type_field in row_type_fields: - if row_type_field['row_type'] == row_type: - return row_type_field['row_type_has_featured_add_button'] + if row_type_field["row_type"] == row_type: + return row_type_field["row_type_has_featured_add_button"] return False def render(self, request): diff --git a/src/cs_dynamicpages/content/dynamic_page_row_featured.py b/src/cs_dynamicpages/content/dynamic_page_row_featured.py index 1a20140..27ad5f5 100644 --- a/src/cs_dynamicpages/content/dynamic_page_row_featured.py +++ b/src/cs_dynamicpages/content/dynamic_page_row_featured.py @@ -1,5 +1,6 @@ # from plone.app.textfield import RichText # from plone.autoform import directives +from plone import api from plone.dexterity.content import Item # from plone.namedfile import field as namedfile @@ -9,7 +10,7 @@ # from z3c.form.browser.radio import RadioFieldWidget # from zope import schema from zope.interface import implementer -from plone import api + # from cs_dynamicpages import _ diff --git a/src/cs_dynamicpages/controlpanels/configure.zcml b/src/cs_dynamicpages/controlpanels/configure.zcml index d2f133e..00ad5c8 100644 --- a/src/cs_dynamicpages/controlpanels/configure.zcml +++ b/src/cs_dynamicpages/controlpanels/configure.zcml @@ -7,7 +7,7 @@ - + diff --git a/src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/__init__.py b/src/cs_dynamicpages/controlpanels/dynamic_pages_control_panel/__init__.py similarity index 100% rename from src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/__init__.py rename to src/cs_dynamicpages/controlpanels/dynamic_pages_control_panel/__init__.py diff --git a/src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/configure.zcml b/src/cs_dynamicpages/controlpanels/dynamic_pages_control_panel/configure.zcml similarity index 68% rename from src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/configure.zcml rename to src/cs_dynamicpages/controlpanels/dynamic_pages_control_panel/configure.zcml index 4409c48..b2e337f 100644 --- a/src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/configure.zcml +++ b/src/cs_dynamicpages/controlpanels/dynamic_pages_control_panel/configure.zcml @@ -7,17 +7,17 @@ > diff --git a/src/cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py b/src/cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py new file mode 100644 index 0000000..bf5203e --- /dev/null +++ b/src/cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py @@ -0,0 +1,218 @@ +from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory +from collective.z3cform.datagridfield.registry import DictRow +from cs_dynamicpages import _ +from cs_dynamicpages.interfaces import IBrowserLayer +from plone.app.registry.browser.controlpanel import ControlPanelFormWrapper +from plone.app.registry.browser.controlpanel import RegistryEditForm +from plone.autoform.directives import widget +from plone.restapi.controlpanels import RegistryConfigletPanel +from plone.z3cform import layout +from zope import schema +from zope.component import adapter +from zope.interface import Interface + + +class IRowTypeFieldsSchema(Interface): + row_type = schema.Choice( + title=_("Row type"), + required=True, + vocabulary="cs_dynamicpages.RowType", + ) + + each_row_type_fields = schema.List( + title=_("Row fields"), + description=_( + "Enter the fields that will be available when " + "editing this row type. This is useful to hide unused fields." + ), + required=True, + value_type=schema.TextLine(), + default=[], + ) + + row_type_has_featured_add_button = schema.Bool( + title=_("Has featured add button?"), + description=_( + "If selected a 'Add featured' button will be added in the edit " + "interface. This is useful for rows that have content pieces " + "inside them. For example in a slider row, there are slider items. " + "This button will be used to add those items." + ), + required=False, + default=False, + ) + + +class IRowWidthSchema(Interface): + row_width_label = schema.TextLine( + title=_("Row Width Label"), + description=_("This is the label corresponding to this width"), + required=True, + ) + + row_width_class = schema.TextLine( + title=_("Row Width CSS class"), + description=_("CSS class for the row width"), + required=True, + ) + + +class IDynamicPagesControlPanel(Interface): + widget(row_type_fields=DataGridFieldFactory) + row_type_fields = schema.List( + title=_("Row type fields"), + description=_( + "Here we have all the available views for the rows and their settings" + ), + required=True, + value_type=DictRow(title=_("Row type field"), schema=IRowTypeFieldsSchema), + default=[ + { + "row_type": "cs_dynamicpages-featured-view", + "each_row_type_fields": [ + "IBasic.title", + "IBasic.description", + "IRowWidth.width", + "IExtraClass.extra_class", + "IRelatedImage.related_image", + "IRelatedImage.image_position", + "ILinkInfo.link_text", + "ILinkInfo.link_url", + ], + "row_type_has_featured_add_button": False, + }, + { + "row_type": "cs_dynamicpages-featured-overlay-view", + "each_row_type_fields": [ + "IBasic.title", + "IBasic.description", + "IRowWidth.width", + "IExtraClass.extra_class", + "IRelatedImage.related_image", + "IRelatedImage.image_position", + "ILinkInfo.link_text", + "ILinkInfo.link_url", + ], + "row_type_has_featured_add_button": False, + }, + { + "row_type": "cs_dynamicpages-horizontal-rule-view", + "each_row_type_fields": [ + "IBasic.title", + "IRowWidth.width", + "IExtraClass.extra_class", + ], + "row_type_has_featured_add_button": False, + }, + { + "row_type": "cs_dynamicpages-spacer-view", + "each_row_type_fields": [ + "IBasic.title", + "IExtraClass.extra_class", + ], + "row_type_has_featured_add_button": False, + }, + { + "row_type": "cs_dynamicpages-slider-view", + "each_row_type_fields": [ + "IBasic.title", + "IRowWidth.width", + "IExtraClass.extra_class", + ], + "row_type_has_featured_add_button": True, + }, + { + "row_type": "cs_dynamicpages-features-view", + "each_row_type_fields": [ + "IBasic.title", + "IRowWidth.width", + "IExtraClass.extra_class", + ], + "row_type_has_featured_add_button": True, + }, + { + "row_type": "cs_dynamicpages-accordion-view", + "each_row_type_fields": [ + "IBasic.title", + "IRowWidth.width", + "IExtraClass.extra_class", + ], + "row_type_has_featured_add_button": True, + }, + { + "row_type": "cs_dynamicpages-query-columns-view", + "each_row_type_fields": [ + "IBasic.title", + "IRowWidth.width", + "IExtraClass.extra_class", + "ICollection.query", + "ICollection.sort_on", + "ICollection.sort_order", + "ICollection.betweeen", + "ICollection.limit", + "IRowColumns.columns", + ], + "row_type_has_featured_add_button": False, + }, + { + "row_type": "cs_dynamicpages-text-view", + "each_row_type_fields": [ + "IBasic.title", + "IRowWidth.width", + "IExtraClass.extra_class", + "IRichTextBehavior-text", + ], + "row_type_has_featured_add_button": False, + }, + ], + ) + + widget(row_widths=DataGridFieldFactory) + row_widths = schema.List( + title=_("Row widths"), + description=_("Here you can define the available widths for each row"), + required=True, + value_type=DictRow( + title=_("Row width"), + schema=Interface( + IRowWidthSchema, + ), + ), + default=[ + { + "row_width_label": "Narrow", + "row_width_class": "col-md-6 offset-md-3", + }, + { + "row_width_label": "Centered", + "row_width_class": "col-md-8 offset-md-2", + }, + { + "row_width_label": "Full width", + "row_width_class": "col-md-12", + }, + ], + ) + + +class DynamicPagesControlPanel(RegistryEditForm): + schema = IDynamicPagesControlPanel + schema_prefix = "cs_dynamicpages.dynamic_pages_control_panel" + label = _("Dynamic Pages Control Panel") + + +DynamicPagesControlPanelView = layout.wrap_form( + DynamicPagesControlPanel, ControlPanelFormWrapper +) + + +@adapter(Interface, IBrowserLayer) +class DynamicPagesControlPanelConfigletPanel(RegistryConfigletPanel): + """Control Panel endpoint""" + + schema = IDynamicPagesControlPanel + configlet_id = "dynamic_pages_control_panel-controlpanel" + configlet_category_id = "Products" + title = _("Dynamic Pages Control Panel") + group = "" + schema_prefix = "cs_dynamicpages.dynamic_pages_control_panel" diff --git a/src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/controlpanel.py b/src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/controlpanel.py deleted file mode 100644 index af17a25..0000000 --- a/src/cs_dynamicpages/controlpanels/dynamica_pages_control_panel/controlpanel.py +++ /dev/null @@ -1,111 +0,0 @@ -from cs_dynamicpages import _ -from cs_dynamicpages.interfaces import IBrowserLayer -from plone.app.registry.browser.controlpanel import ControlPanelFormWrapper -from plone.app.registry.browser.controlpanel import RegistryEditForm -from plone.restapi.controlpanels import RegistryConfigletPanel -from plone.z3cform import layout -from zope import schema -from zope.component import adapter -from zope.interface import Interface -from collective.z3cform.datagridfield.datagridfield import DataGridFieldFactory -from collective.z3cform.datagridfield.registry import DictRow -from plone.autoform.directives import widget - -class IRowTypeFieldsSchema(Interface): - row_type = schema.Choice( - title="Row type", - required=True, - vocabulary="cs_dynamicpages.RowType", - ) - - each_row_type_fields = schema.List( - title="Row type fields", - required=True, - value_type=schema.TextLine(), - default=[], - ) - - row_type_has_featured_add_button = schema.Bool( - title="Has featured add button", - required=False, - default=False, - ) - - -class IDynamicaPagesControlPanel(Interface): - widget(row_type_fields=DataGridFieldFactory) - row_type_fields = schema.List( - title=u"Row Type Fields", - required=True, - value_type=DictRow(title=u"Row Type Fields", schema=IRowTypeFieldsSchema), - default=[ - { - "row_type": "cs_dynamicpages-featured-view", - "each_row_type_fields": ["IBasic.title", "IBasic.description", "IRowWidth.width", "IRelatedImage.related_image", "IRelatedImage.image_position", "ILinkInfo.link_text", "ILinkInfo.link_url"], - "row_type_has_featured_add_button": False, - }, - { - "row_type": "cs_dynamicpages-featured-overlay-view", - "each_row_type_fields": ["IBasic.title", "IBasic.description", "IRowWidth.width", "IRelatedImage.related_image", "IRelatedImage.image_position", "ILinkInfo.link_text", "ILinkInfo.link_url"], - "row_type_has_featured_add_button": False, - }, - { - "row_type": "cs_dynamicpages-horizontal-rule-view", - "each_row_type_fields": ["IBasic.title", "IRowWidth.width"], - "row_type_has_featured_add_button": False, - }, - { - "row_type": "cs_dynamicpages-spacer-view", - "each_row_type_fields": ["IBasic.title"], - "row_type_has_featured_add_button": False, - }, - { - "row_type": "cs_dynamicpages-slider-view", - "each_row_type_fields": ["IBasic.title", "IRowWidth.width"], - "row_type_has_featured_add_button": True, - }, - { - "row_type": "cs_dynamicpages-features-view", - "each_row_type_fields": ["IBasic.title", "IRowWidth.width"], - "row_type_has_featured_add_button": True, - }, - { - "row_type": "cs_dynamicpages-accordion-view", - "each_row_type_fields": ["IBasic.title", "IRowWidth.width"], - "row_type_has_featured_add_button": True, - }, - { - "row_type": "cs_dynamicpages-query-columns-view", - "each_row_type_fields": ["IBasic.title", "IRowWidth.width", "ICollection.query", "ICollection.sort_on", "ICollection.sort_order", "ICollection.betweeen", "ICollection.limit", "IRowColumns.columns"], - "row_type_has_featured_add_button": False, - }, - { - "row_type": "cs_dynamicpages-text-view", - "each_row_type_fields": ["IBasic.title", "IRowWidth.width", "IRichTextBehavior-text"], - "row_type_has_featured_add_button": False, - }, - ], - ) - - -class DynamicaPagesControlPanel(RegistryEditForm): - schema = IDynamicaPagesControlPanel - schema_prefix = "cs_dynamicpages.dynamica_pages_control_panel" - label = _("Dynamica Pages Control Panel") - - -DynamicaPagesControlPanelView = layout.wrap_form( - DynamicaPagesControlPanel, ControlPanelFormWrapper -) - - -@adapter(Interface, IBrowserLayer) -class DynamicaPagesControlPanelConfigletPanel(RegistryConfigletPanel): - """Control Panel endpoint""" - - schema = IDynamicaPagesControlPanel - configlet_id = "dynamica_pages_control_panel-controlpanel" - configlet_category_id = "Products" - title = _("Dynamica Pages Control Panel") - group = "" - schema_prefix = "cs_dynamicpages.dynamica_pages_control_panel" diff --git a/src/cs_dynamicpages/dependencies.zcml b/src/cs_dynamicpages/dependencies.zcml index 75ca76a..c231e4c 100644 --- a/src/cs_dynamicpages/dependencies.zcml +++ b/src/cs_dynamicpages/dependencies.zcml @@ -1,5 +1,6 @@ - + + diff --git a/src/cs_dynamicpages/indexers/configure.zcml b/src/cs_dynamicpages/indexers/configure.zcml index ee4ad7c..3a7c52b 100644 --- a/src/cs_dynamicpages/indexers/configure.zcml +++ b/src/cs_dynamicpages/indexers/configure.zcml @@ -3,5 +3,9 @@ + diff --git a/src/cs_dynamicpages/indexers/content_index_extender.py b/src/cs_dynamicpages/indexers/content_index_extender.py new file mode 100644 index 0000000..d967294 --- /dev/null +++ b/src/cs_dynamicpages/indexers/content_index_extender.py @@ -0,0 +1,72 @@ +from plone import api +from plone.app.dexterity import textindexer +from plone.dexterity.interfaces import IDexterityContainer +from zope.component import adapter +from zope.interface import implementer + + +def extract_text_value_to_index(content): + """convert the text field of a content item to plain text""" + text = (content.text and content.text.output) or "" + pt = api.portal.get_tool("portal_transforms") + data = pt.convertTo("text/plain", text, mimetype="text/html") + return data.getData() + + +FIELDS_TO_INDEX = { + # Full field name: function to get the indexed value + "IBasic.title": lambda content: content.Title(), + "IBasic.description": lambda content: content.Description(), + "IRichTextBehavior-text": extract_text_value_to_index, +} + + +@implementer(textindexer.IDynamicTextIndexExtender) +@adapter(IDexterityContainer) +class FolderishItemTextExtender: + def __init__(self, context): + self.context = context + + def __call__(self): + layout = self.context.getLayout() + if layout == "dynamic-view": + return get_available_text_from_dynamic_pages(self.context) + return "" + + +def get_enabled_fields(row_type): + """return the fields that are enabled to be edited in the given + row type + """ + row_type_fields = api.portal.get_registry_record( + "cs_dynamicpages.dynamic_pages_control_panel.row_type_fields" + ) + + for item in row_type_fields: + if item["row_type"] == row_type: + return item["each_row_type_fields"] + + return [] + + +def get_available_text_from_dynamic_pages(context): + """this should return the indexable texts + for a given dynamic page + + it should extract the texts from the row container in the context + """ + value = [] + brains = api.content.find( + portal_type="DynamicPageRow", + review_state="published", + context=context, + ) + for brain in brains: + drr = brain.getObject() + enabled_fields = get_enabled_fields(drr.row_type) + for enabled_field in enabled_fields: + extract_content_function = FIELDS_TO_INDEX.get(enabled_field) + if extract_content_function is not None: + value.append(extract_content_function(drr)) + + return " ".join(value) diff --git a/src/cs_dynamicpages/locales/__main__.py b/src/cs_dynamicpages/locales/__main__.py index a5677b6..cea189c 100644 --- a/src/cs_dynamicpages/locales/__main__.py +++ b/src/cs_dynamicpages/locales/__main__.py @@ -37,7 +37,7 @@ def locale_folder_setup(domain: str): f"--input={locale_path}/{domain}.pot " f"--output={locale_path}/{lang}/LC_MESSAGES/{domain}.po" ) - subprocess.call(cmd, shell=True) # noQA: S602 + subprocess.call(cmd, shell=True) # noqa: S602 def _rebuild(domain: str): @@ -46,7 +46,7 @@ def _rebuild(domain: str): f"--exclude {excludes} " f"--create {domain} {target_path}" ) - subprocess.call(cmd, shell=True) # noQA: S602 + subprocess.call(cmd, shell=True) # noqa: S602 def _sync(domain: str): @@ -54,7 +54,7 @@ def _sync(domain: str): f"{i18ndude} sync --pot {locale_path}/{domain}.pot " f"{locale_path}/*/LC_MESSAGES/{domain}.po" ) - subprocess.call(cmd, shell=True) # noQA: S602 + subprocess.call(cmd, shell=True) # noqa: S602 def main(): diff --git a/src/cs_dynamicpages/locales/cs_dynamicpages.pot b/src/cs_dynamicpages/locales/cs_dynamicpages.pot new file mode 100644 index 0000000..2b0f7ab --- /dev/null +++ b/src/cs_dynamicpages/locales/cs_dynamicpages.pot @@ -0,0 +1,253 @@ +#--- PLEASE EDIT THE LINES BELOW CORRECTLY --- +#SOME DESCRIPTIVE TITLE. +#FIRST AUTHOR , YEAR. +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2025-10-08 08:36+0000\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" +"Language-Code: en\n" +"Language-Name: English\n" +"Preferred-Encodings: utf-8 latin1\n" +"Domain: cs_dynamicpages\n" + +#: cs_dynamicpages/vocabularies/row_columns.py:25 +msgid "1" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:26 +msgid "2" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:27 +msgid "3" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:28 +msgid "4" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:273 +msgid "Add featured" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:303 +msgid "Add row" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:342 +msgid "Are you sure you want to delete this item? This action cannot be undone." +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:55 +msgid "CSS class for the row width" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:345 +msgid "Cancel" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:334 +msgid "Close" +msgstr "" + +#: cs_dynamicpages/behaviors/row_columns.py:21 +msgid "Column count" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:330 +msgid "Confirm Deletion" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:81 +msgid "Delete" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:201 +#: cs_dynamicpages/profiles/default/controlpanel.xml +#: cs_dynamicpages/upgrades/1002/controlpanel.xml +msgid "Dynamic Pages Control Panel" +msgstr "" + +#: cs_dynamicpages/views/configure.zcml:29 +msgid "Dynamic view" +msgstr "" + +#: cs_dynamicpages/profiles/default/types/DynamicPageFolder.xml +msgid "DynamicPageFolder" +msgstr "" + +#: cs_dynamicpages/profiles/default/types/DynamicPageRow.xml +msgid "DynamicPageRow" +msgstr "" + +#: cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml +msgid "DynamicPageRowFeatured" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:67 +msgid "Edit" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:27 +msgid "Edit Mode" +msgstr "" + +#: cs_dynamicpages/behaviors/extra_class.py:22 +msgid "Enter an extra CSS class that will be added to the row" +msgstr "" + +#: cs_dynamicpages/behaviors/link_info.py:28 +msgid "Enter the URL of the link" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:24 +msgid "Enter the fields that will be available when editing this row type. This is useful to hide unused fields." +msgstr "" + +#: cs_dynamicpages/behaviors/link_info.py:22 +msgid "Enter the text that will be linked" +msgstr "" + +#: cs_dynamicpages/behaviors/extra_class.py:21 +msgid "Extra CSS class" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:34 +msgid "Has featured add button?" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:64 +msgid "Here we have all the available views for the rows and their settings" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:173 +msgid "Here you can define the available widths for each row" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:35 +msgid "If selected a 'Add featured' button will be added in the edit interface. This is useful for rows that have content pieces inside them. For example in a slider row, there are slider items. This button will be used to add those items." +msgstr "" + +#: cs_dynamicpages/behaviors/related_image.py:56 +msgid "Image position" +msgstr "" + +#: cs_dynamicpages/vocabularies/image_position.py:25 +msgid "Left" +msgstr "" + +#: cs_dynamicpages/behaviors/link_info.py:27 +msgid "Link URL" +msgstr "" + +#: cs_dynamicpages/behaviors/link_info.py:21 +msgid "Link text" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:241 +msgid "Move actions" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:118 +msgid "Move down" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:101 +msgid "Move up" +msgstr "" + +#: cs_dynamicpages/profiles.zcml:13 +msgid "Package to configure a new cs_dynamicpages site" +msgstr "" + +#: cs_dynamicpages/behaviors/related_image.py:37 +msgid "Related image" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:160 +msgid "Review state: ${state}" +msgstr "" + +#: cs_dynamicpages/vocabularies/image_position.py:26 +msgid "Right" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:54 +msgid "Row Width CSS class" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:48 +msgid "Row Width Label" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:23 +msgid "Row fields" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:17 +msgid "Row type" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:68 +msgid "Row type field" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:63 +msgid "Row type fields" +msgstr "" + +#: cs_dynamicpages/behaviors/row_width.py:19 +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:176 +msgid "Row width" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:172 +msgid "Row widths" +msgstr "" + +#: cs_dynamicpages/behaviors/row_columns.py:22 +msgid "Select how many columns will be shown in this row" +msgstr "" + +#: cs_dynamicpages/behaviors/related_image.py:57 +msgid "Select the position of this image" +msgstr "" + +#: cs_dynamicpages/behaviors/related_image.py:38 +msgid "Select the related image that will be shown in this row" +msgstr "" + +#: cs_dynamicpages/behaviors/row_width.py:20 +msgid "Select the width that this row will have" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:226 +msgid "State" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:64 +msgid "Template: ${template_id}" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:49 +msgid "This is the label corresponding to this width" +msgstr "" + +#: cs_dynamicpages/profiles.zcml:21 +msgid "Uninstall cs_dynamicpages setup." +msgstr "" + +#: cs_dynamicpages/profiles.zcml:13 +msgid "cs_dynamicpages: Install" +msgstr "" + +#: cs_dynamicpages/profiles.zcml:21 +msgid "cs_dynamicpages: Uninstall" +msgstr "" diff --git a/src/cs_dynamicpages/locales/en/LC_MESSAGES/cs_dynamicpages.po b/src/cs_dynamicpages/locales/en/LC_MESSAGES/cs_dynamicpages.po index e915fd2..ad69599 100644 --- a/src/cs_dynamicpages/locales/en/LC_MESSAGES/cs_dynamicpages.po +++ b/src/cs_dynamicpages/locales/en/LC_MESSAGES/cs_dynamicpages.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2022-05-25 17:12+0000\n" +"POT-Creation-Date: 2025-10-08 08:36+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -13,3 +13,238 @@ msgstr "" "Language-Name: English\n" "Preferred-Encodings: utf-8 latin1\n" "Domain: cs_dynamicpages\n" + +#: cs_dynamicpages/vocabularies/row_columns.py:25 +msgid "1" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:26 +msgid "2" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:27 +msgid "3" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:28 +msgid "4" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:273 +msgid "Add featured" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:303 +msgid "Add row" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:342 +msgid "Are you sure you want to delete this item? This action cannot be undone." +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:55 +msgid "CSS class for the row width" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:345 +msgid "Cancel" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:334 +msgid "Close" +msgstr "" + +#: cs_dynamicpages/behaviors/row_columns.py:21 +msgid "Column count" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:330 +msgid "Confirm Deletion" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:81 +msgid "Delete" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:201 +#: cs_dynamicpages/profiles/default/controlpanel.xml +#: cs_dynamicpages/upgrades/1002/controlpanel.xml +msgid "Dynamic Pages Control Panel" +msgstr "" + +#: cs_dynamicpages/views/configure.zcml:29 +msgid "Dynamic view" +msgstr "" + +#: cs_dynamicpages/profiles/default/types/DynamicPageFolder.xml +msgid "DynamicPageFolder" +msgstr "" + +#: cs_dynamicpages/profiles/default/types/DynamicPageRow.xml +msgid "DynamicPageRow" +msgstr "" + +#: cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml +msgid "DynamicPageRowFeatured" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:67 +msgid "Edit" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:27 +msgid "Edit Mode" +msgstr "" + +#: cs_dynamicpages/behaviors/extra_class.py:22 +msgid "Enter an extra CSS class that will be added to the row" +msgstr "" + +#: cs_dynamicpages/behaviors/link_info.py:28 +msgid "Enter the URL of the link" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:24 +msgid "Enter the fields that will be available when editing this row type. This is useful to hide unused fields." +msgstr "" + +#: cs_dynamicpages/behaviors/link_info.py:22 +msgid "Enter the text that will be linked" +msgstr "" + +#: cs_dynamicpages/behaviors/extra_class.py:21 +msgid "Extra CSS class" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:34 +msgid "Has featured add button?" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:64 +msgid "Here we have all the available views for the rows and their settings" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:173 +msgid "Here you can define the available widths for each row" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:35 +msgid "If selected a 'Add featured' button will be added in the edit interface. This is useful for rows that have content pieces inside them. For example in a slider row, there are slider items. This button will be used to add those items." +msgstr "" + +#: cs_dynamicpages/behaviors/related_image.py:56 +msgid "Image position" +msgstr "" + +#: cs_dynamicpages/vocabularies/image_position.py:25 +msgid "Left" +msgstr "" + +#: cs_dynamicpages/behaviors/link_info.py:27 +msgid "Link URL" +msgstr "" + +#: cs_dynamicpages/behaviors/link_info.py:21 +msgid "Link text" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:241 +msgid "Move actions" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:118 +msgid "Move down" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:101 +msgid "Move up" +msgstr "" + +#: cs_dynamicpages/profiles.zcml:13 +msgid "Package to configure a new cs_dynamicpages site" +msgstr "" + +#: cs_dynamicpages/behaviors/related_image.py:37 +msgid "Related image" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:160 +msgid "Review state: ${state}" +msgstr "" + +#: cs_dynamicpages/vocabularies/image_position.py:26 +msgid "Right" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:54 +msgid "Row Width CSS class" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:48 +msgid "Row Width Label" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:23 +msgid "Row fields" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:17 +msgid "Row type" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:68 +msgid "Row type field" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:63 +msgid "Row type fields" +msgstr "" + +#: cs_dynamicpages/behaviors/row_width.py:19 +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:176 +msgid "Row width" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:172 +msgid "Row widths" +msgstr "" + +#: cs_dynamicpages/behaviors/row_columns.py:22 +msgid "Select how many columns will be shown in this row" +msgstr "" + +#: cs_dynamicpages/behaviors/related_image.py:57 +msgid "Select the position of this image" +msgstr "" + +#: cs_dynamicpages/behaviors/related_image.py:38 +msgid "Select the related image that will be shown in this row" +msgstr "" + +#: cs_dynamicpages/behaviors/row_width.py:20 +msgid "Select the width that this row will have" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:226 +msgid "State" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:64 +msgid "Template: ${template_id}" +msgstr "" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:49 +msgid "This is the label corresponding to this width" +msgstr "" + +#: cs_dynamicpages/profiles.zcml:21 +msgid "Uninstall cs_dynamicpages setup." +msgstr "" + +#: cs_dynamicpages/profiles.zcml:13 +msgid "cs_dynamicpages: Install" +msgstr "" + +#: cs_dynamicpages/profiles.zcml:21 +msgid "cs_dynamicpages: Uninstall" +msgstr "" diff --git a/src/cs_dynamicpages/locales/es/LC_MESSAGES/cs_dynamicpages.po b/src/cs_dynamicpages/locales/es/LC_MESSAGES/cs_dynamicpages.po new file mode 100644 index 0000000..7c912d2 --- /dev/null +++ b/src/cs_dynamicpages/locales/es/LC_MESSAGES/cs_dynamicpages.po @@ -0,0 +1,252 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-10-08 08:36+0000\n" +"PO-Revision-Date: 2025-10-08 10:39+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language-Code: en\n" +"Language-Name: English\n" +"Preferred-Encodings: utf-8 latin1\n" +"Domain: cs_dynamicpages\n" +"X-Generator: Poedit 3.4.2\n" + +#: cs_dynamicpages/vocabularies/row_columns.py:25 +msgid "1" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:26 +msgid "2" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:27 +msgid "3" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:28 +msgid "4" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:273 +msgid "Add featured" +msgstr "Añadir elemento destacado" + +#: cs_dynamicpages/views/dynamic_view.pt:303 +msgid "Add row" +msgstr "Añadir fila" + +#: cs_dynamicpages/views/dynamic_view.pt:342 +msgid "Are you sure you want to delete this item? This action cannot be undone." +msgstr "¿Estás seguro de que quieres eliminar este elemento? Esta acción no se puede deshacer." + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:55 +msgid "CSS class for the row width" +msgstr "Clase CSS para el ancho de la fila" + +#: cs_dynamicpages/views/dynamic_view.pt:345 +msgid "Cancel" +msgstr "Cancelar" + +#: cs_dynamicpages/views/dynamic_view.pt:334 +msgid "Close" +msgstr "Cerrar" + +#: cs_dynamicpages/behaviors/row_columns.py:21 +msgid "Column count" +msgstr "Número de columnas" + +#: cs_dynamicpages/views/dynamic_view.pt:330 +msgid "Confirm Deletion" +msgstr "Confirmar eliminado" + +#: cs_dynamicpages/views/dynamic_view.pt:81 +msgid "Delete" +msgstr "Eliminar" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:201 +#: cs_dynamicpages/profiles/default/controlpanel.xml +#: cs_dynamicpages/upgrades/1002/controlpanel.xml +msgid "Dynamic Pages Control Panel" +msgstr "Panel de control de páginas dinámicas" + +#: cs_dynamicpages/views/configure.zcml:29 +msgid "Dynamic view" +msgstr "Vista dinámica" + +#: cs_dynamicpages/profiles/default/types/DynamicPageFolder.xml +msgid "DynamicPageFolder" +msgstr "Carpeta de página dinámica" + +#: cs_dynamicpages/profiles/default/types/DynamicPageRow.xml +msgid "DynamicPageRow" +msgstr "Fila de página dinámica" + +#: cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml +msgid "DynamicPageRowFeatured" +msgstr "Destacado de fila de página dinámica" + +#: cs_dynamicpages/views/dynamic_view.pt:67 +msgid "Edit" +msgstr "Editar" + +#: cs_dynamicpages/views/dynamic_view.pt:27 +msgid "Edit Mode" +msgstr "Modo edición" + +#: cs_dynamicpages/behaviors/extra_class.py:22 +msgid "Enter an extra CSS class that will be added to the row" +msgstr "Introduzca una clase CSS extra que se añadirá a la fila" + +#: cs_dynamicpages/behaviors/link_info.py:28 +msgid "Enter the URL of the link" +msgstr "Introduzca la URL del enlace" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:24 +msgid "Enter the fields that will be available when editing this row type. This is useful to hide unused fields." +msgstr "Introduzca los campos que se mostrarán al editar este tipo de fila. Esto es útil para esconder campos innecesarios." + +#: cs_dynamicpages/behaviors/link_info.py:22 +msgid "Enter the text that will be linked" +msgstr "Introduzca el texto que será enlazado" + +#: cs_dynamicpages/behaviors/extra_class.py:21 +msgid "Extra CSS class" +msgstr "Clase CSS extra" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:34 +msgid "Has featured add button?" +msgstr "¿Tiene el botón para añadir elementos destacados?" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:64 +msgid "Here we have all the available views for the rows and their settings" +msgstr "Aquí tenemos todas las vistas disponibles para las filas y su configuración" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:173 +msgid "Here you can define the available widths for each row" +msgstr "Aquí puede definir los anchos disponibles para las filas" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:35 +msgid "If selected a 'Add featured' button will be added in the edit interface. This is useful for rows that have content pieces inside them. For example in a slider row, there are slider items. This button will be used to add those items." +msgstr "Si está seleccionado se mostrará un botón \"Añadir destacado\" en la interfaz de edición. Esto es útil para filas que tiene elementos de contenido dentro de ellas. Por ejemplo en un slider de imágenes, cada una de las imágenes será un \"destacado\". Este botón se utiliza para añadir este tipo de elementos." + +#: cs_dynamicpages/behaviors/related_image.py:56 +msgid "Image position" +msgstr "Posición de la imagen" + +#: cs_dynamicpages/vocabularies/image_position.py:25 +msgid "Left" +msgstr "Izquierda" + +#: cs_dynamicpages/behaviors/link_info.py:27 +msgid "Link URL" +msgstr "URL del enlace" + +#: cs_dynamicpages/behaviors/link_info.py:21 +msgid "Link text" +msgstr "Texto del enlace" + +#: cs_dynamicpages/views/dynamic_view.pt:241 +msgid "Move actions" +msgstr "Acciones para mover elementos" + +#: cs_dynamicpages/views/dynamic_view.pt:118 +msgid "Move down" +msgstr "Bajar" + +#: cs_dynamicpages/views/dynamic_view.pt:101 +msgid "Move up" +msgstr "Subir" + +#: cs_dynamicpages/profiles.zcml:13 +msgid "Package to configure a new cs_dynamicpages site" +msgstr "Paquete para configurar cs_dynamicpages" + +#: cs_dynamicpages/behaviors/related_image.py:37 +msgid "Related image" +msgstr "Imagen relacionada" + +#: cs_dynamicpages/views/dynamic_view.pt:160 +msgid "Review state: ${state}" +msgstr "Estado: ${state}" + +#: cs_dynamicpages/vocabularies/image_position.py:26 +msgid "Right" +msgstr "Derecha" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:54 +msgid "Row Width CSS class" +msgstr "Clase CSS del ancho de la fila" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:48 +msgid "Row Width Label" +msgstr "Etiqueta del ancho de la fila" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:23 +msgid "Row fields" +msgstr "Campos de la fila" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:17 +msgid "Row type" +msgstr "Tipo de fila" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:68 +msgid "Row type field" +msgstr "Campo del tipo de fila" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:63 +msgid "Row type fields" +msgstr "Campos del tipo de fila" + +#: cs_dynamicpages/behaviors/row_width.py:19 +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:176 +msgid "Row width" +msgstr "Ancho de la fila" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:172 +msgid "Row widths" +msgstr "Anchos de la fila" + +#: cs_dynamicpages/behaviors/row_columns.py:22 +msgid "Select how many columns will be shown in this row" +msgstr "Seleccione cuántas columnas se mostrarán en esta fila" + +#: cs_dynamicpages/behaviors/related_image.py:57 +msgid "Select the position of this image" +msgstr "Seleccione la posición de esta imagen" + +#: cs_dynamicpages/behaviors/related_image.py:38 +msgid "Select the related image that will be shown in this row" +msgstr "Seleccione la imagen relaconada que se mostrará en esta fila" + +#: cs_dynamicpages/behaviors/row_width.py:20 +msgid "Select the width that this row will have" +msgstr "Seleccione el ancho de esta fila" + +#: cs_dynamicpages/views/dynamic_view.pt:226 +msgid "State" +msgstr "Estado" + +#: cs_dynamicpages/views/dynamic_view.pt:64 +msgid "Template: ${template_id}" +msgstr "Plantilla: ${template_id}" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:49 +msgid "This is the label corresponding to this width" +msgstr "Etiqueta correspondiente a este ancho" + +#: cs_dynamicpages/profiles.zcml:21 +msgid "Uninstall cs_dynamicpages setup." +msgstr "Desinstalar cs_dynamicpages." + +#: cs_dynamicpages/profiles.zcml:13 +msgid "cs_dynamicpages: Install" +msgstr "cs_dynamicpages: instalar" + +#: cs_dynamicpages/profiles.zcml:21 +msgid "cs_dynamicpages: Uninstall" +msgstr "cs_dynamicpages: desinstalar" diff --git a/src/cs_dynamicpages/locales/eu/LC_MESSAGES/cs_dynamicpages.po b/src/cs_dynamicpages/locales/eu/LC_MESSAGES/cs_dynamicpages.po new file mode 100644 index 0000000..7083235 --- /dev/null +++ b/src/cs_dynamicpages/locales/eu/LC_MESSAGES/cs_dynamicpages.po @@ -0,0 +1,252 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: 2025-10-08 08:36+0000\n" +"PO-Revision-Date: 2025-10-08 10:40+0200\n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language-Code: en\n" +"Language-Name: English\n" +"Preferred-Encodings: utf-8 latin1\n" +"Domain: cs_dynamicpages\n" +"X-Generator: Poedit 3.4.2\n" + +#: cs_dynamicpages/vocabularies/row_columns.py:25 +msgid "1" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:26 +msgid "2" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:27 +msgid "3" +msgstr "" + +#: cs_dynamicpages/vocabularies/row_columns.py:28 +msgid "4" +msgstr "" + +#: cs_dynamicpages/views/dynamic_view.pt:273 +msgid "Add featured" +msgstr "Gehitu elementu destakatua" + +#: cs_dynamicpages/views/dynamic_view.pt:303 +msgid "Add row" +msgstr "Gehitu lerroa" + +#: cs_dynamicpages/views/dynamic_view.pt:342 +msgid "Are you sure you want to delete this item? This action cannot be undone." +msgstr "Ziur zaude elementu hau ezabatu nahi duzula? Ekintza hau ezin da desegin." + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:55 +msgid "CSS class for the row width" +msgstr "Lerroaren zabaleraren CSS klasea" + +#: cs_dynamicpages/views/dynamic_view.pt:345 +msgid "Cancel" +msgstr "Utzi" + +#: cs_dynamicpages/views/dynamic_view.pt:334 +msgid "Close" +msgstr "Itxi" + +#: cs_dynamicpages/behaviors/row_columns.py:21 +msgid "Column count" +msgstr "Zutabe kopurua" + +#: cs_dynamicpages/views/dynamic_view.pt:330 +msgid "Confirm Deletion" +msgstr "Baieztatu ezabatzea" + +#: cs_dynamicpages/views/dynamic_view.pt:81 +msgid "Delete" +msgstr "Ezabatu" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:201 +#: cs_dynamicpages/profiles/default/controlpanel.xml +#: cs_dynamicpages/upgrades/1002/controlpanel.xml +msgid "Dynamic Pages Control Panel" +msgstr "Orrialde dinamikoen kontrol panela" + +#: cs_dynamicpages/views/configure.zcml:29 +msgid "Dynamic view" +msgstr "Bista dinamikoa" + +#: cs_dynamicpages/profiles/default/types/DynamicPageFolder.xml +msgid "DynamicPageFolder" +msgstr "Orri dinamikoen karpeta" + +#: cs_dynamicpages/profiles/default/types/DynamicPageRow.xml +msgid "DynamicPageRow" +msgstr "Orri dinamikoen lerroa" + +#: cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml +msgid "DynamicPageRowFeatured" +msgstr "Orri dinamikoen lerroetako destakatua" + +#: cs_dynamicpages/views/dynamic_view.pt:67 +msgid "Edit" +msgstr "Editatu" + +#: cs_dynamicpages/views/dynamic_view.pt:27 +msgid "Edit Mode" +msgstr "Edizio modua" + +#: cs_dynamicpages/behaviors/extra_class.py:22 +msgid "Enter an extra CSS class that will be added to the row" +msgstr "Idatzi lerroari gehituko zaion CSS klase gehigarria" + +#: cs_dynamicpages/behaviors/link_info.py:28 +msgid "Enter the URL of the link" +msgstr "Idatzi estekaren URLa" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:24 +msgid "Enter the fields that will be available when editing this row type. This is useful to hide unused fields." +msgstr "Idatzi lerro-mota hau editatzean agertuko diren eremuen izenak. Behar ez diren eremuak ezkutatzeko balio du honek." + +#: cs_dynamicpages/behaviors/link_info.py:22 +msgid "Enter the text that will be linked" +msgstr "Idatzi esteka izango duen testua" + +#: cs_dynamicpages/behaviors/extra_class.py:21 +msgid "Extra CSS class" +msgstr "CSS klase gehigarria" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:34 +msgid "Has featured add button?" +msgstr "Elementu destakatua gehitzeko botoia du?" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:64 +msgid "Here we have all the available views for the rows and their settings" +msgstr "Hemen lerro guztien bistak eta beren ezarpenak dituzu" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:173 +msgid "Here you can define the available widths for each row" +msgstr "Hemen lerro bakoitzaren zabalera posibleak gehitu ditzakezu" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:35 +msgid "If selected a 'Add featured' button will be added in the edit interface. This is useful for rows that have content pieces inside them. For example in a slider row, there are slider items. This button will be used to add those items." +msgstr "Aukeratuta badago, edizio interfazean \"Gehitu elementu destakatua\" botoia agertuko da. Eduki elementuak dituzten lerroentzat da hau erabilgarria. Adibidez, karrusel bat adierazten duen lerro baten, elementu destakatua karruseleko elementuetako bakoitza izango da. Botoi hau elementu horiek gehitzeko erabiliko da." + +#: cs_dynamicpages/behaviors/related_image.py:56 +msgid "Image position" +msgstr "Irudiaren posizioa" + +#: cs_dynamicpages/vocabularies/image_position.py:25 +msgid "Left" +msgstr "Ezkerrean" + +#: cs_dynamicpages/behaviors/link_info.py:27 +msgid "Link URL" +msgstr "Estekaren URLa" + +#: cs_dynamicpages/behaviors/link_info.py:21 +msgid "Link text" +msgstr "Estekaren testua" + +#: cs_dynamicpages/views/dynamic_view.pt:241 +msgid "Move actions" +msgstr "Elementuak mugitzeko akzioak" + +#: cs_dynamicpages/views/dynamic_view.pt:118 +msgid "Move down" +msgstr "Mugitu behera" + +#: cs_dynamicpages/views/dynamic_view.pt:101 +msgid "Move up" +msgstr "Mugitu gora" + +#: cs_dynamicpages/profiles.zcml:13 +msgid "Package to configure a new cs_dynamicpages site" +msgstr "cs_dynamicpages konfiguratzeko paketea" + +#: cs_dynamicpages/behaviors/related_image.py:37 +msgid "Related image" +msgstr "Irudi erlazionatua" + +#: cs_dynamicpages/views/dynamic_view.pt:160 +msgid "Review state: ${state}" +msgstr "Egoera: ${state}" + +#: cs_dynamicpages/vocabularies/image_position.py:26 +msgid "Right" +msgstr "Eskuma" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:54 +msgid "Row Width CSS class" +msgstr "Lerroaren zabalerara CSS klasea" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:48 +msgid "Row Width Label" +msgstr "Lerro zabaleraren etiketa" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:23 +msgid "Row fields" +msgstr "Lerroaren eremuak" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:17 +msgid "Row type" +msgstr "Lerro-mota" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:68 +msgid "Row type field" +msgstr "Lerro motaren eremua" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:63 +msgid "Row type fields" +msgstr "Lerro motaren eremuak" + +#: cs_dynamicpages/behaviors/row_width.py:19 +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:176 +msgid "Row width" +msgstr "Lerroaren zabalera" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:172 +msgid "Row widths" +msgstr "Lerroaren zabalerak" + +#: cs_dynamicpages/behaviors/row_columns.py:22 +msgid "Select how many columns will be shown in this row" +msgstr "Aukeratu lerro honek zenbat zutabe izango dituen" + +#: cs_dynamicpages/behaviors/related_image.py:57 +msgid "Select the position of this image" +msgstr "Aukeratu irudiaren posizioa" + +#: cs_dynamicpages/behaviors/related_image.py:38 +msgid "Select the related image that will be shown in this row" +msgstr "Aukeratu lerro honetan agertuko den erlazionatutako irudia" + +#: cs_dynamicpages/behaviors/row_width.py:20 +msgid "Select the width that this row will have" +msgstr "Aukeratu lerro honek izango duen zabalera" + +#: cs_dynamicpages/views/dynamic_view.pt:226 +msgid "State" +msgstr "Egoera" + +#: cs_dynamicpages/views/dynamic_view.pt:64 +msgid "Template: ${template_id}" +msgstr "Txantiloia: ${template_id}" + +#: cs_dynamicpages/controlpanels/dynamic_pages_control_panel/controlpanel.py:49 +msgid "This is the label corresponding to this width" +msgstr "Zabalera honi dagokion etiketa da hau" + +#: cs_dynamicpages/profiles.zcml:21 +msgid "Uninstall cs_dynamicpages setup." +msgstr "cs_dynamicpages desinstalatu" + +#: cs_dynamicpages/profiles.zcml:13 +msgid "cs_dynamicpages: Install" +msgstr "cs_dynamicpages: instalatu" + +#: cs_dynamicpages/profiles.zcml:21 +msgid "cs_dynamicpages: Uninstall" +msgstr "cs_dynamicpages: desinstalatu" diff --git a/src/cs_dynamicpages/permissions.zcml b/src/cs_dynamicpages/permissions.zcml index 6773a76..cf82d48 100644 --- a/src/cs_dynamicpages/permissions.zcml +++ b/src/cs_dynamicpages/permissions.zcml @@ -17,7 +17,7 @@ title="cs_dynamicpages: Add DynamicPageRow" /> - diff --git a/src/cs_dynamicpages/profiles/default/controlpanel.xml b/src/cs_dynamicpages/profiles/default/controlpanel.xml index 0f06f9c..24436e4 100644 --- a/src/cs_dynamicpages/profiles/default/controlpanel.xml +++ b/src/cs_dynamicpages/profiles/default/controlpanel.xml @@ -6,13 +6,13 @@ - diff --git a/src/cs_dynamicpages/profiles/default/metadata.xml b/src/cs_dynamicpages/profiles/default/metadata.xml index ec58cba..30cd99d 100644 --- a/src/cs_dynamicpages/profiles/default/metadata.xml +++ b/src/cs_dynamicpages/profiles/default/metadata.xml @@ -1,6 +1,8 @@ - 1000 + 1004 - profile-plone.app.dexterity:default + profile-plone.app.dexterity:default + profile-collective.z3cform.datagridfield:default + diff --git a/src/cs_dynamicpages/profiles/default/registry/dynamic_bundle.xml b/src/cs_dynamicpages/profiles/default/registry/dynamic_bundle.xml index 2419b1c..908eb65 100644 --- a/src/cs_dynamicpages/profiles/default/registry/dynamic_bundle.xml +++ b/src/cs_dynamicpages/profiles/default/registry/dynamic_bundle.xml @@ -1,50 +1,48 @@ - + - - - - True - ++plone++cs_dynamicpages.edit/edit_dynamicpagerow.js - ++plone++cs_dynamicpages.edit/dynamicpageview.css - plone - True - False - + True + ++plone++cs_dynamicpages.edit/edit_dynamicpagerow.js + ++plone++cs_dynamicpages.edit/dynamicpageview.css + plone + True + False + - True - ++plone++cs_dynamicpages.edit/delete-row.js - plone - True - False - + True + ++plone++cs_dynamicpages.edit/delete-row.js + plone + True + False + - True - ++plone++cs_dynamicpages.edit/reorder-rows.js - plone - True - False - + True + ++plone++cs_dynamicpages.edit/reorder-rows.js + plone + True + False + - True - ++plone++cs_dynamicpages.edit/editmode-toggle.js - plone - True - False - + True + ++plone++cs_dynamicpages.edit/editmode-toggle.js + plone + True + False + diff --git a/src/cs_dynamicpages/profiles/default/registry/dynamic_pages_control_panel.xml b/src/cs_dynamicpages/profiles/default/registry/dynamic_pages_control_panel.xml new file mode 100644 index 0000000..33d3583 --- /dev/null +++ b/src/cs_dynamicpages/profiles/default/registry/dynamic_pages_control_panel.xml @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/src/cs_dynamicpages/profiles/default/types/DynamicPageFolder.xml b/src/cs_dynamicpages/profiles/default/types/DynamicPageFolder.xml index 719aeeb..1c14f84 100644 --- a/src/cs_dynamicpages/profiles/default/types/DynamicPageFolder.xml +++ b/src/cs_dynamicpages/profiles/default/types/DynamicPageFolder.xml @@ -40,7 +40,7 @@ --> - + diff --git a/src/cs_dynamicpages/profiles/default/types/DynamicPageRow.xml b/src/cs_dynamicpages/profiles/default/types/DynamicPageRow.xml index e93586b..b1075ca 100644 --- a/src/cs_dynamicpages/profiles/default/types/DynamicPageRow.xml +++ b/src/cs_dynamicpages/profiles/default/types/DynamicPageRow.xml @@ -40,7 +40,7 @@ --> - + @@ -51,11 +51,12 @@ + - + diff --git a/src/cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml b/src/cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml index 06e8789..6b16a69 100644 --- a/src/cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml +++ b/src/cs_dynamicpages/profiles/default/types/DynamicPageRowFeatured.xml @@ -36,7 +36,7 @@ --> - + @@ -47,7 +47,7 @@ - + diff --git a/src/cs_dynamicpages/profiles/default/types/Folder.xml b/src/cs_dynamicpages/profiles/default/types/Folder.xml index 51ad272..a04cdaa 100644 --- a/src/cs_dynamicpages/profiles/default/types/Folder.xml +++ b/src/cs_dynamicpages/profiles/default/types/Folder.xml @@ -2,7 +2,6 @@ + + + + + + diff --git a/src/cs_dynamicpages/profiles/default/types/Plone_Site.xml b/src/cs_dynamicpages/profiles/default/types/Plone_Site.xml new file mode 100644 index 0000000..232d8bc --- /dev/null +++ b/src/cs_dynamicpages/profiles/default/types/Plone_Site.xml @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/cs_dynamicpages/profiles/uninstall/controlpanel.xml b/src/cs_dynamicpages/profiles/uninstall/controlpanel.xml new file mode 100644 index 0000000..2bf9d88 --- /dev/null +++ b/src/cs_dynamicpages/profiles/uninstall/controlpanel.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/src/cs_dynamicpages/profiles/uninstall/registry/dynamic_bundle.xml b/src/cs_dynamicpages/profiles/uninstall/registry/dynamic_bundle.xml new file mode 100644 index 0000000..dc49d67 --- /dev/null +++ b/src/cs_dynamicpages/profiles/uninstall/registry/dynamic_bundle.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/profiles/uninstall/registry/dynamica_pages_control_panel.xml b/src/cs_dynamicpages/profiles/uninstall/registry/dynamica_pages_control_panel.xml new file mode 100644 index 0000000..59735da --- /dev/null +++ b/src/cs_dynamicpages/profiles/uninstall/registry/dynamica_pages_control_panel.xml @@ -0,0 +1,14 @@ + + + + + + + + + diff --git a/src/cs_dynamicpages/profiles/uninstall/types.xml b/src/cs_dynamicpages/profiles/uninstall/types.xml new file mode 100644 index 0000000..a325b1b --- /dev/null +++ b/src/cs_dynamicpages/profiles/uninstall/types.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/src/cs_dynamicpages/setuphandlers/__init__.py b/src/cs_dynamicpages/setuphandlers/__init__.py index 57c7f73..5953303 100644 --- a/src/cs_dynamicpages/setuphandlers/__init__.py +++ b/src/cs_dynamicpages/setuphandlers/__init__.py @@ -9,3 +9,7 @@ def getNonInstallableProfiles(self): return [ "cs_dynamicpages:uninstall", ] + + def getNonInstallableProducts(self): + """Hide the upgrades package from site-creation and quickinstaller.""" + return ["cs_dynamicpages.upgrades"] diff --git a/src/cs_dynamicpages/browser/overrides/.gitkeep b/src/cs_dynamicpages/subscribers/__init__.py similarity index 100% rename from src/cs_dynamicpages/browser/overrides/.gitkeep rename to src/cs_dynamicpages/subscribers/__init__.py diff --git a/src/cs_dynamicpages/subscribers/configure.zcml b/src/cs_dynamicpages/subscribers/configure.zcml new file mode 100644 index 0000000..3a1e11d --- /dev/null +++ b/src/cs_dynamicpages/subscribers/configure.zcml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/subscribers/index_contents_in_parents.py b/src/cs_dynamicpages/subscribers/index_contents_in_parents.py new file mode 100644 index 0000000..8889038 --- /dev/null +++ b/src/cs_dynamicpages/subscribers/index_contents_in_parents.py @@ -0,0 +1,15 @@ +from Acquisition import aq_parent +from cs_dynamicpages import logger + + +def handler(obj, event): + """When modifying a DynamicPageRow, we need to index the contents of the + item where this row is shown. + To do so we go up in the tree until we reach the content and force + the reindex of it. + """ + dynamic_page_folder = aq_parent(obj) + if dynamic_page_folder.portal_type == "DynamicPageFolder": + content = aq_parent(dynamic_page_folder) + content.reindexObject() + logger.info("Reindex item: %s", "/".join(content.getPhysicalPath())) diff --git a/src/cs_dynamicpages/tests/test_behavior_row_columns.py b/src/cs_dynamicpages/tests/test_behavior_row_columns.py index cfc4c29..4e56339 100644 --- a/src/cs_dynamicpages/tests/test_behavior_row_columns.py +++ b/src/cs_dynamicpages/tests/test_behavior_row_columns.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- from cs_dynamicpages.behaviors.row_columns import IRowColumnsMarker -from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING # noqa +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from plone.behavior.interfaces import IBehavior @@ -10,16 +9,15 @@ class RowColumnsIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): """Custom shared utility setup for tests.""" - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) def test_behavior_row_columns(self): - behavior = getUtility(IBehavior, 'cs_dynamicpages.row_columns') + behavior = getUtility(IBehavior, "cs_dynamicpages.row_columns") self.assertEqual( behavior.marker, IRowColumnsMarker, diff --git a/src/cs_dynamicpages/tests/test_behavior_row_width.py b/src/cs_dynamicpages/tests/test_behavior_row_width.py index d8434b5..dc3c9c6 100644 --- a/src/cs_dynamicpages/tests/test_behavior_row_width.py +++ b/src/cs_dynamicpages/tests/test_behavior_row_width.py @@ -1,6 +1,5 @@ -# -*- coding: utf-8 -*- from cs_dynamicpages.behaviors.row_width import IRowWidthMarker -from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING # noqa +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from plone.behavior.interfaces import IBehavior @@ -10,16 +9,15 @@ class RowWidthIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): """Custom shared utility setup for tests.""" - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) def test_behavior_row_width(self): - behavior = getUtility(IBehavior, 'cs_dynamicpages.row_width') + behavior = getUtility(IBehavior, "cs_dynamicpages.row_width") self.assertEqual( behavior.marker, IRowWidthMarker, diff --git a/src/cs_dynamicpages/tests/test_subscriber_index_contents_in_parents.py b/src/cs_dynamicpages/tests/test_subscriber_index_contents_in_parents.py new file mode 100644 index 0000000..a2772c8 --- /dev/null +++ b/src/cs_dynamicpages/tests/test_subscriber_index_contents_in_parents.py @@ -0,0 +1,22 @@ +from cs_dynamicpages.testing import CS_DYNAMICPAGES_FUNCTIONAL_TESTING +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID + +import unittest + + +class SubscriberIntegrationTest(unittest.TestCase): + layer = CS_DYNAMICPAGES_INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + +class SubscriberFunctionalTest(unittest.TestCase): + layer = CS_DYNAMICPAGES_FUNCTIONAL_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) diff --git a/src/cs_dynamicpages/tests/test_upgrade_step_1001.py b/src/cs_dynamicpages/tests/test_upgrade_step_1001.py new file mode 100644 index 0000000..f3a1881 --- /dev/null +++ b/src/cs_dynamicpages/tests/test_upgrade_step_1001.py @@ -0,0 +1,27 @@ +# from cs_dynamicpages.testing import CS_DYNAMICPAGES_FUNCTIONAL_TESTING +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID + +import unittest + + +class UpgradeStepIntegrationTest(unittest.TestCase): + layer = CS_DYNAMICPAGES_INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + def test_upgrade_step(self): + # dummy, add tests here + self.assertTrue(True) + + +# class UpgradeStepFunctionalTest(unittest.TestCase): +# +# layer = CS_DYNAMICPAGES_FUNCTIONAL_TESTING +# +# def setUp(self): +# self.portal = self.layer['portal'] +# setRoles(self.portal, TEST_USER_ID, ['Manager']) diff --git a/src/cs_dynamicpages/tests/test_upgrade_step_1002.py b/src/cs_dynamicpages/tests/test_upgrade_step_1002.py new file mode 100644 index 0000000..f3a1881 --- /dev/null +++ b/src/cs_dynamicpages/tests/test_upgrade_step_1002.py @@ -0,0 +1,27 @@ +# from cs_dynamicpages.testing import CS_DYNAMICPAGES_FUNCTIONAL_TESTING +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID + +import unittest + + +class UpgradeStepIntegrationTest(unittest.TestCase): + layer = CS_DYNAMICPAGES_INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + def test_upgrade_step(self): + # dummy, add tests here + self.assertTrue(True) + + +# class UpgradeStepFunctionalTest(unittest.TestCase): +# +# layer = CS_DYNAMICPAGES_FUNCTIONAL_TESTING +# +# def setUp(self): +# self.portal = self.layer['portal'] +# setRoles(self.portal, TEST_USER_ID, ['Manager']) diff --git a/src/cs_dynamicpages/tests/test_upgrade_step_1003.py b/src/cs_dynamicpages/tests/test_upgrade_step_1003.py new file mode 100644 index 0000000..f3a1881 --- /dev/null +++ b/src/cs_dynamicpages/tests/test_upgrade_step_1003.py @@ -0,0 +1,27 @@ +# from cs_dynamicpages.testing import CS_DYNAMICPAGES_FUNCTIONAL_TESTING +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID + +import unittest + + +class UpgradeStepIntegrationTest(unittest.TestCase): + layer = CS_DYNAMICPAGES_INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + def test_upgrade_step(self): + # dummy, add tests here + self.assertTrue(True) + + +# class UpgradeStepFunctionalTest(unittest.TestCase): +# +# layer = CS_DYNAMICPAGES_FUNCTIONAL_TESTING +# +# def setUp(self): +# self.portal = self.layer['portal'] +# setRoles(self.portal, TEST_USER_ID, ['Manager']) diff --git a/src/cs_dynamicpages/tests/test_upgrade_step_1004.py b/src/cs_dynamicpages/tests/test_upgrade_step_1004.py new file mode 100644 index 0000000..f3a1881 --- /dev/null +++ b/src/cs_dynamicpages/tests/test_upgrade_step_1004.py @@ -0,0 +1,27 @@ +# from cs_dynamicpages.testing import CS_DYNAMICPAGES_FUNCTIONAL_TESTING +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING +from plone.app.testing import setRoles +from plone.app.testing import TEST_USER_ID + +import unittest + + +class UpgradeStepIntegrationTest(unittest.TestCase): + layer = CS_DYNAMICPAGES_INTEGRATION_TESTING + + def setUp(self): + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + + def test_upgrade_step(self): + # dummy, add tests here + self.assertTrue(True) + + +# class UpgradeStepFunctionalTest(unittest.TestCase): +# +# layer = CS_DYNAMICPAGES_FUNCTIONAL_TESTING +# +# def setUp(self): +# self.portal = self.layer['portal'] +# setRoles(self.portal, TEST_USER_ID, ['Manager']) diff --git a/src/cs_dynamicpages/tests/test_view_dynamic_page_folder_view.py b/src/cs_dynamicpages/tests/test_view_dynamic_page_folder_view.py index c00c836..caf7d16 100644 --- a/src/cs_dynamicpages/tests/test_view_dynamic_page_folder_view.py +++ b/src/cs_dynamicpages/tests/test_view_dynamic_page_folder_view.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- from cs_dynamicpages.testing import CS_DYNAMICPAGES_FUNCTIONAL_TESTING from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING from cs_dynamicpages.views.dynamic_page_folder_view import IDynamicPageFolderView @@ -12,19 +11,18 @@ class ViewsIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) - api.content.create(self.portal, 'Folder', 'other-folder') - api.content.create(self.portal, 'Document', 'front-page') + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + api.content.create(self.portal, "Folder", "other-folder") + api.content.create(self.portal, "Document", "front-page") def test_dynamic_page_folder_view_is_registered(self): view = getMultiAdapter( - (self.portal['other-folder'], self.portal.REQUEST), - name='dynamic-page-folder-view' + (self.portal["other-folder"], self.portal.REQUEST), + name="dynamic-page-folder-view", ) self.assertTrue(IDynamicPageFolderView.providedBy(view)) @@ -32,8 +30,8 @@ def test_dynamic_page_folder_view_not_matching_interface(self): view_found = True try: view = getMultiAdapter( - (self.portal['front-page'], self.portal.REQUEST), - name='dynamic-page-folder-view' + (self.portal["front-page"], self.portal.REQUEST), + name="dynamic-page-folder-view", ) except ComponentLookupError: view_found = False @@ -43,9 +41,8 @@ def test_dynamic_page_folder_view_not_matching_interface(self): class ViewsFunctionalTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_FUNCTIONAL_TESTING def setUp(self): - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) diff --git a/src/cs_dynamicpages/tests/test_view_dynamic_page_row_featured_view.py b/src/cs_dynamicpages/tests/test_view_dynamic_page_row_featured_view.py index 29e6a8f..e8d71fa 100644 --- a/src/cs_dynamicpages/tests/test_view_dynamic_page_row_featured_view.py +++ b/src/cs_dynamicpages/tests/test_view_dynamic_page_row_featured_view.py @@ -1,7 +1,8 @@ -# -*- coding: utf-8 -*- from cs_dynamicpages.testing import CS_DYNAMICPAGES_FUNCTIONAL_TESTING from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING -from cs_dynamicpages.views.dynamic_page_row_featured_view import IDynamicPageRowFeaturedView +from cs_dynamicpages.views.dynamic_page_row_featured_view import ( + IDynamicPageRowFeaturedView, +) from plone import api from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID @@ -12,19 +13,18 @@ class ViewsIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) - api.content.create(self.portal, 'Folder', 'other-folder') - api.content.create(self.portal, 'Document', 'front-page') + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) + api.content.create(self.portal, "Folder", "other-folder") + api.content.create(self.portal, "Document", "front-page") def test_dynamic_page_row_featured_view_is_registered(self): view = getMultiAdapter( - (self.portal['other-folder'], self.portal.REQUEST), - name='dynamic-page-row-featured-view' + (self.portal["other-folder"], self.portal.REQUEST), + name="dynamic-page-row-featured-view", ) self.assertTrue(IDynamicPageRowFeaturedView.providedBy(view)) @@ -32,8 +32,8 @@ def test_dynamic_page_row_featured_view_not_matching_interface(self): view_found = True try: view = getMultiAdapter( - (self.portal['front-page'], self.portal.REQUEST), - name='dynamic-page-row-featured-view' + (self.portal["front-page"], self.portal.REQUEST), + name="dynamic-page-row-featured-view", ) except ComponentLookupError: view_found = False @@ -43,9 +43,8 @@ def test_dynamic_page_row_featured_view_not_matching_interface(self): class ViewsFunctionalTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_FUNCTIONAL_TESTING def setUp(self): - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) diff --git a/src/cs_dynamicpages/tests/test_vocab_image_position.py b/src/cs_dynamicpages/tests/test_vocab_image_position.py index b5ce923..ad21df9 100644 --- a/src/cs_dynamicpages/tests/test_vocab_image_position.py +++ b/src/cs_dynamicpages/tests/test_vocab_image_position.py @@ -1,5 +1,5 @@ from cs_dynamicpages import _ -from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING # noqa +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from zope.component import getUtility @@ -10,22 +10,21 @@ class ImagePositionIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): """Custom shared utility setup for tests.""" - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) def test_vocab_image_position(self): - vocab_name = 'cs_dynamicpages.ImagePosition' + vocab_name = "cs_dynamicpages.ImagePosition" factory = getUtility(IVocabularyFactory, vocab_name) self.assertTrue(IVocabularyFactory.providedBy(factory)) vocabulary = factory(self.portal) self.assertTrue(IVocabularyTokenized.providedBy(vocabulary)) self.assertEqual( - vocabulary.getTerm('sony-a7r-iii').title, - _(u'Sony Aplha 7R III'), + vocabulary.getTerm("sony-a7r-iii").title, + _("Sony Aplha 7R III"), ) diff --git a/src/cs_dynamicpages/tests/test_vocab_row_columns.py b/src/cs_dynamicpages/tests/test_vocab_row_columns.py index afe4d49..4bc54cd 100644 --- a/src/cs_dynamicpages/tests/test_vocab_row_columns.py +++ b/src/cs_dynamicpages/tests/test_vocab_row_columns.py @@ -1,5 +1,5 @@ from cs_dynamicpages import _ -from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING # noqa +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from zope.component import getUtility @@ -10,22 +10,21 @@ class RowColumnsIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): """Custom shared utility setup for tests.""" - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) def test_vocab_row_columns(self): - vocab_name = 'cs_dynamicpages.RowColumns' + vocab_name = "cs_dynamicpages.RowColumns" factory = getUtility(IVocabularyFactory, vocab_name) self.assertTrue(IVocabularyFactory.providedBy(factory)) vocabulary = factory(self.portal) self.assertTrue(IVocabularyTokenized.providedBy(vocabulary)) self.assertEqual( - vocabulary.getTerm('sony-a7r-iii').title, - _(u'Sony Aplha 7R III'), + vocabulary.getTerm("sony-a7r-iii").title, + _("Sony Aplha 7R III"), ) diff --git a/src/cs_dynamicpages/tests/test_vocab_row_width.py b/src/cs_dynamicpages/tests/test_vocab_row_width.py index f90a250..21ae37c 100644 --- a/src/cs_dynamicpages/tests/test_vocab_row_width.py +++ b/src/cs_dynamicpages/tests/test_vocab_row_width.py @@ -1,5 +1,5 @@ from cs_dynamicpages import _ -from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING # noqa +from cs_dynamicpages.testing import CS_DYNAMICPAGES_INTEGRATION_TESTING from plone.app.testing import setRoles from plone.app.testing import TEST_USER_ID from zope.component import getUtility @@ -10,22 +10,21 @@ class RowWidthIntegrationTest(unittest.TestCase): - layer = CS_DYNAMICPAGES_INTEGRATION_TESTING def setUp(self): """Custom shared utility setup for tests.""" - self.portal = self.layer['portal'] - setRoles(self.portal, TEST_USER_ID, ['Manager']) + self.portal = self.layer["portal"] + setRoles(self.portal, TEST_USER_ID, ["Manager"]) def test_vocab_row_width(self): - vocab_name = 'cs_dynamicpages.RowWidth' + vocab_name = "cs_dynamicpages.RowWidth" factory = getUtility(IVocabularyFactory, vocab_name) self.assertTrue(IVocabularyFactory.providedBy(factory)) vocabulary = factory(self.portal) self.assertTrue(IVocabularyTokenized.providedBy(vocabulary)) self.assertEqual( - vocabulary.getTerm('sony-a7r-iii').title, - _(u'Sony Aplha 7R III'), + vocabulary.getTerm("sony-a7r-iii").title, + _("Sony Aplha 7R III"), ) diff --git a/src/cs_dynamicpages/upgrades/1001.zcml b/src/cs_dynamicpages/upgrades/1001.zcml new file mode 100644 index 0000000..1b8867c --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1001.zcml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/1001/.gitkeep b/src/cs_dynamicpages/upgrades/1001/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/cs_dynamicpages/upgrades/1001/metadata.txt b/src/cs_dynamicpages/upgrades/1001/metadata.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/cs_dynamicpages/profiles/default/registry/dynamica_pages_control_panel.xml b/src/cs_dynamicpages/upgrades/1001/registry.xml similarity index 100% rename from src/cs_dynamicpages/profiles/default/registry/dynamica_pages_control_panel.xml rename to src/cs_dynamicpages/upgrades/1001/registry.xml diff --git a/src/cs_dynamicpages/upgrades/1002.zcml b/src/cs_dynamicpages/upgrades/1002.zcml new file mode 100644 index 0000000..16f73fe --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1002.zcml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/1002/.gitkeep b/src/cs_dynamicpages/upgrades/1002/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/cs_dynamicpages/upgrades/1002/controlpanel.xml b/src/cs_dynamicpages/upgrades/1002/controlpanel.xml new file mode 100644 index 0000000..0042509 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1002/controlpanel.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + Manage Portal + + + + diff --git a/src/cs_dynamicpages/upgrades/1002/metadata.txt b/src/cs_dynamicpages/upgrades/1002/metadata.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/cs_dynamicpages/upgrades/1002/registry.xml b/src/cs_dynamicpages/upgrades/1002/registry.xml new file mode 100644 index 0000000..667857c --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1002/registry.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/1003.zcml b/src/cs_dynamicpages/upgrades/1003.zcml new file mode 100644 index 0000000..16f20e4 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1003.zcml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/1003/.gitkeep b/src/cs_dynamicpages/upgrades/1003/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/cs_dynamicpages/upgrades/1003/controlpanel.xml b/src/cs_dynamicpages/upgrades/1003/controlpanel.xml new file mode 100644 index 0000000..24436e4 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1003/controlpanel.xml @@ -0,0 +1,23 @@ + + + + + + + Manage Portal + + + + diff --git a/src/cs_dynamicpages/upgrades/1003/metadata.txt b/src/cs_dynamicpages/upgrades/1003/metadata.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/cs_dynamicpages/upgrades/1003/types.xml b/src/cs_dynamicpages/upgrades/1003/types.xml new file mode 100644 index 0000000..274b102 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1003/types.xml @@ -0,0 +1,13 @@ + + + + + diff --git a/src/cs_dynamicpages/upgrades/1003/types/DynamicPageRow.xml b/src/cs_dynamicpages/upgrades/1003/types/DynamicPageRow.xml new file mode 100644 index 0000000..666c3b3 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1003/types/DynamicPageRow.xml @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/1004.zcml b/src/cs_dynamicpages/upgrades/1004.zcml new file mode 100644 index 0000000..be98dff --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1004.zcml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/1004/.gitkeep b/src/cs_dynamicpages/upgrades/1004/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/cs_dynamicpages/upgrades/1004/metadata.txt b/src/cs_dynamicpages/upgrades/1004/metadata.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/cs_dynamicpages/upgrades/1004/types.xml b/src/cs_dynamicpages/upgrades/1004/types.xml new file mode 100644 index 0000000..7e5703a --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1004/types.xml @@ -0,0 +1,19 @@ + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/1004/types/DynamicPageFolder.xml b/src/cs_dynamicpages/upgrades/1004/types/DynamicPageFolder.xml new file mode 100644 index 0000000..8820798 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1004/types/DynamicPageFolder.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/1004/types/DynamicPageRow.xml b/src/cs_dynamicpages/upgrades/1004/types/DynamicPageRow.xml new file mode 100644 index 0000000..7929aae --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1004/types/DynamicPageRow.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/1004/types/DynamicPageRowFeatured.xml b/src/cs_dynamicpages/upgrades/1004/types/DynamicPageRowFeatured.xml new file mode 100644 index 0000000..3054528 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/1004/types/DynamicPageRowFeatured.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/__init__.py b/src/cs_dynamicpages/upgrades/__init__.py new file mode 100644 index 0000000..f212019 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/__init__.py @@ -0,0 +1,4 @@ +import logging + + +logger = logging.getLogger("cs_dynamicpages") diff --git a/src/cs_dynamicpages/upgrades/base.py b/src/cs_dynamicpages/upgrades/base.py new file mode 100644 index 0000000..34d319e --- /dev/null +++ b/src/cs_dynamicpages/upgrades/base.py @@ -0,0 +1,8 @@ +from plone.app.upgrade.utils import loadMigrationProfile + + +def reload_gs_profile(context): + loadMigrationProfile( + context, + "profile-cs_dynamicpages:default", + ) diff --git a/src/cs_dynamicpages/upgrades/configure.zcml b/src/cs_dynamicpages/upgrades/configure.zcml new file mode 100644 index 0000000..6014983 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/configure.zcml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + diff --git a/src/cs_dynamicpages/upgrades/v1001.py b/src/cs_dynamicpages/upgrades/v1001.py new file mode 100644 index 0000000..75a7f39 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/v1001.py @@ -0,0 +1,9 @@ +from . import logger + + +# from plone import api + + +def upgrade(setup_tool=None): + """ """ + logger.info("Running upgrade (Python): Add row width field in the controlpanel") diff --git a/src/cs_dynamicpages/upgrades/v1002.py b/src/cs_dynamicpages/upgrades/v1002.py new file mode 100644 index 0000000..43c5c8c --- /dev/null +++ b/src/cs_dynamicpages/upgrades/v1002.py @@ -0,0 +1,64 @@ +from . import logger +from cs_dynamicpages.controlpanels.dynamic_pages_control_panel.controlpanel import ( + IDynamicPagesControlPanel, +) +from plone import api +from plone.app.upgrade.utils import alias_module +from zope.annotation.interfaces import IAnnotations + + +# from plone import api +import json + + +alias_module( + "cs_dynamicpages.controlpanels.dynamica_pages_control_panel.controlpanel.IDynamicaPagesControlPanel", + IDynamicPagesControlPanel, +) + + +def upgrade(setup_tool=None): + """ """ + logger.info("Running upgrade (Python): Change Control Panel name in registry") + + +UPGRADEABLE_KEYS = ["row_type_fields", "row_widths"] + + +def pre_handler(setup_tool=None): + """ """ + for key in UPGRADEABLE_KEYS: + value = api.portal.get_registry_record( + f"cs_dynamicpages.dynamica_pages_control_panel.{key}", default=[] + ) + + value_str = json.dumps(value) + portal = api.portal.get() + IAnnotations(portal)[ + f"cs_dynamicpages.dynamic_pages_control_panel.{key}.UPGRADE" + ] = value_str + + logger.info("Save existing values for upgrade") + + +def post_handler(setup_tool=None): + """ """ + portal = api.portal.get() + for key in UPGRADEABLE_KEYS: + annotated = IAnnotations(portal) + value_str = annotated.get( + f"cs_dynamicpages.dynamic_pages_control_panel.{key}.UPGRADE", "[]" + ) + try: + value = json.loads(value_str) + except Exception: + value = [] + if not isinstance(value, list): + value = [] + api.portal.set_registry_record( + f"cs_dynamicpages.dynamic_pages_control_panel.{key}", value + ) + + del annotated[f"cs_dynamicpages.dynamic_pages_control_panel.{key}.UPGRADE"] + + logger.info("Restored existing values after upgrade") diff --git a/src/cs_dynamicpages/upgrades/v1003.py b/src/cs_dynamicpages/upgrades/v1003.py new file mode 100644 index 0000000..df3ac32 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/v1003.py @@ -0,0 +1,11 @@ +from . import logger +from .base import reload_gs_profile + + +# from plone import api + + +def upgrade(setup_tool=None): + """ """ + logger.info("Running upgrade (Python): Add a new default behavior to the row") + reload_gs_profile(setup_tool) diff --git a/src/cs_dynamicpages/upgrades/v1004.py b/src/cs_dynamicpages/upgrades/v1004.py new file mode 100644 index 0000000..d1d0ac4 --- /dev/null +++ b/src/cs_dynamicpages/upgrades/v1004.py @@ -0,0 +1,11 @@ +from . import logger +from .base import reload_gs_profile + + +# from plone import api + + +def upgrade(setup_tool=None): + """ """ + logger.info("Running upgrade (Python): Remove unneeded behaviors") + reload_gs_profile(setup_tool) diff --git a/src/cs_dynamicpages/utils.py b/src/cs_dynamicpages/utils.py new file mode 100644 index 0000000..065821d --- /dev/null +++ b/src/cs_dynamicpages/utils.py @@ -0,0 +1,50 @@ +from cs_dynamicpages import logger +from plone import api + + +def add_custom_view(view_name: str, shown_fields: list[str], has_button: bool = False): + """utility function to add a given view to the list of available row types""" + record_name = "cs_dynamicpages.dynamic_pages_control_panel.row_type_fields" + values = api.portal.get_registry_record(record_name) + new_item = { + "row_type": view_name, + "each_row_type_fields": shown_fields, + "row_type_has_featured_add_button": has_button, + } + values.append(new_item) + api.portal.set_registry_record(record_name, values) + logger.info("Added new row type: %s", view_name) + + return True + + +def enable_behavior(behavior_dotted_name=str): + """ + utility function to enable the given behavior in the DynamicPageRow content type + """ + # Get the portal_types tool, which manages all content type definitions (FTIs) + portal_types = api.portal.get_tool("portal_types") + + # Get the Factory Type Information (FTI) for our specific content type + fti = getattr(portal_types, "DynamicPageRow", None) + + if not fti: + # Failsafe in case the content type doesn't exist + print("Content type 'DynamicPageRow' not found.") + return + + # Get the current list of behaviors + behaviors = list(fti.behaviors) + + # --- The Core Logic --- + # Check if the behavior is already enabled to avoid duplicates + if behavior_dotted_name not in behaviors: + print(f"Enabling behavior '{behavior_dotted_name}' on 'DynamicPageRow'.") + # Add the new behavior to the list + behaviors.append(behavior_dotted_name) + # Assign the updated list back to the FTI's behaviors attribute + fti.behaviors = tuple(behaviors) + else: + print( + f"Behavior '{behavior_dotted_name}' is already enabled on 'DynamicPageRow'." + ) diff --git a/src/cs_dynamicpages/views/accordion_view.pt b/src/cs_dynamicpages/views/accordion_view.pt index 491f6e8..196e04b 100644 --- a/src/cs_dynamicpages/views/accordion_view.pt +++ b/src/cs_dynamicpages/views/accordion_view.pt @@ -1,22 +1,42 @@ -
-
+ " + tal:condition="elements" +> +
-
-
-
+
- + " + > +
-
\ No newline at end of file +
diff --git a/src/cs_dynamicpages/views/configure.zcml b/src/cs_dynamicpages/views/configure.zcml index 15a3539..cf529be 100644 --- a/src/cs_dynamicpages/views/configure.zcml +++ b/src/cs_dynamicpages/views/configure.zcml @@ -2,28 +2,31 @@ xmlns="http://namespaces.zope.org/zope" xmlns:browser="http://namespaces.zope.org/browser" xmlns:plone="http://namespaces.plone.org/plone" + xmlns:zcml="http://namespaces.zope.org/zcml" i18n_domain="cs_dynamicpages" > + name="view" + for="cs_dynamicpages.content.dynamic_page_row_featured.IDynamicPageRowFeatured" + class=".dynamic_page_row_featured_view.DynamicPageRowFeaturedView" + template="dynamic_page_row_featured_view.pt" + permission="zope2.View" + layer="cs_dynamicpages.interfaces.IBrowserLayer" + /> + name="view" + for="cs_dynamicpages.content.dynamic_page_folder.IDynamicPageFolder" + class=".dynamic_page_folder_view.DynamicPageFolderView" + template="dynamic_page_folder_view.pt" + permission="zope2.View" + layer="cs_dynamicpages.interfaces.IBrowserLayer" + menu="plone_displayviews" + title="Dynamic view" + /> + + + @@ -98,6 +118,7 @@ diff --git a/src/cs_dynamicpages/views/dynamic_page_folder_view.pt b/src/cs_dynamicpages/views/dynamic_page_folder_view.pt index d5f368c..a3fa57c 100644 --- a/src/cs_dynamicpages/views/dynamic_page_folder_view.pt +++ b/src/cs_dynamicpages/views/dynamic_page_folder_view.pt @@ -1,29 +1,33 @@ - + - + - -

- + +

+
- -

- + +

+
- - + + - - - - + + + + - - - + + + - \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/dynamic_page_folder_view.py b/src/cs_dynamicpages/views/dynamic_page_folder_view.py index f8596ad..d58cd86 100644 --- a/src/cs_dynamicpages/views/dynamic_page_folder_view.py +++ b/src/cs_dynamicpages/views/dynamic_page_folder_view.py @@ -1,14 +1,14 @@ -# -*- coding: utf-8 -*- - # from cs_dynamicpages import _ from Products.Five.browser import BrowserView from zope.interface import implementer from zope.interface import Interface + # from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile + class IDynamicPageFolderView(Interface): - """ Marker Interface for IDynamicPageFolderView""" + """Marker Interface for IDynamicPageFolderView""" @implementer(IDynamicPageFolderView) diff --git a/src/cs_dynamicpages/views/dynamic_page_row_featured_view.pt b/src/cs_dynamicpages/views/dynamic_page_row_featured_view.pt index c20cd52..e52636d 100644 --- a/src/cs_dynamicpages/views/dynamic_page_row_featured_view.pt +++ b/src/cs_dynamicpages/views/dynamic_page_row_featured_view.pt @@ -1,26 +1,29 @@ - + - + - -

- + +

+
- -

- + +

+
- - + + - - + + - - - + + + - \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/dynamic_page_row_featured_view.py b/src/cs_dynamicpages/views/dynamic_page_row_featured_view.py index 0dd9585..84422a9 100644 --- a/src/cs_dynamicpages/views/dynamic_page_row_featured_view.py +++ b/src/cs_dynamicpages/views/dynamic_page_row_featured_view.py @@ -1,14 +1,14 @@ -# -*- coding: utf-8 -*- - # from cs_dynamicpages import _ from Products.Five.browser import BrowserView from zope.interface import implementer from zope.interface import Interface + # from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile + class IDynamicPageRowFeaturedView(Interface): - """ Marker Interface for IDynamicPageRowFeaturedView""" + """Marker Interface for IDynamicPageRowFeaturedView""" @implementer(IDynamicPageRowFeaturedView) diff --git a/src/cs_dynamicpages/views/dynamic_page_row_view.pt b/src/cs_dynamicpages/views/dynamic_page_row_view.pt index ee0fb45..6fdc932 100644 --- a/src/cs_dynamicpages/views/dynamic_page_row_view.pt +++ b/src/cs_dynamicpages/views/dynamic_page_row_view.pt @@ -1,26 +1,29 @@ - + - + - -

- + +

+
- -

- + +

+
- - + + - - + + - - - + + + - \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/dynamic_page_row_view.py b/src/cs_dynamicpages/views/dynamic_page_row_view.py index df39bd6..a15d1ea 100644 --- a/src/cs_dynamicpages/views/dynamic_page_row_view.py +++ b/src/cs_dynamicpages/views/dynamic_page_row_view.py @@ -3,6 +3,7 @@ from zope.interface import implementer from zope.interface import Interface + # from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile diff --git a/src/cs_dynamicpages/views/dynamic_view.pt b/src/cs_dynamicpages/views/dynamic_view.pt index 890ba37..a78b9c1 100644 --- a/src/cs_dynamicpages/views/dynamic_view.pt +++ b/src/cs_dynamicpages/views/dynamic_view.pt @@ -1,202 +1,368 @@ - + - - -
- -
-
-
- - + + +
+ +
+
+
+ + +
-
- - -
-
- - - - - Template: ${row/row_template} - - - - - - - - - -
+ + +
+
+ + + + + + Template: + ${row/row_template} + - - + + + - - + + + -
- + + + + + + + +
+ - + 'position-relative btn btn-outline-danger btn-sm bg-danger-subtle dropdown-toggle'; + " + > + + + + + Review state: + ${row/review_state} + + + + +
-
-
- -
- - -
- + +
+
+ +
- -
-
- +
+
+
+ +
+ + + +
+
+ +
-
- + + + + - \ No newline at end of file + diff --git a/src/cs_dynamicpages/views/dynamic_view.py b/src/cs_dynamicpages/views/dynamic_view.py index adee2ed..cef7187 100644 --- a/src/cs_dynamicpages/views/dynamic_view.py +++ b/src/cs_dynamicpages/views/dynamic_view.py @@ -1,10 +1,10 @@ # from cs_dynamicpages import _ from plone import api +from plone.protect.interfaces import IDisableCSRFProtection from Products.Five.browser import BrowserView +from zope.interface import alsoProvides from zope.interface import implementer from zope.interface import Interface -from plone.protect.interfaces import IDisableCSRFProtection -from zope.interface import alsoProvides # from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile @@ -28,20 +28,27 @@ def rows(self): def dynamic_page_folder_element(self): page_folders = api.content.find( - portal_type="DynamicPageFolder", context=self.context, depth=1, sort_on="getObjPositionInParent" + portal_type="DynamicPageFolder", + context=self.context, + depth=1, + sort_on="getObjPositionInParent", ) if page_folders: return page_folders else: - alsoProvides(self.request, IDisableCSRFProtection) - api.content.create( - container=self.context, - type="DynamicPageFolder", - title="Rows", - ) - return api.content.find( - portal_type="DynamicPageFolder", context=self.context, depth=1, sort_on="getObjPositionInParent" - ) + if self.can_edit(): + alsoProvides(self.request, IDisableCSRFProtection) + api.content.create( + container=self.context, + type="DynamicPageFolder", + title="Rows", + ) + return api.content.find( + portal_type="DynamicPageFolder", + context=self.context, + depth=1, + sort_on="getObjPositionInParent", + ) def dynamic_page_folder_element_url(self): dynamic_page_folder = self.dynamic_page_folder_element() @@ -50,4 +57,4 @@ def dynamic_page_folder_element_url(self): return "" def can_edit(self): - return api.user.has_permission("Modify portal content", obj=self.context) \ No newline at end of file + return api.user.has_permission("Modify portal content", obj=self.context) diff --git a/src/cs_dynamicpages/views/featured_overlay_view.pt b/src/cs_dynamicpages/views/featured_overlay_view.pt index 34fc3da..07742fc 100644 --- a/src/cs_dynamicpages/views/featured_overlay_view.pt +++ b/src/cs_dynamicpages/views/featured_overlay_view.pt @@ -2,18 +2,26 @@ + " + tal:condition="image" + > + title=image.Title())" + />
${context/Title}
-

${context/Description}

- ${context/link_text} +

${context/Description}

+ ${context/link_text}
-

\ No newline at end of file + diff --git a/src/cs_dynamicpages/views/featured_view.pt b/src/cs_dynamicpages/views/featured_view.pt index 915d80b..839626b 100644 --- a/src/cs_dynamicpages/views/featured_view.pt +++ b/src/cs_dynamicpages/views/featured_view.pt @@ -1,23 +1,35 @@
+ image view/related_image; + " + tal:condition="image" + > + title=image.Title())" + />
+ tal:attributes=" + class python:context.image_position=='right' and 'col-md-6 order-first' or 'col-md-6'; + " + >

${context/Title}

${context/Description}

- + - ${context/link_text} + ${context/link_text}
-
\ No newline at end of file + diff --git a/src/cs_dynamicpages/views/featured_view.py b/src/cs_dynamicpages/views/featured_view.py index 0f6e7c5..ae977c9 100644 --- a/src/cs_dynamicpages/views/featured_view.py +++ b/src/cs_dynamicpages/views/featured_view.py @@ -1,7 +1,7 @@ # from cs_dynamicpages import _ +from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView from zope.interface import implementer from zope.interface import Interface -from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView class IFeaturedView(Interface): diff --git a/src/cs_dynamicpages/views/features_view.pt b/src/cs_dynamicpages/views/features_view.pt index c85ec5d..664903b 100644 --- a/src/cs_dynamicpages/views/features_view.pt +++ b/src/cs_dynamicpages/views/features_view.pt @@ -1,32 +1,50 @@ -
-
+ " + tal:condition="elements" +> +
+ element brain/getObject; + ">
+ image element/related_image_object; + " + tal:condition="image" + tal:on-error="nothing" + > + title=element.Title())" + />
- ${element/Title} -

${element/Title}

-

${element/Description}

- + ${element/Title} +

${element/Title}

+

${element/Description}

+
-
\ No newline at end of file +
diff --git a/src/cs_dynamicpages/views/horizontal_rule_view.pt b/src/cs_dynamicpages/views/horizontal_rule_view.pt index 84af8ad..af383ee 100644 --- a/src/cs_dynamicpages/views/horizontal_rule_view.pt +++ b/src/cs_dynamicpages/views/horizontal_rule_view.pt @@ -1 +1 @@ -
\ No newline at end of file +
diff --git a/src/cs_dynamicpages/views/query_columns_view.pt b/src/cs_dynamicpages/views/query_columns_view.pt index 5b11405..5c23d4e 100644 --- a/src/cs_dynamicpages/views/query_columns_view.pt +++ b/src/cs_dynamicpages/views/query_columns_view.pt @@ -1,6 +1,8 @@ -
+

${context/Title}

@@ -11,21 +13,32 @@
+ " + tal:condition="image" + tal:on-error="nothing" + > + title=element.Title())" + />
- ${element/Title} -

-

+ ${element/Title} +

+

${element/Description}

@@ -36,7 +49,9 @@
-
\ No newline at end of file +
diff --git a/src/cs_dynamicpages/views/query_columns_view.py b/src/cs_dynamicpages/views/query_columns_view.py index 5ae8b6d..29a923a 100644 --- a/src/cs_dynamicpages/views/query_columns_view.py +++ b/src/cs_dynamicpages/views/query_columns_view.py @@ -1,8 +1,9 @@ # from cs_dynamicpages import _ +from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView from plone.app.contenttypes.browser.collection import CollectionView from zope.interface import implementer from zope.interface import Interface -from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView + # from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile diff --git a/src/cs_dynamicpages/views/slider_view.pt b/src/cs_dynamicpages/views/slider_view.pt index bad68cb..c2fd2d8 100644 --- a/src/cs_dynamicpages/views/slider_view.pt +++ b/src/cs_dynamicpages/views/slider_view.pt @@ -1,44 +1,79 @@ - \ No newline at end of file +
diff --git a/src/cs_dynamicpages/views/slider_view.py b/src/cs_dynamicpages/views/slider_view.py index ca22b3e..1ce0fd2 100644 --- a/src/cs_dynamicpages/views/slider_view.py +++ b/src/cs_dynamicpages/views/slider_view.py @@ -1,8 +1,8 @@ # from cs_dynamicpages import _ +from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView from plone import api from zope.interface import implementer from zope.interface import Interface -from cs_dynamicpages.views.dynamic_page_row_view import DynamicPageRowView class ISliderView(Interface): diff --git a/src/cs_dynamicpages/views/spacer_view.pt b/src/cs_dynamicpages/views/spacer_view.pt index ae4bf27..903b036 100644 --- a/src/cs_dynamicpages/views/spacer_view.pt +++ b/src/cs_dynamicpages/views/spacer_view.pt @@ -1,2 +1,2 @@
-
\ No newline at end of file + diff --git a/src/cs_dynamicpages/views/text_view.pt b/src/cs_dynamicpages/views/text_view.pt index c739948..fd65f8d 100644 --- a/src/cs_dynamicpages/views/text_view.pt +++ b/src/cs_dynamicpages/views/text_view.pt @@ -1,4 +1,6 @@
- - -
\ No newline at end of file + + + diff --git a/src/cs_dynamicpages/vocabularies/configure.zcml b/src/cs_dynamicpages/vocabularies/configure.zcml index df1578b..6dce66c 100644 --- a/src/cs_dynamicpages/vocabularies/configure.zcml +++ b/src/cs_dynamicpages/vocabularies/configure.zcml @@ -2,22 +2,22 @@ - + - + - + list: + """Content to be created.""" + return [ + # EU CONTENT + { + "_container": "", + "_language": "eu", + "_transitions": ["publish"], + "type": "Folder", + "id": "folder", + "title": "Folder", + }, + { + "_container": "folder", + "_transitions": ["publish"], + "_language": "eu", + "type": "DynamicPageFolder", + "id": "dpf", + "title": "DPF", + }, + { + "_container": "folder/dpf", + "_transitions": ["publish"], + "_language": "eu", + "type": "DynamicPageRow", + "id": "row-1", + "title": "Row 1", + }, + { + "_container": "folder/dpf", + "_transitions": ["publish"], + "_language": "eu", + "type": "DynamicPageRow", + "id": "row-2", + "title": "Row 2", + }, + ] + + +@pytest.fixture() +def portal(functional): + return functional["portal"] + + +@pytest.fixture() +def browser(functional): + browser = Browser(functional["app"]) + browser.handleErrors = False + browser.addHeader("Authorization", f"Basic {SITE_OWNER_NAME}:{SITE_OWNER_PASSWORD}") + return browser + + +@pytest.fixture() +def my_request(functional): + req = functional["request"] + alsoProvides(req, IBrowserLayer) + return req + + +@pytest.fixture +def create_contents(contents): + """Helper fixture to create initial content.""" + + def func(portal) -> dict: + ids = defaultdict(list) + for item in contents: + container_path = item["_container"] + container = portal.unrestrictedTraverse(container_path) + payload = {"container": container, "language": item["_language"]} + if "_image" in item: + payload["image"] = NamedBlobImage(b64decode(item["_image"])) + for key, value in item.items(): + if key.startswith("_"): + continue + payload[key] = value + + content = api.content.create(**payload) + content.language = payload["language"] + if "_view" in item: + content.setLayout(item["_view"]) + # Set translation + if "_translation_of" in item: + source = portal.unrestrictedTraverse(item["_translation_of"]) + ITranslationManager(source).register_translation( + content.language, content + ) + # Transition items + if "_transitions" in item: + transitions = item["_transitions"] + for transition in transitions: + api.content.transition(content, transition=transition) + ids[container_path].append(content.getId()) + return ids + + return func + + +@pytest.fixture() +def portal_with_content(app, portal, create_contents): + """Plone portal with initial content.""" + with api.env.adopt_roles(["Manager"]): + create_contents(portal) + # transaction.commit() + yield portal + # with api.env.adopt_roles(["Manager"]): + # containers = sorted(content_ids.keys(), reverse=True) + # for container_path in containers: + # container = portal.unrestrictedTraverse(container_path) + # container.manage_delObjects(content_ids[container_path]) + # transaction.commit() diff --git a/tests/content/test_content_operations.py b/tests/content/test_content_operations.py new file mode 100644 index 0000000..40b4e6e --- /dev/null +++ b/tests/content/test_content_operations.py @@ -0,0 +1,72 @@ +from ..base import TestBase +from plone import api + +import pytest +import transaction + + +class TestContent(TestBase): + @pytest.fixture(autouse=True) + def create_content(self, portal): + with api.env.adopt_roles(["Manager"]): + self.folder = api.content.create( + container=portal, + type="Folder", + id="folder", + ) + + assert self.folder is not None + assert self.folder.id == "folder" + + self.folder.setLayout("dynamic-view") + + self.dpf = api.content.create( + container=self.folder, type="DynamicPageFolder", id="dpf", title="DPF" + ) + + assert self.dpf is not None + assert self.dpf.id == "dpf" + + self.row1 = api.content.create( + container=self.dpf, type="DynamicPageRow", id="row-1", title="Row 1" + ) + assert self.row1 is not None + assert self.row1.id == "row-1" + + self.row2 = api.content.create( + container=self.dpf, type="DynamicPageRow", id="row-2", title="Row 2" + ) + assert self.row2 is not None + assert self.row2.id == "row-2" + + transaction.commit() + + def test_view(self, browser): + """check that the folder is rendered correctly with the basic instructions""" + + browser.open(self.folder.absolute_url()) + # We have 2 rows, so there must be an option to delete a row + # assert "Delete row" in browser.contents + + # assert "Row 1" in browser.contents + # assert "Row 2" in browser.contents + + # There must be an option to add a new row + assert "Add row" in browser.contents + + # def test_add_row(self, browser): + # """click add row""" + # browser.open(self.folder.absolute_url()) + # link = browser.getLink(title="Add row") + # link.click() + # assert "++add++DynamicPageRow" in browser.url + + # control = browser.getControl(name="form.widgets.IBasic.title") + # control.value = "Row 3" + + # save = browser.getControl(name="form.buttons.save") + # save.click() + + # browser.open(self.folder.absolute_url()) + + # assert len(self.folder.dpf.keys()) == 3 diff --git a/tests/setup/__init__.py b/tests/setup/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/setup/test_setup_install.py b/tests/setup/test_setup_install.py index e2efb57..5595212 100644 --- a/tests/setup/test_setup_install.py +++ b/tests/setup/test_setup_install.py @@ -1,7 +1,8 @@ +from ..base import TestBase from cs_dynamicpages import PACKAGE_NAME -class TestSetupInstall: +class TestSetupInstall(TestBase): def test_addon_installed(self, installer): """Test if cs_dynamicpages is installed.""" assert installer.is_product_installed(PACKAGE_NAME) is True @@ -14,4 +15,4 @@ def test_browserlayer(self, browser_layers): def test_latest_version(self, profile_last_version): """Test latest version of default profile.""" - assert profile_last_version(f"{PACKAGE_NAME}:default") == "1000" + assert profile_last_version(f"{PACKAGE_NAME}:default") == "1004"