Monday, 9 July 2012

Search API, Facet API and Display Suite

Just spent most of the day tracking down a nasty little issue involving these three modules.

Let's face it Search API with Facet API (and all the Search API support modules) are brilliant, the core Search is very difficult to customise and you usually have to end up with nasty core hacks if you want to do anything clever.

Search API on the other hand is lovely, and Facet API is just great with almost everything extendible. And, of course, you can display search results as a view, which adds that level of delightfulness.

Display Suite is also awesome (I may have already mentioned this).

But if you have all three together - displaying search results and facet blocks on a Display Suite configured page, you may run into the problem of the facet blocks refusing to appear.

The reason is really simple: there are no facets to display.

But you say (well, I screamed in my head) I'm displaying search results through a view, I'm looking at them right now and I know they have facets.

I finally, eventually, lit upon this issue in Facet API which explains the problem but doesn't come up with any solid solution. The issue is that if the page displays the blocks before the search query has been run they will be empty because search results are needed before the facets can be calculated.

Simple? Yes. Solvable? Not easily. There's no way of telling Display Suite what order you want the blocks and content displayed (it would be a nice touch but not worth for just this problem, or maybe a way to defer content rendering of blocks to the end). There is talk of having the facet run the query if it's not been run, but that's in the future if it ever happens.

The solution is legal but ugly.

The way to ensure the query is run first is to do it in hook_init() in my case by rendering the view and saving it. Then adding the view to the output when required. Yucky but it works.

UPDATE: Typical really, what I hadn't done is fully explored the DS Extras module which allows Views pages to be configured. This is very handy but the issue above still remains.

1 comment:

Pontus Nilsson said...

Try this.

* Implements hook_ctools_plugin_post_alter().
function hook_ctools_plugin_post_alter(&$plugin, &$info) {
// Workaround to render blocks last.
if ('content_types' == $plugin['plugin type'] && 'block' == $plugin['name']) {
$plugin['render last'] = TRUE;