feesh
feesh

Reputation: 1248

Customize the search portlet in Plone for specific content types

I'm using the search portlet in certain areas of my website, but I'd like to restrict the results to only search for a specific content type: for example only search the news items, or only show Faculty Staff Directory profiles.

I know you can do this after you get to the @@search form through that "filter" list, but is there a way to start with the filter on, so that the "Live Search" results only show the relevant results (i.e. only news items or only profiles).

Upvotes: 3

Views: 700

Answers (2)

Ida
Ida

Reputation: 3965

I suspect you know it already, but just to be sure: You can globally define which types should be allowed to show up in searchresults in the navigations-settings of the controlpanel, and then export and include the relevant parts to your product's GS-profile-propertiestool.xml.

However, if you would like to have some types excluded only in certain sections, you can customize Products.CMFPlone/skins/plone_scripts/livesearch_reply, which already filters the types, to only show "friendly_types" around line 38 (version 4.3.1) and add a condition like this:

Edit: I removed the solution to check for the absolute_url of the context, because the context is actually the livesearch_reply in this case, not the current section-location. Instead the statement checks now, if the referer is our section:

REQUEST = context.REQUEST
current_location = REQUEST['HTTP_REFERER']
location_to_filter = '/fullpath/relative/to/siteroot/sectionId'
url_to_filter = str(portal_url) + location_to_filter
types_to_filter = ['Event', 'News Item']

if current_location.find(url_to_filter) != -1 or current_location.endswith(url_to_filter):
    friendly_types = types_to_filter
else:
    friendly_types = ploneUtils.getUserFriendlyTypes()

Yet, this leaves the case open, if the user hits the Return- or Enter-key or the 'Advanced search...'-link, landing on a different result-page than the liveresults have.

Update: An opportunity to apply the filtering to the @@search-template can be to register a Javascript with the following content:

(function($) {
    $(document).ready(function() {
        // Let's see, if we are coming from our special section:
        if (document.referrer.indexOf('/fullpath/relative/to/siteroot/sectionId') != -1) {
            // Yes, we have the button to toggle portal_type-filter:
            if ($('#pt_toggle').length>0) {
                // If it's checked we uncheck it:
                if ($('#pt_toggle').is(':checked')) {
                    $('#pt_toggle').click();
                }
                // If for any reason it's not checked, we check and uncheck it,
                // which results in NO types to filter, for now:
                else {
                    $('#pt_toggle').click();
                    $('#pt_toggle').click();
                }
                // Then we check types we want to filter:
                $("input[value='Event']").click();
                $("input[value='News Item']").click();
            }
        }
    })
})(jQuery);

Also, the different user-actions result in different, inconsistent behaviours:

  • Livesearch accepts terms which are not sharp, whereas the @@search-view only accepts sharp terms or requires the user to know, that you can append an asterix for unsharp results.

  • When hitting the Enter/Return-key in the livesearch-input, the searchterm will be transmitted to the landing-page's (@@search) input-element, whilst when clicking on 'Advanced search...' the searchterm gets lost.

Update: To overcome the sharp results, you can add this to the JS right after the if-statement:

// Get search-term and add an asterix for blurry results:
var searchterm = decodeURI(window.location.search.replace(new RegExp("^(?:.*[&\\?]" + encodeURI('SearchableText').replace(/[\.\+\*]/g, "\\$&") + "(?:\\=([^&]*))?)?.*$", "i"), "$1")) + '*';
// Insert new searchterm in input-text-field:
$('input[name=SearchableText]').val(searchterm);

Update2: In this related quest, Eric Brehault provides a better solution for passing the asterix during submit: Customize Plone search

Of course you can also customize the target of advanced-search-link in livesearch_reply, respectively in the JS for @@search, yet this link is rather superfluous UI-wise, imho.

Also, if you're still with Archetypes and have more use-cases for pre-filtered searchresults depending on the context, I can recommend to have a look at collective.formcriteria, which allows to define search-criteria via the UI. I love it for it's generic and straightforward plone-ish approach: catalogued indizi and collections. In contradiction to eea.facetednavigation it doesn't break accessibility and can be enhanced progressively with some live-search-js-magic with a little bit of effort, too. Kudos to Ross Patterson here! Simply turn a collection (old-style) into a searchform by changing it's view and it can be displayed as a collection-portlet, as well. And you can decide which criteria the user should be able to change or not (f.e. you hide the type-filter and offer a textsearch-input).

Upvotes: 4

SteveM
SteveM

Reputation: 6048

Watch how the query string changes when you use the filter mechanism on the @@search page. You're simply adding/subtracting catalog query criteria.

You may any of those queries in hidden fields in a search form. For example:

<form ...>
    ....
    <input type="hidden" name="portal_type" value="Document" />
</form>

The form on the query string when you use filter is complicated a bit by its record mechanism, which allows for some min/max queries. Simple filters are much easier.

Upvotes: 3

Related Questions