diff --git a/src/iosanita/contenttypes/adapters/__init__.py b/src/iosanita/contenttypes/adapters/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/iosanita/contenttypes/adapters/configure.zcml b/src/iosanita/contenttypes/adapters/configure.zcml
new file mode 100644
index 0000000..3ebe30e
--- /dev/null
+++ b/src/iosanita/contenttypes/adapters/configure.zcml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
diff --git a/src/iosanita/contenttypes/adapters/query.py b/src/iosanita/contenttypes/adapters/query.py
new file mode 100644
index 0000000..25be442
--- /dev/null
+++ b/src/iosanita/contenttypes/adapters/query.py
@@ -0,0 +1,26 @@
+from iosanita.contenttypes.interfaces import IIosanitaContenttypesLayer
+from plone.restapi.interfaces import IZCatalogCompatibleQuery
+from plone.restapi.search.query import ZCatalogCompatibleQueryAdapter as BaseAdapter
+from zope.component import adapter
+from zope.interface import implementer
+from zope.interface import Interface
+from plone import api
+
+
+@implementer(IZCatalogCompatibleQuery)
+@adapter(Interface, IIosanitaContenttypesLayer)
+class ZCatalogCompatibleQueryAdapter(BaseAdapter):
+ """ """
+
+ def __call__(self, query):
+ """
+ Do not show excluded from search items when anonymous are performing
+ some catalog searches
+ """
+ query = super().__call__(query=query)
+
+ if api.user.is_anonymous():
+ # For the anonymous user, only content that is not "excluded from the search" is found
+ query["exclude_from_search"] = False
+
+ return query
diff --git a/src/iosanita/contenttypes/behaviors/configure.zcml b/src/iosanita/contenttypes/behaviors/configure.zcml
index 2dcbd68..c0198cf 100644
--- a/src/iosanita/contenttypes/behaviors/configure.zcml
+++ b/src/iosanita/contenttypes/behaviors/configure.zcml
@@ -85,14 +85,6 @@
provides=".contatti.IContattiUnitaOrganizzativa"
marker=".contatti.IContattiUnitaOrganizzativa"
/>
-
-
+
+
diff --git a/src/iosanita/contenttypes/behaviors/contatti.py b/src/iosanita/contenttypes/behaviors/contatti.py
index d9e825c..6827966 100644
--- a/src/iosanita/contenttypes/behaviors/contatti.py
+++ b/src/iosanita/contenttypes/behaviors/contatti.py
@@ -13,6 +13,8 @@
from iosanita.contenttypes import _
from iosanita.contenttypes.interfaces.persona import IPersona
+from iosanita.contenttypes.interfaces.step import IStep
+
from iosanita.contenttypes.interfaces.unita_organizzativa import IUnitaOrganizzativa
@@ -61,29 +63,48 @@ class IContattiUnitaOrganizzativa(model.Schema):
@provider(IFormFieldProvider)
-class IContattiStep(model.Schema):
+class IContattiEvent(model.Schema):
contact_info = RelationList(
title=_(
"contact_info_label",
- default="Contatti",
+ default="Punti di contatto",
),
description=_(
- "contatti_step_contact_info_help",
- default="I contatti per questo step.",
+ "contact_info_help",
+ default="Relazione con i punti di contatto dell'evento.",
),
+ required=True,
+ default=[],
+ value_type=RelationChoice(
+ title=_("Punti di contatto"),
+ vocabulary="plone.app.vocabularies.Catalog",
+ ),
+ )
+ form.widget(
+ "contact_info",
+ RelatedItemsFieldWidget,
+ vocabulary="plone.app.vocabularies.Catalog",
+ pattern_options={
+ "selectableTypes": ["PuntoDiContatto"],
+ },
+ )
+ model.fieldset(
+ "contatti",
+ label=_("contatti_label", default="Contatti"),
+ fields=["contact_info"],
)
@provider(IFormFieldProvider)
-class IContattiEvent(model.Schema):
+class IContattiPersona(model.Schema):
contact_info = RelationList(
title=_(
"contatti_event_contact_info_label",
default="Punti di contatto",
),
description=_(
- "contatti_event_contact_info_help",
- default="Relazione con i punti di contatto dell'evento.",
+ "contact_info_help",
+ default="Punti di contatto della persona.",
),
required=True,
default=[],
@@ -92,6 +113,7 @@ class IContattiEvent(model.Schema):
vocabulary="plone.app.vocabularies.Catalog",
),
)
+
form.widget(
"contact_info",
RelatedItemsFieldWidget,
@@ -108,7 +130,7 @@ class IContattiEvent(model.Schema):
@provider(IFormFieldProvider)
-class IContattiPersona(model.Schema):
+class IContattiStep(model.Schema):
contact_info = RelationList(
title=_(
"contatti_persona_contact_info_label",
@@ -116,7 +138,7 @@ class IContattiPersona(model.Schema):
),
description=_(
"contact_info_help",
- default="Punti di contatto della persona.",
+ default="Punti di contatto per questo passo.",
),
required=True,
default=[],
@@ -175,3 +197,12 @@ class ContattiPersona(object):
def __init__(self, context):
self.context = context
+
+
+@implementer(IContattiStep)
+@adapter(IStep)
+class ContattiStep(object):
+ """ """
+
+ def __init__(self, context):
+ self.context = context
diff --git a/src/iosanita/contenttypes/behaviors/exclude_from_search.py b/src/iosanita/contenttypes/behaviors/exclude_from_search.py
new file mode 100644
index 0000000..fc73272
--- /dev/null
+++ b/src/iosanita/contenttypes/behaviors/exclude_from_search.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+from iosanita.contenttypes import _
+from plone.autoform.interfaces import IFormFieldProvider
+from plone.dexterity.interfaces import IDexterityContent
+from plone.supermodel import model
+from zope import schema
+from zope.component import adapter
+from zope.interface import implementer
+from zope.interface import provider
+
+
+@provider(IFormFieldProvider)
+class IExcludeFromSearch(model.Schema):
+ """ """
+
+ exclude_from_search = schema.Bool(
+ title=_("exclude_from_search_label", default="Escludi dalla ricerca"),
+ description=_(
+ "help_exclude_from_search",
+ default="Se selezionato, questo contenuto non verrà mostrato nelle ricerche del sito per gli utenti anonimi.",
+ ),
+ required=False,
+ default=False,
+ )
+ model.fieldset(
+ "settings",
+ fields=["exclude_from_search"],
+ )
+
+
+@implementer(IExcludeFromSearch)
+@adapter(IDexterityContent)
+class ExcludeFromSearch(object):
+ """ """
+
+ def __init__(self, context):
+ self.context = context
diff --git a/src/iosanita/contenttypes/configure.zcml b/src/iosanita/contenttypes/configure.zcml
index e26658b..464b258 100644
--- a/src/iosanita/contenttypes/configure.zcml
+++ b/src/iosanita/contenttypes/configure.zcml
@@ -10,10 +10,10 @@
-
+
-
+
diff --git a/src/iosanita/contenttypes/content/punto_di_contatto.py b/src/iosanita/contenttypes/content/punto_di_contatto.py
new file mode 100644
index 0000000..1505a3c
--- /dev/null
+++ b/src/iosanita/contenttypes/content/punto_di_contatto.py
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+from iosanita.contenttypes.interfaces.punto_di_contatto import IPuntoDiContatto
+from plone.dexterity.content import Container
+from zope.interface import implementer
+
+
+@implementer(IPuntoDiContatto)
+class PuntoDiContatto(Container):
+ """ """
diff --git a/src/iosanita/contenttypes/controlpanels/__init__.py b/src/iosanita/contenttypes/controlpanels/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/src/iosanita/contenttypes/controlpanels/configure.zcml b/src/iosanita/contenttypes/controlpanels/configure.zcml
new file mode 100644
index 0000000..a25901c
--- /dev/null
+++ b/src/iosanita/contenttypes/controlpanels/configure.zcml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/src/iosanita/contenttypes/controlpanels/settings.py b/src/iosanita/contenttypes/controlpanels/settings.py
new file mode 100644
index 0000000..9935b93
--- /dev/null
+++ b/src/iosanita/contenttypes/controlpanels/settings.py
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+from iosanita.contenttypes import _
+from plone.app.registry.browser.controlpanel import ControlPanelFormWrapper
+from plone.app.registry.browser.controlpanel import RegistryEditForm
+from plone.restapi.controlpanels.interfaces import IControlpanel
+from zope.interface import Interface
+from zope.schema import Bool
+from zope.schema import List
+from zope.schema import SourceText
+from zope.schema import TextLine
+
+
+class IoSanitaSettingsControlpanel(IControlpanel):
+ """ """
+
+
+class IIoSanitaSettings(Interface):
+
+ lead_image_dimension = List(
+ title=_(
+ "lead_image_dimension_label",
+ default="Dimensioni lead image",
+ ),
+ description=_(
+ "lead_image_dimension_help",
+ default="Se un content-type deve avere una dimensione della "
+ "leadimage particolare, indicarle qui. "
+ "Inserire le dimensioni nella forma di esempio "
+ "PortalType|900x900",
+ ),
+ required=True,
+ default=[
+ "News Item|1920x600",
+ "Servizio|1920x600",
+ "UnitaOrganizzativa|1920x600",
+ "Persona|180x100",
+ ],
+ value_type=TextLine(),
+ )
+
+ search_sections = SourceText(
+ title=_("search_sections_label", default="Sezioni ricerca"),
+ description=_(
+ "search_sections_help",
+ default="Inserire una lista di sezioni per la ricerca.",
+ ),
+ default="",
+ required=False,
+ )
+
+ show_modified_default = Bool(
+ title=_("show_modified_default_label", default="Mostra la data di modifica"),
+ description=_(
+ "show_modified_default_help",
+ default="Questo è il valore di default per decidere se mostrare "
+ "o meno la data di modifica nei contenuti che hanno la behavior "
+ "abilitata. E' poi possibile sovrascrivere il default nei singoli "
+ 'contenuti (nel tab "Impostazioni").',
+ ),
+ default=True,
+ required=False,
+ )
+ show_dynamic_folders_in_footer = Bool(
+ title=_("show_dynamic_folders_in_footer_label", default="Footer dinamico"),
+ description=_(
+ "show_dynamic_folders_in_footer_help",
+ default="Se selezionato, il footer verrà popolato automaticamente "
+ "con i contenuti di primo livello non esclusi dalla navigazione.",
+ ),
+ default=True,
+ required=False,
+ )
+
+
+class IoSanitaControlPanelForm(RegistryEditForm):
+ schema = IIoSanitaSettings
+ id = "io-sanita-control-panel"
+ label = _("Impostazioni Io sanita")
+
+
+class IoSanitaControlPanelView(ControlPanelFormWrapper):
+ """ """
+
+ form = IoSanitaControlPanelForm
diff --git a/src/iosanita/contenttypes/events/common.py b/src/iosanita/contenttypes/events/common.py
new file mode 100644
index 0000000..536a8e3
--- /dev/null
+++ b/src/iosanita/contenttypes/events/common.py
@@ -0,0 +1,234 @@
+# -*- coding: utf-8 -*-
+from iosanita.contenttypes.interfaces import IIosanitaContenttypesLayer
+from iosanita.contenttypes.utils import create_default_blocks
+from plone import api
+from Products.CMFPlone.interfaces import ISelectableConstrainTypes
+
+
+SUBFOLDERS_MAPPING = {
+ "Bando": {
+ "content": [
+ {"id": "documenti", "title": "Documenti", "type": "Bando Folder Deepening"},
+ {
+ "id": "comunicazioni",
+ "title": "Comunicazioni",
+ "type": "Bando Folder Deepening",
+ },
+ {"id": "esiti", "title": "Esiti", "type": "Bando Folder Deepening"},
+ ],
+ },
+ "Documento": {
+ "content": [
+ {
+ "id": "multimedia",
+ "title": "Multimedia",
+ "type": "Document",
+ "allowed_types": ("Image",),
+ },
+ ],
+ },
+ "Event": {
+ "content": [
+ {
+ "id": "immagini",
+ "title": "Immagini",
+ "allowed_types": ("Image", "Link"),
+ "publish": True,
+ },
+ {
+ "id": "video",
+ "title": "Video",
+ "allowed_types": ("Link",),
+ "publish": True,
+ },
+ {
+ "id": "sponsor_evento",
+ "title": "Sponsor Evento",
+ "allowed_types": ("Link",),
+ "publish": True,
+ },
+ {
+ "id": "documenti",
+ "title": "Allegati",
+ "allowed_types": ("File",),
+ "publish": True,
+ },
+ ],
+ },
+ "Incarico": {
+ "content": [
+ {"id": "compensi-file", "title": "Compensi", "allowed": ("File",)},
+ {
+ "id": "importi-di-viaggio-e-o-servizi",
+ "title": "Importi di viaggio e/o servizi",
+ "allowed_types": ("File",),
+ },
+ ],
+ "allowed_types": [],
+ },
+ "Venue": {
+ "content": [
+ {
+ "id": "multimedia",
+ "title": "Multimedia",
+ "type": "Folder",
+ "allowed_types": (
+ "Image",
+ "Link",
+ ),
+ "publish": True,
+ }
+ ],
+ },
+ "News Item": {
+ "content": [
+ {
+ "id": "multimedia",
+ "title": "Multimedia",
+ "allowed_types": (
+ "Image",
+ "Link",
+ ),
+ },
+ {
+ "id": "documenti-allegati",
+ "title": "Documenti allegati",
+ "allowed_types": (
+ "File",
+ "Image",
+ ),
+ },
+ ],
+ },
+ "Persona": {
+ "content": [
+ {
+ "id": "foto-e-attivita-politica",
+ "title": "Foto e attività politica",
+ "allowed_types": ("Image",),
+ },
+ {
+ "id": "curriculum-vitae",
+ "title": "Curriculum vitae",
+ "allowed_types": ("File",),
+ },
+ {
+ "id": "situazione-patrimoniale",
+ "title": "Situazione patrimoniale",
+ "allowed_types": ("File",),
+ },
+ {
+ "id": "dichiarazione-dei-redditi",
+ "title": "Dichiarazione dei redditi",
+ "allowed_types": ("File",),
+ },
+ {
+ "id": "spese-elettorali",
+ "title": "Spese elettorali",
+ "allowed_types": ("File",),
+ },
+ {
+ "id": "variazione-situazione-patrimoniale",
+ "title": "Variazione situazione patrimoniale",
+ "allowed_types": ("File",),
+ },
+ {
+ "id": "altre-cariche",
+ "title": "Altre cariche",
+ "allowed_types": ("File",),
+ },
+ {"id": "incarichi", "title": "Incarichi", "allowed_types": ("Incarico",)},
+ {
+ "id": "altri-documenti",
+ "title": "Altri documenti",
+ "allowed_types": ("File", "Image", "Link"),
+ },
+ ],
+ "allowed_types": [],
+ },
+ "Pratica": {
+ "content": [
+ {
+ "id": "allegati",
+ "title": "Allegati",
+ "type": "Folder",
+ "allowed_types": ("File",),
+ }
+ ],
+ },
+ "Servizio": {
+ "content": [
+ {
+ "id": "modulistica",
+ "title": "Modulistica",
+ "allowed_types": ("Link",),
+ },
+ {"id": "allegati", "title": "Allegati", "allowed_types": ("File", "Link")},
+ ],
+ },
+ "UnitaOrganizzativa": {
+ "content": [
+ {"id": "allegati", "title": "Allegati", "allowed_types": ("File",)},
+ ],
+ },
+ "Step": {
+ "content": [
+ {"id": "documenti", "title": "Documenti", "allowed_types": ("File",)},
+ ],
+ },
+}
+
+
+def onModify(context, event):
+ for description in event.descriptions:
+ if "IBasic.title" in getattr(
+ description, "attributes", []
+ ) or "IDublinCore.title" in getattr(description, "attributes", []):
+ for child in context.listFolderContents():
+ child.reindexObject(idxs=["parent"])
+
+
+def createSubfolders(context, event):
+ """
+ Create subfolders structure based on a portal_type mapping
+ """
+ if not IIosanitaContenttypesLayer.providedBy(context.REQUEST):
+ return
+
+ subfolders_mapping = SUBFOLDERS_MAPPING.get(context.portal_type, [])
+ if not subfolders_mapping:
+ return
+
+ for mapping in subfolders_mapping.get("content", {}):
+ if mapping["id"] not in context.keys():
+ portal_type = mapping.get("type", "Document")
+ child = api.content.create(
+ container=context,
+ type=portal_type,
+ title=mapping["title"],
+ id=mapping["id"],
+ )
+ if portal_type == "Document":
+ create_default_blocks(context=child)
+
+ if portal_type in ["Folder", "Document"]:
+ child.exclude_from_search = True
+ child.reindexObject(idxs=["exclude_from_search"])
+ # select constraints
+ if mapping.get("allowed_types", ()):
+ constraints_child = ISelectableConstrainTypes(child)
+ constraints_child.setConstrainTypesMode(1)
+ constraints_child.setLocallyAllowedTypes(mapping["allowed_types"])
+
+ if mapping.get("publish", False):
+ with api.env.adopt_roles(["Reviewer"]):
+ api.content.transition(obj=child, transition="publish")
+
+ allowed_types = subfolders_mapping.get("allowed_types", None)
+ if allowed_types is not None and not isinstance(allowed_types, list):
+ raise ValueError("Subfolder map is not well formed")
+
+ if isinstance(allowed_types, list):
+ constraints_context = ISelectableConstrainTypes(context)
+ constraints_context.setConstrainTypesMode(1)
+ constraints_context.setLocallyAllowedTypes(allowed_types)
diff --git a/src/iosanita/contenttypes/events/configure.zcml b/src/iosanita/contenttypes/events/configure.zcml
index d276036..163feec 100644
--- a/src/iosanita/contenttypes/events/configure.zcml
+++ b/src/iosanita/contenttypes/events/configure.zcml
@@ -7,6 +7,16 @@
+
+
+
diff --git a/src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg b/src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg
new file mode 100644
index 0000000..799a947
--- /dev/null
+++ b/src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.cfg
@@ -0,0 +1,11 @@
+[taxonomy]
+name = tipologia_pdc
+title = Tipo di punto di contatto
+description = Il sistema di gestione contenuti basato su React
+default_language = it
+field_title = Tipo di punto di contatto
+field_description = Seleziona la tipologia del punto di contatto
+field_prefix =
+taxonomy_fieldset = contatti
+is_single_select = false
+is_required = true
\ No newline at end of file
diff --git a/src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_punti_di_contatto.xml b/src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml
similarity index 96%
rename from src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_punti_di_contatto.xml
rename to src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml
index 13f595b..f2d8cf8 100644
--- a/src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_punti_di_contatto.xml
+++ b/src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_pdc.xml
@@ -9,7 +9,7 @@
Tipologia punti di contatto
- tipologia_punti_di_contatto
+ tipologia_pdc
email
diff --git a/src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_punti_di_contatto.cfg b/src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_punti_di_contatto.cfg
deleted file mode 100644
index 3a6eb08..0000000
--- a/src/iosanita/contenttypes/profiles/behaviors/taxonomies/tipologia_punti_di_contatto.cfg
+++ /dev/null
@@ -1,11 +0,0 @@
-[taxonomy]
-name = tipologia_punti_di_contatto
-title = Tipologia punti di contatto
-description = Il sistema di gestione contenuti basato su React
-default_language = it
-field_title = Punti di contatto
-field_description = Contatti degli organizzatori o della struttura organizzatrice dell''evento.
-field_prefix =
-taxonomy_fieldset = contatti
-is_single_select = false
-is_required = true
diff --git a/src/iosanita/contenttypes/profiles/default/registry/settings.xml b/src/iosanita/contenttypes/profiles/default/registry/settings.xml
new file mode 100644
index 0000000..2e64b24
--- /dev/null
+++ b/src/iosanita/contenttypes/profiles/default/registry/settings.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+ gallery 250:65536
+
+
+
diff --git a/src/iosanita/contenttypes/profiles/default/rolemap.xml b/src/iosanita/contenttypes/profiles/default/rolemap.xml
index cc2b989..a6f2dbb 100644
--- a/src/iosanita/contenttypes/profiles/default/rolemap.xml
+++ b/src/iosanita/contenttypes/profiles/default/rolemap.xml
@@ -54,5 +54,14 @@
+
+
+
+
+
+
+
diff --git a/src/iosanita/contenttypes/profiles/default/types.xml b/src/iosanita/contenttypes/profiles/default/types.xml
index d40b0ec..0f1598d 100644
--- a/src/iosanita/contenttypes/profiles/default/types.xml
+++ b/src/iosanita/contenttypes/profiles/default/types.xml
@@ -15,4 +15,7 @@
+
diff --git a/src/iosanita/contenttypes/profiles/default/types/Document.xml b/src/iosanita/contenttypes/profiles/default/types/Document.xml
new file mode 100644
index 0000000..70057d7
--- /dev/null
+++ b/src/iosanita/contenttypes/profiles/default/types/Document.xml
@@ -0,0 +1,25 @@
+
+
diff --git a/src/iosanita/contenttypes/profiles/default/types/Event.xml b/src/iosanita/contenttypes/profiles/default/types/Event.xml
index 27482ac..51c9000 100644
--- a/src/iosanita/contenttypes/profiles/default/types/Event.xml
+++ b/src/iosanita/contenttypes/profiles/default/types/Event.xml
@@ -26,7 +26,6 @@
-
diff --git a/src/iosanita/contenttypes/profiles/default/types/PuntoDiContatto.xml b/src/iosanita/contenttypes/profiles/default/types/PuntoDiContatto.xml
new file mode 100644
index 0000000..3ddecf8
--- /dev/null
+++ b/src/iosanita/contenttypes/profiles/default/types/PuntoDiContatto.xml
@@ -0,0 +1,105 @@
+
+
diff --git a/src/iosanita/contenttypes/profiles/default/types/Step.xml b/src/iosanita/contenttypes/profiles/default/types/Step.xml
index beb1331..57d49ef 100644
--- a/src/iosanita/contenttypes/profiles/default/types/Step.xml
+++ b/src/iosanita/contenttypes/profiles/default/types/Step.xml
@@ -24,6 +24,7 @@
+
@@ -50,7 +51,7 @@
-
+
diff --git a/src/iosanita/contenttypes/utils.py b/src/iosanita/contenttypes/utils.py
new file mode 100644
index 0000000..f86235a
--- /dev/null
+++ b/src/iosanita/contenttypes/utils.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+from iosanita.contenttypes.controlpanels.settings import IIoSanitaSettings
+from plone import api
+from plone.restapi.behaviors import IBlocks
+from uuid import uuid4
+from zope.interface import implementer
+
+import json
+import logging
+import six
+
+
+HAVE_REST_API_PRE_961 = False
+
+try:
+ # plone 6.0.11 with last plone.restapi>9.6.0
+ from plone.restapi.indexers import get_blocks_text
+ from plone.restapi.indexers import text_strip
+
+except ImportError:
+ # plone 6.0.10.1 with plone.restapi<9.6.1
+ HAVE_REST_API_PRE_961 = True
+ from plone.restapi.indexers import SearchableText_blocks
+
+
+logger = logging.getLogger(__name__)
+
+
+def get_settings_for_language(field):
+ values = api.portal.get_registry_record(
+ field, interface=IIoSanitaSettings, default=[]
+ )
+ if not values:
+ return []
+ if not isinstance(values, six.text_type):
+ return values
+ try:
+ json_data = json.loads(values)
+ except Exception as e:
+ logger.exception(e)
+ return values
+ lang = api.portal.get_current_language()
+ return json_data.get(lang, [])
+
+
+def create_default_blocks(context):
+ title_uuid = str(uuid4())
+ context.blocks = {title_uuid: {"@type": "title"}}
+ context.blocks_layout = {"items": [title_uuid]}
+
+
+def text_in_block(blocks):
+ @implementer(IBlocks)
+ class FakeObject(object):
+ """
+ We use a fake object to use SearchableText Indexer
+ """
+
+ def Subject(self):
+ return ""
+
+ def __init__(self, blocks, blocks_layout):
+ self.blocks = blocks
+ self.blocks_layout = blocks_layout
+ self.id = ""
+ self.title = ""
+ self.description = ""
+
+ if not blocks:
+ return None
+
+ fakeObj = FakeObject(blocks.get("blocks", ""), blocks.get("blocks_layout", ""))
+
+ if HAVE_REST_API_PRE_961:
+ return SearchableText_blocks(fakeObj)()
+ else:
+ blocks_text = get_blocks_text(fakeObj)
+ return text_strip(blocks_text)