A very common paradigm is to want type-specific verticals and behaviors. CCK, taxonomy, books and others can add facets that are type-specific. This patch adds a checkbox to each facet block configuration form asking if the block should be type dependent. If checked, the facet block only shows if the type:book or type:story filter is selected first. This is very convenient for our new in-the-well browsing facets. It also lets you enable lots and lots of facet blocks and not worry about running out of real estate because a large number of the blocks can be type dependent and only show when the requisite type filter has been selected. Committing the attached patch. Will leave open for review for some time.
| Comment | File | Size | Author |
|---|---|---|---|
| #19 | Screen shot 2011-05-15 at 4.16.33 PM.png | 158.1 KB | cpliakas |
| #6 | apachesolr_contextual_facets.patch | 6.06 KB | socki |
| #4 | type_filter_module_fix.diff | 1.24 KB | robertdouglass |
| #3 | type_hierarchy_refactor.patch | 3.57 KB | robertdouglass |
| #1 | type_dependent_blocks.patch | 6.99 KB | robertdouglass |
Comments
Comment #1
robertdouglass commentedComment #2
robertdouglass commentedComment #3
robertdouglass commentedA followup that factors the visibility logic into a new function in the apachesolr.module for reusability. Committing attached patch.
Comment #4
robertdouglass commentedFollowup bug fix: $module was hardcoded.
Comment #6
socki commentedHere is a consolidated patch file which packages together all three of the above fixes into a single patch. This has been tested against the 6.x-1.x RC3 version of the module.
Comment #7
SergeyR commentedthe one aspect leaved to be solved
if you uncheck type facet -it's good other depended facets filters automatically to be unchecked
i.e. if you switch your searching from "news" to "products" -filters by "type of news" is become useless -and more.. you cannot uncheck it cause this block become unvisible. Crazy situation )))
the another thing- to expand idea of "type dependent facet blocks" to "any previous filter choiced facet block"
i.e. the only subset of objects has some kind of feature -i don't want to see this feature untill appropriate filter of that subset is choosed.
PS just found bad example from whitehouse.gov
1. I dont like to see "Filter by Blog Category" untill "Blog post" from "Filter by type" checked
2. I dont like "White house" be checked as "Blog Category" , as soon as i unchecked "Blog post" as "Type"
Comment #8
pwolanin commentedComment #9
pwolanin commentedmoving to Facet API queue for future consideration.
Comment #10
cpliakas commentedThis seems very possible, and not that difficult to implement once we finish the task at #1147510: Rework logic to initialize all facet builds earlier in the application flow. Ideally there should be a hook that prevents the facet from rendering so other projects can add conditions such i.e. "only render this facet if content type x is active".
If we take a look at the FacetapiAdapter::addFacetsFilters() function, it would be simple to invoke the hook to allow modules to prevent the query type plugins from firing. That way the backend won't process the data. On the rendering side, we would have to take a cached return value from the hook and prevent the facet from rendering in FacetapiAdapter::buildRealm().
Switching to a task, because I think this is important.
Comment #11
Anonymous (not verified) commentedLooking forward to this as apachesolr module is now dependent on the facetapi so I've lost the ability to easily control block visibility according to type.
For the moment, I'm just using some PHP code in my block visibility settings:
Comment #12
pwolanin commentedSo a discussion Chris and I has was whether this should be generic functionality (a block can depend for visibility on any filter being active) or focus just on the content type use case.
Making a generic version is going to be harder to have a comprehensible UI.
Comment #13
cpliakas commentedI think it would be simple to make the framework for the functionality generic, however the implementations would have to be aware of the field they are dependent on. I cannot think of a non Content Type implementation off the top of my head, but the framework should be generic enough to at least support other use cases.
Comment #14
pwolanin commentedDoes this affect the facet fetching or only rendering code?
The prior apachesolr implementation had this sort of comment:
So, I think the corresponding effect would be in the execute() method of the FacetapiQueryType plugin there would have to be some way to get from the global (not realm) settings all the facets that have to be active in order for execute() to add the facet params? Not sure how to get a facet just by name. Is this functionality specific to the block realm?
Looking in the code, there is a comment about
facetapi_enabled_facets_get()on line 265 of the module, but I don't see that it exists.Perhaps add a drupal_static() to facetapi_get_facet_info() so we can call it repeatedly?
Comment #15
cpliakas commentedMy goal is to abstract the process so the modules can implement something like a hook_facetapi_suppress_facet() which will simply prevent the query type plugin from being added in FacetapiAdapter::addActiveFilters (hence one of the reasons why #1147510: Rework logic to initialize all facet builds earlier in the application flow was helpful) . If no query type plugin is added, this takes care of both the params set in the backend and the display of the facet. I think I have to modify the flow slightly in the FacetapiFacetProcessor::__construct() method to skip the initialization routines if the facet doesn't have a query type plugin, but the code is pretty close as it is.
In short, the facet will still be enabled, but the backend won't fetch facet data nor will the rendering mechanism display the facet.
Comment #16
cpliakas commentedAs a side note, setting it up this way allows for extensibility for contributed modules to add whatever dependency logic they want. Toying with the idea of not having the type dependency in Facet API and separating it out to another module.
Comment #17
cpliakas commentedSo just a note here, after playing around with this for an hour on the train, I settled on a system that works really well. I am ditching the idea of implementing a hook as well as the idea of separating this functionality out into another module. The concept of dependency plugins works extremely well and allows developers to add whatever dependency logic they need. Core Facet API will come with two dependency plugins, content type and role. This way you can have a dependency on the active content type, and you can even have a dependency to say "only users with this role can use this facet.".
The additional benefit of this approach is if the dependencies aren't met then the server doesn't even process that facet. Therefore this does more than just hide the data. I set up the dependency-551620 feature branch to develop this functionality since it is a larger change.
Comment #18
pwolanin commentedSounds like good progress.
Comment #19
cpliakas commentedDevelopment is progressing well, and the plugin system seems to be the right way to solve this. Attached is a screenshot of where we are at now. Any facet that has one or more dependency plugins associated with it will have a new configuration form to edit the dependencies. Each plugin can provide settings that are usually contained in a vertical tab. This will allow for multiple plugins to be chained together in a scalable way from the UI perspective.
Comment #20
pwolanin commentedTook me a second to grasp the middle radio's text, but that right there probably solves 90% of use cases, especially since in D7 taxonomy term reference is a field too.
Comment #21
cpliakas commentedMarking as fixed, although that second option you mention is not implemented yet. The reason we need the facet definition to have the field information in order to see what bundles reference it. The dependency system has been merged back into the 7.x-1.x branch, and the two remaining issues are listed below:
#1158592: Add an update function to avoid undefined index errors from dependency system
#1158594: Implement the "referenced" dependency setting
Comment #23
SergeyR commentedplease look at endeca "precedence rules"
as i understood this is a possibility to manage facet dependencies in general case
and in fact the actual dependencies pligins are just limited to parenth's facet that is content type
my vision -it must something like this:
"at least one of the selected content type must be active" >>>"all selected filters type must be active"
or
"all selected value of filters type must be active"
second approach just eliminate queries to search server with possible zero count facets -but hard for configuration interface -anyway first approach is working-see next:
i.e. -you have content type (read: value of filter1) " news" with field "date" (filter2) and "goods" (another value of filter1) with "manufacturer" (filter3)
and you have idea to select date as soon as news are selected and to select manufacturer as soon as goods are selected
make dependecies filter1>filter2 and filter1>filter3
as soon as you select any value of filter1 -both filter2 and filter3 will be activated -but if value of filter1 will be news -filter2 will work but filter3 will have zero count and appropriate block will be invisible -anyway the goal achieved
PS
sytem must to disactivate children's filters as soon as parenth's filters are disactivated
Comment #24
cpliakas commentedOpened a new issue for this at #1218714: Add more advanced filter and dependency settings. Let's continue discussions there.