Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion castle/cms/browser/controlpanel/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@
<browser:page
name="search-exclusion-controlpanel"
for="Products.CMFPlone.interfaces.IPloneSiteRoot"
class=".search.ExclusionPanel"
class=".search.ExclusionPanelView"
permission="plone.app.controlpanel.Site"
layer="castle.cms.interfaces.ICastleLayer"
template="templates/search-exclusion.pt"
Expand Down
31 changes: 30 additions & 1 deletion castle/cms/browser/controlpanel/search.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,43 @@
from Products.Five import BrowserView
from plone import api

from castle.cms.interfaces import ISearchExclusionSettings
from castle.cms.widgets import SelectFieldWidget
from plone.app.registry.browser.controlpanel import ControlPanelFormWrapper
from plone.app.registry.browser.controlpanel import RegistryEditForm
from plone.z3cform import layout
from z3c.form import form


class ExclusionPanelForm(RegistryEditForm):
form.extends(RegistryEditForm)
schema = ISearchExclusionSettings

label = u'Search Exclusion Settings'

control_panel_view = '@@search-exclusion-controlpanel'

def updateFields(self):
super(ExclusionPanelForm, self).updateFields()
self.fields['items_to_exclude'].widgetFactory = SelectFieldWidget


class ExclusionPanelFormWrapper(ControlPanelFormWrapper):

def __init__(self, *args, **kwargs):
super(ExclusionPanelFormWrapper, self).__init__(*args, **kwargs)

class ExclusionPanel(BrowserView):
def get_excluded_content(self):
catalog = api.portal.get_tool('portal_catalog')
excluded_content = catalog(exclude_from_search=True)
return excluded_content


ExclusionPanelView = layout.wrap_form(
ExclusionPanelForm,
ExclusionPanelFormWrapper)


class PublishedWithPrivateParents(BrowserView):
def get_published_private_parent_content(self):
catalog = api.portal.get_tool('portal_catalog')
Expand Down
11 changes: 10 additions & 1 deletion castle/cms/browser/controlpanel/templates/search-exclusion.pt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,18 @@
i18n:domain="plone">
<metal:main metal:fill-slot="prefs_configlet_main">
<body>
<h1 class="documentFirstHeading" tal:content="view/label">View Title</h1>
<h4>Excluded content</h4>
This is a list of items with "Exclude From Search" selected in their properties. You can click on an item to navigate and edit that property if you'd like it to show up in search results.
<br><br>
<p tal:repeat="item view/get_excluded_content"><a href="${item/getURL}">${item/Title}</a></p>
<br><br>
<h4>Exclude by type</h4>
Content can be excluded from searches by type. Adding to the list below will make all content of that type not show up in search results.
<br><br>
<div id="layout-contents">
<span tal:replace="structure view/contents" />
</div>
</body>
</metal:main>
</html>
</html>
35 changes: 33 additions & 2 deletions castle/cms/browser/search.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from castle.cms.interfaces import ICrawlerConfiguration
from castle.cms.interfaces.controlpanel import ISearchExclusionSettings
from castle.cms.utils import get_public_url
from castle.cms.indexing import hps

Expand Down Expand Up @@ -51,10 +52,18 @@ def options(self):
}
]

registry = getUtility(IRegistry)
settings = registry.forInterface(ISearchExclusionSettings)
exclude_types_from_search = settings.exclude_from_searches
excluded_content = []

if exclude_types_from_search:
excluded_content = settings.items_to_exclude or []

ptypes = api.portal.get_tool('portal_types')
allow_anyway = ['Audio']
for type_id in ptypes.objectIds():
if type_id in ('Link', 'Document', 'Folder'):
if type_id in excluded_content:
continue
_type = ptypes[type_id]
if not _type.global_allow and type_id not in allow_anyway:
Expand All @@ -68,7 +77,6 @@ def options(self):
})

additional_sites = []
registry = getUtility(IRegistry)
settings = registry.forInterface(ICrawlerConfiguration, prefix='castle')
if hps.is_enabled() and settings.crawler_active and settings.crawler_site_maps:
result = hps.get_index_summary(hps.get_index_name(), dict(field="domain"))
Expand Down Expand Up @@ -164,6 +172,9 @@ def __call__(self):
query['has_private_parents'] = False
query['exclude_from_search'] = False

allowed_types = self.get_allowed_types(query)
query['portal_type'] = allowed_types

try:
page_size = int(self.request.form.get('pageSize'))
except Exception:
Expand All @@ -178,6 +189,26 @@ def __call__(self):
return self.get_hps_results(page, page_size, query)
else:
return self.get_results(page, page_size, query)

def get_allowed_types(self, query):
# If a filter tab is selected, use that portal type only
portal_types = query.get('portal_type')
if portal_types is not None:
return portal_types

# Otherwise, use all non-excluded portal types
registry = getUtility(IRegistry)
settings = registry.forInterface(ISearchExclusionSettings)
exclude_types_from_search = settings.exclude_from_searches
excluded_content = []

if exclude_types_from_search:
excluded_content = settings.items_to_exclude or []

ptypes = api.portal.get_tool('portal_types')
allowed_types = [type for type in ptypes.objectIds() if type not in excluded_content]

return tuple(allowed_types)

def get_results(self, page, page_size, query):
# regular plone search
Expand Down
4 changes: 4 additions & 0 deletions castle/cms/configure.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@
component=".vocabularies.ProvidesTitleSummaryLeadImageVocabularyFactory"
name="castle.cms.vocabularies.ProvidesTitleSummaryLeadImage"
/>
<utility
component=".vocabularies.SiteTypesVocabulary"
name="castle.cms.vocabularies.SiteTypes"
/>
<utility
component=".vocabularies.EmailTemplateVocabulary"
name="castle.cms.vocabularies.EmailTemplates"
Expand Down
1 change: 1 addition & 0 deletions castle/cms/interfaces/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from .controlpanel import ISiteConfiguration
from .controlpanel import ISiteSchema
from .controlpanel import ISearchSettings
from .controlpanel import ISearchExclusionSettings
from .controlpanel import ISlideshowSettings
from .controlpanel import ISocialMediaSchema
from .layers import ICastleLayer
Expand Down
16 changes: 16 additions & 0 deletions castle/cms/interfaces/controlpanel.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,22 @@ class ISlideshowSettings(Interface):
required=False)


class ISearchExclusionSettings(Interface):
exclude_from_searches = schema.Bool(
title=u"Exclude content type from searches",
default=False
)

items_to_exclude = schema.List(
title=u'Content To Exclude',
required=False,
default=[],
value_type=schema.Choice(
vocabulary='castle.cms.vocabularies.SiteTypes'
)
)


class IAdjustableFontSizeSettings(Interface):
font_size_small = schema.TextLine(
title=u"Small font size",
Expand Down
4 changes: 4 additions & 0 deletions castle/cms/profiles/3014/metadata.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0"?>
<metadata>
<version>3014</version>
</metadata>
5 changes: 5 additions & 0 deletions castle/cms/profiles/3014/registry/registry.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0"?>
<registry xmlns:i18n="http://xml.zope.org/namespaces/i18n"
i18n:domain="plone">
<records interface="castle.cms.interfaces.ISearchExclusionSettings" />
</registry>
17 changes: 16 additions & 1 deletion castle/cms/upgrades.zcml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
profile="castle.cms:default"
/>


<genericsetup:registerProfile
name="3003"
title="CastleCMS upgrade to 3003 profile"
Expand Down Expand Up @@ -192,4 +191,20 @@
profile="castle.cms:default"
/>

<genericsetup:registerProfile
name="3014"
title="CastleCMS upgrade to 3014 profile"
directory="profiles/3014"
description=""
provides="Products.GenericSetup.interfaces.EXTENSION"
/>
<genericsetup:upgradeStep
title="Upgrade CastleCMS to 3014"
description="Adds ability to exclude dexterity content from search"
source="*"
destination="3014"
handler=".upgrades.upgrade_3014"
profile="castle.cms:default"
/>

</configure>
2 changes: 2 additions & 0 deletions castle/cms/upgrades/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,5 @@ def upgrade_3011(site, logger=CASTLE_LOGGER):


upgrade_3012 = default_upgrade_factory('3012')

upgrade_3014 = default_upgrade_factory('3014')
17 changes: 17 additions & 0 deletions castle/cms/vocabularies.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,23 @@ def __call__(self, context):
LocationsVocabulary = LocationsVocabularyFactory()


@implementer(IVocabularyFactory)
class SiteTypesVocabularyFactory(object):

def __call__(self, context):
site = getSite()
portal_types = getToolByName(site, "portal_types")
types = portal_types.listContentTypes()
terms = []
for type in types:
terms.append(SimpleVocabulary.createTerm(type, type, type))

return SimpleVocabulary(terms)


SiteTypesVocabulary = SiteTypesVocabularyFactory()


@implementer(IVocabularyFactory)
class MimeTypeVocabularyFactory(object):

Expand Down