This package provides multilingual search indexes for easy Haystack integration with django CMS.
After installing django-cms-facetsearch through your package manager of choice, add cms_facetsearch to your INSTALLED_APPS. That’s it.
For setting up Haystack using solr as needed for faceting, please refer to their documentation.
You can customize what parts of a CMSPlugin end up in the index with two class attributes on CMSPlugin subclasses:
a list of field names to index.
if True, the index renders the plugin and adds the result (sans HTML tags) to the index.
Add the Django Cms Faceted Search apphook to a page.
django-cms-search provides a couple of useful helpers to deal with multilingual content.
A SearchIndex that adds a prepare_translated method and a faceted language field to the search index. An example for when this is useful is the app hook infrastructure from django CMS. When a model’s get_absolute_url() uses a url pattern that is attached to an app hook and there is a own model for titles per language the URL varies depending on the language or ay translated strings. A usage example:
# models.py
class Story(models.Model):
pub_date = models.DateTimeField(default=datetime.datetime.now)
class StoryTitle(models.Model):
story = models.ForeignKey(Story)
language = models.CharField(max_length=15, choices=settings.LANGUAGES)
title = models.CharField(max_length=255)
slug = models.SlugField()
def _get_absolute_url(self):
return ('%sstory_detail' % self.language, (), {
'year': self.story.pub_date.strftime('%Y'),
'month': self.story.pub_date.strftime('%m'),
'day': self.story.pub_date.strftime('%d'),
'slug': self.slug
})
get_absolute_url = models.permalink(_get_absolute_url)
# search_indexes.py
from models import StoryTitle
from haystack import indexes, site
from cms_facetsearch.indexes import TranslationIndex
class StoryTitleIndex(TranslationIndex):
text = indexes.CharField(document=True, use_template=True)
title = indexes.CharField(model_attr='title')
url = indexes.CharField(stored=True)
def prepare_translated(self, obj, language):
data = super(StoryTitleIndex, self).prepare_translated(self, obj, language)
data['url'] = obj.get_absolute_url()
return data
site.register(StoryTitle, StoryTitleIndex)
Note
Note
django CMS monkeypatches django.core.urlresolvers.reverse() to enable language namespaces. To ensure that this monkeypatching happens before haystack autodiscovers your indexes, your search_sites.py should look somewhat like this, will be fixed to work properly in django-cms 2.2:
from cms.models import monkeypatch_reverse
import haystack
monkeypatch_reverse()
haystack.autodiscover()
A cms_facetsearch:TranslationIndex subclass that renders plugins from for a specific language as a document CharField for all placeholdes related to the model. A usage example:
# models.py
from cms.models.fields import PlaceholderField
# or from djangocms_utils.fields import M2MPlaceholderField
class Story(models.Model):
pub_date = models.DateTimeField(default=datetime.datetime.now)
placeholder = PlaceholderField()
class StoryTitle(models.Model):
story = models.ForeignKey(Story)
language = models.CharField(max_length=15, choices=settings.LANGUAGES)
title = models.CharField(max_length=255)
slug = models.SlugField()
# search_indexes.py
from models import StoryTitle
from haystack import indexes, site
from cms_facetsearch.indexes import PluginIndex
class StoryTitleIndex(PluginIndex):
title = indexes.CharField(model_attr='title')
url = indexes.CharField(stored=True)
def get_placeholders(self, obj, language):
return [obj.story.placeholder]
site.register(StoryTitle, StoryTitleIndex)
The current development version of django-cms-facetsearch supports haystack-celery so you can update the index when saving the model you want to index or a plugin related to the model you want to index.
All you need to do to activate this is to set up django-celery and add haystack_celery to INSTALLED_APPS.
Finding the model related to the plugins requires a extara hook ``get_index_instance_from_plugin``to query for the instance. The search_index for the Django CMS pages and cmsplugin-blog already has this method defined.
# models.py from cms.models.fields import PlaceholderField # or from djangocms_utils.fields import M2MPlaceholderField class Story(models.Model): pub_date = models.DateTimeField(default=datetime.datetime.now) placeholder = PlaceholderField() class StoryTitle(models.Model): story = models.ForeignKey(Story) language = models.CharField(max_length=15, choices=settings.LANGUAGES) title = models.CharField(max_length=255) slug = models.SlugField() from models import StoryTitle from haystack import indexes, site from cms_facetsearch.indexes import PluginIndex class StoryTitleIndex(PluginIndex): title = indexes.CharField(model_attr='title') url = indexes.CharField(stored=True) def get_placeholders(self, obj, language): return [obj.story.placeholder] def get_index_instance_from_plugin(self, instance, **kwargs): try: return StoryTitle.objects.get(story__placeholder__cmsplugin=instance) except StoryTitle.DoesNotExist: return None site.register(StoryTitle, StoryTitleIndex)
Default: :boolean:`True`
This setting can be used to disable registering of django-cms Titles with a cms_facetsearch:PluginIndex if you use another search solution for cms core.
Default: :dict:`{}`
This setting can be used to change the labels for model selection in the search form Eg. CMS_FACETSEARCH_LABEL_OVERRIDES={‘news.storytitle’: gettext(‘Stories’) }