Please see issue #1402642: Facet API blocks not showing on "non search" pages.

The reason this is not working is that Search API is running the empty search to enable Facets in a block, so the search does not exist yet when facetapi_block_list_alter does its checks.

Not sure if this is a Facet API or Search API bug, but only way to get this (great!) feature working again right now is to patch Facet API to not remove blocks in facetapi_block_list_alter.

CommentFileSizeAuthor
#17 block-render-order-1417456-1.patch2.57 KBcpliakas

Comments

cpliakas’s picture

Hi atlea.

Thanks for posting. This is a tough issue in general because a query has to get the facet data.

Not sure if this is a Facet API or Search API bug, but only way to get this (great!) feature working again right now is to patch Facet API to not remove blocks in facetapi_block_list_alter.

This might work for your specific use case but it probably isn't a blanket solution. When the query is executed during the block rendering process then we will still have potential race conditions. Therefore there isn't a reliable solution unless the backend is smart enough to understand when a query will be executed and do so before the block rendering happens.

Thanks,
Chris

atlea’s picture

Hi Chris,

thanks for the quick reply. This is a tricky one. I've added to the module weight (to be on the safe side) and patched Facet API as this project was otherwise complete and the client wants it to go live, but I am very uncomfortable relying on such a hack.

Do you have any thoughts on how this could be solved?

Atle

cpliakas’s picture

I've added to the module weight (to be on the safe side) and patched Facet API as this project was otherwise complete and the client wants it to go live

Great! That's the most important thing. Although it is a "hack", I think it will remain stable for your client as the rendering order probably won't change for your specific site.

In terms of a long term solution, I would like to get some people who are a bit more involved in the the weeds of the block rendering system to weigh in here. Then we can try to flush out a reliable system. Definitely open for ideas if you come up with any.

Thanks,
Chris

atlea’s picture

Oops, I've missed your answer. My apologies!

Definitely open for ideas if you come up with any.

Can you perhaps start by explaining why you need hook_block_list_alter, as you do the same checks - as far as I can tell - in hook_block_view? If you removed hook_block_list_alter, what kind of issues would/could that cause?

I understand that block rendering order would still be important. There are probably a lot of situations where one would not be able to manipulate this to fit, but as far as the use case with Search API the block that triggers the search does not actually have any ouput - it is only used to run an empty search and can ble placed anywhere.

Here's my fix if anyone else needs it. Please forgive my modules name. ;)

function facetapi_fixer_module_implements_alter(&$implementations, $hook) {
  // Remove Facet APIs hook_block_list_alter. See #1417456: Facets on non-search Search API pages broken by facetapi_block_list_alter removing the block.
  if ($hook == 'block_list_alter') {
    unset($implementations['facetapi']);
  }
}
cpliakas’s picture

Can you perhaps start by explaining why you need hook_block_list_alter, as you do the same checks - as far as I can tell - in hook_block_view? If you removed hook_block_list_alter, what kind of issues would/could that cause?

Sure. The goal here is to prevent the hook_block_view() implementation from firing at all if the facet shouldn't be displayed. And just to clarify, it doesn't run twice, but it is smart enough to know if the visibility check has been run and calls the function if it hasn't. A good example here is the Context module which doesn't invoke hook_block_list_alter(), so it falls back to calling the visibility check in hook_block_view(). If we removed hook_block_list_alter() then the hook_block_view() implementation would be called on every page, however I am not sure if it's a big deal and wouldn't cause any issues I can think of. Since the searcher is a visibility setting, I was following the same pattern for other block visibility settings as illustrated by the block_block_list_alter() implementation.

Regarding your solution, cool little fix! Actually wasn't aware of hook_module_implements_alter(), so thanks for that! If this is a blocker for other people I am willing to eliminate Facet API's hook_block_list_alter() implementation, however I want to fully understand the issues of doing so first. Given that there is a nice little snippet than can force the issue, it seems we have a little leeway to discuss.

Thanks!
Chris

cpliakas’s picture

About the code snippet in #4, this might be a good candidate for the Facet API Extra or Facet API Bonus modules, where we could expose a setting to apply this fix. We can be a little more liberal in that module since it isn't tied directly to core.

Thanks,
Chris

atlea’s picture

Hi,

if you insist on doing the check in hook_block_list_alter, then this sounds like a nice idea. ;)

Please note: hook_module_implements_alter is cached in the registry, so other modules could not change this on the fly. Storing it in a variable is probably the best way to do this.

function facetapi_extras_module_implements_alter(&$implementations, $hook) {
  if ($hook == 'block_list_alter' && variable_get('facetapi_extras_search_in_block', FALSE)) {
    unset($implementations['facetapi']);
  }
}
cpliakas’s picture

Status: Active » Fixed

Marking as fixed since there is a viable workaround. If there is a hard requirement to add this to Facet API, then I am willing to re-open.

cpliakas’s picture

Status: Fixed » Closed (works as designed)

Changing status to something more appropriate.

giorgio79’s picture

Hey Chris,

How about setting the weight of the Facet API to a high value, and when the Search API Views block runs we set a php global and the Facet API block checks for that value? :)

iajay’s picture

I have created a module as you said and implemented the code mentioned above
After I enable the module
i see this error on non search page (on a node page)
Notice: Undefined index: field_tax_contributor in FacetapiAdapter->buildRealm() (line 826 of /home/iajay/www/pair/sites/all/modules/facetapi/plugins/facetapi/adapter.inc).
i see this type of message for each faceted search block
Am i missing something?
Do you need any other info
Should I open another issue for this?
Pls help
Regards
Ajjaykummar

cpliakas’s picture

giorgio79,

Thanks for the suggestion, but I am not sure how this would solve the problem. Since the hook_block_list_alter() implementation fires before hook_block_view(), then it really doesn't matter how heavily Facet API is weighted. That would only be a factor when code such as #7 is implemented and we are only dealing with the visibility checks in one hook. In addition, changing the entire module's weight is a little to brute-force-ish IMHO. The correct way to weight the implementation of a single hook is to do so in a hook_module_implements_alter() implementation so that other things aren't effected. I could very well be wrong here, so I would suggest testing some different things out and posting back. I'm sure others as well as my self would ber very interested in your findings.

iajay,

Unfortunately I don;t have the time to focus on this specific issues as I do have to prioritize some other things in order to get a 1.0 out. I would love to get some more information on any debugging you can to to push this forward.

Thanks,
Chris

iajay’s picture

Hi Chris
Thanks for the reply
I will see if I can find out anything
Regards
Ajjaykummar

atlea’s picture

giorgio79: Changing module weight does not help, even with the code from #4. Block weight does matter (render order), so one has to place the block generating the search above/before the facet blocks.

drunken monkey’s picture

Status: Closed (works as designed) » Active

Sorry for re-opening this, but I'd like you to reconsider this, Chris. As it is now, the Search API Views „Facets block“ is unusable in its intended form without a custom module. I agree that having hook_block_view()s being called for blocks that won't be displayed is suboptimal if it can be prevented, but currently we sacrifice correctness for performance (and even though it's only a small amount of correctness, I can't imagine we're gaining a considerable amount of performance), which is rarely a good idea.
Fixing this with a better context system in Drupal 8 would be great, but until then I don't suppose there's anything we can do to fix this (without implementing some system that would cost even more performance).

So I'd heavily vote for dropping facetapi_block_list_alter().
Otherwise I'll probably have to hook_module_implements_alter() it away in the Search API Views module, which wouldn't be too great a solution, either.

cpliakas’s picture

I will re-consider this, but I am not sure that it will solve the problem across the board. We will still have the same problem in that Search API's block has to be executed before Facet API's. Therefore is could work in some instances, but I also see other instances where it won't work. Maybe I am misunderstanding the flow, but I am willing to work with you to hack together a solution if it will fix the issue permanently and across search modules.

cpliakas’s picture

Version: 7.x-2.x-dev » 7.x-1.0-rc4
Status: Active » Needs review
StatusFileSize
new2.57 KB

Attached is a patch that rips out the hook_module_implements_alter() implementations. Can I get confirmation that this resolves the issues posted in this thread before I commit it?

webavant’s picture

With this patch, is it necessary to have the search API views block displaying in order to display the facets blocks? How do I get the search to occur on a different path than the current one? I would like to have facet blocks appear on any non-search page, regardless of whether or not my search API view block is there, but I am not sure that is possible without using the "facets block" views display style.

cpliakas’s picture

@webavant, in order for facets do be displayed, some sort of search has to be executed in order to get facet data to display. Apache Solr Search Integration has a "Show facets on non-search pages" feature which allows you to input paths that facets should be displayed on. See #1252648: Allow for enabling facet blocks on non-search pages for how this is implemented. For Search API (and someone correct me if I am wrong), I believe this type of query is executed when you use the "facets block" technique, so that is how you do it with that module.

All the patch does is move Facet API's check of whether a search was executed (and thus whether we have facet data to display) later in the page rendering process so that Search API has a chance to execute the query before those checks.

giorgio79’s picture

Applied patch, but I am still unable to show facet blocks before a search view block. (the facet blocks only appear in regions after the search view block)

The same facet blocks show fine before the search view when I use a page display instead of a block display.

cpliakas’s picture

Status: Needs review » Needs work

This is the problem I have with this issue. There is no fix in Facet API for this because Facet API simply can't display facet data when it hasn't been returned from the server. The patch is as good as it is going to get, and at this point the modules that fetch the data from the server really need to get it earlier.

stan turyn’s picture

The patch @ #17 solves this issue for me: http://drupal.org/node/1433008
Thanks, cpliakas!

cpliakas’s picture

Status: Needs work » Reviewed & tested by the community

Marking it as RTBC. If there are any additional issues surrounding this I am going to close immediately, because I believe that Facet API has done all that it can here.

Thanks,
Chris

cpliakas’s picture

Status: Reviewed & tested by the community » Closed (fixed)
trgreen17’s picture

I don't know if I should re-open this, so I won't. But I'm getting this error whenever I put a facet in a Panel:

Notice: Undefined index: field_consultant_title in FacetapiAdapter->buildRealm() (line 1056 of /home/admin/domains/dev-atr-ta.altaruminstitute.net/public_html/sites/all/modules/facetapi/plugins/facetapi/adapter.inc).

I'm using Facet API v7.x-2.x-dev, but do I need to run the patch in #17? Very confused.

I've tried everything: Solr is installed correctly, I've set up my server and two indexes and they all have green lights, and the index ran successfully. I've been at it all day so I figured now would be the time to ask. How can I fix this?

Also, the blocks don't appear when I assign them to regions at all. That's why I tried a Facet API block in a Panel, and that's when I saw the error.

Thanks, any help appreciated.

cpliakas’s picture

Hi trgreen23.

Check out out the issue at #1669918: Allow Panels to properly use Facet API blocks. Note that the 7.x-2.x branch is a nightly snapshot and will change fairly often, especially once active development on it begins. There are no guarantees that it won't break. It is definitely recommended to use the 7.x-1.0 release instead.

Thanks,
Chris

trgreen17’s picture

Chris,

Thanks very much for the help! I'll check out that issue.

Do you know why the facet blocks don't show up in my regions? I wanted to put them in Sidebar Second in Bartik, but I never could get them to appear, that's why I tried Panels. Just wondering if it's me, or if that's happened to anyone else.

Thanks again,
Tim

cpliakas’s picture

Tim,

It could be a lot of different issues. Based on another similar experience, I think there should be a development component to tell administrators why a facet doesn't show. This could be because of permissions, facet data wasn't returned by the search server, or a host of other configurations. If you open up another support request so we don't muddy this discussion, I would be happy to help debug :-).

Thanks,
Chris

trgreen17’s picture

Chris,

Again, thank you for your help. I'm traveling the next few days, but a colleague of mine who is having the same problem on another site will start a new issue about facet blocks not showing in regions. I asked her to create the issue later today. I'll follow the issue while traveling. Really appreciate your help with this, and we will help in any way we can.

Tim

cpliakas’s picture

Excellent! Thanks, and safe travels.

Chris

jwilson3’s picture

I came across a helpful post on stack overflow that explains very well how to put together a search page using search api views + panels, while still being able to use other panes (such as facetapi, and others) that depend on knowing about the view on the page, without being restricted to where you place the main view content in relation to the secondary blocks/panes on the panel page.

http://drupal.stackexchange.com/questions/8932/search-api-panels-display...

The trick is to use a Ctools Context display in your search view (instead of a Views pane, Block, Page or other type of typical Views display that you are probably familiar with and already know how to embed in a panel). This opened up a whole new level of knowledge and understanding between how Views and Panels can work together.

After following the instructions on that page, I was still getting the error mentioned in this issue (using facetapi-7.x-1.2).

After updating to 7.x-1.x-dev the problems went away. A big THANK YOU to everyone who has worked on this issue.

jwilson3’s picture

Version: 7.x-1.0-rc4 » 7.x-1.x-dev

Updating the version to reflect that the problem is resolved in dev.

itangalo’s picture

@jwilson3: As far as I can tell, the post you link to concerns Search API rather than Facet API. Or do I misinterpret things?

itangalo’s picture

@myself + jwilson3: The post actually requires using both search_api and facet_api, though facet_api isn't mentioned.

balintbrews’s picture

I was struggling with the same difficulties and the comments here have been pretty helpful for me to track down the reason. Unfortunately, none of the workarounds mentioned nor the 1.x-dev version worked for me (I'm using Search API Views and Panels), however I found an another way of working this problem around in the following issue: #1018420: Allow the possibility to control the order in which content is rendered. The hook implementation showed off in comment #15 works:

<?php
/**
 * Implements hook_ctools_plugin_post_alter().
 */
function MYMODULE_ctools_plugin_post_alter(&$plugin, &$info) {
  // Workaround to render facet blocks last, this actually sets all block
  // to render last.
  if ('content_types' == $plugin['plugin type'] && 'block' == $plugin['name']) {
    $plugin['render last'] = TRUE;
  }
}
?>

As the inline comment states, this code will change the rendering behavior of all blocks, so use it with caution. I have noticed that Facet API tries to do the same manipulation in facetapi_ctools_block_info(), but that sadly has no effect.

Maybe this will be useful for someone. I understand that there is no perfect way of fixing this problem.

Also, as a result of the referenced issue a new hook had been committed to Panels not long ago, which can be used to alter the rendering order of panes. Maybe this is something, that Facet API could utilize? If you think so, I will open a new feature request and I would love to help out moving that effort forward.