I needed to make some contexts exclusive of each other, but couldn't come up with inclusion criteria that worked consistently. Instead I wrote a reaction plug-in that sets the selected contexts to false when it is triggered.

I'm still trying to understand the inner workings of the 3.x branch and my solution feels like more of a hack than a true solution, so I'm hoping to get some feedback on better methods of accomplishing this. My initial attempt was to make contexts within a tag group exclusive, but I wasn't able to figure out if that's possible (this is why my plugin is called exclusive for now, it should be called disable_context instead).

My reaction plugin:


/**
 * Define a context as exclusive by disabling selected contexts.
 */
class career_custom_context_reaction_exclusive extends context_reaction {

 function options_form($context) {
   $defaults = $this->fetch_from_context($context);
   // Get a list of all contexts to use in the checkboxes element
   $values = context_context_list();
   ksort($values);
   
   return array(
     'exclusions' => array(
      '#title' => t('Contexts to exclude'),
      '#decription' => t('Select the contexts that should be disabled'),
      '#type' => 'checkboxes',
      '#multiple' => TRUE,
      '#options' => $values,
      '#default_value' => $defaults['exclusions'],
     ),
   );
  }

  function execute() {
    $contexts = $this->get_contexts();
    $processed = array();
    foreach ($contexts as $context) {
      $values = $this->fetch_from_context($context);
      foreach ($values['exclusions'] as $exclusion) {
        if ( ($exclusion) && context_isset('context', $exclusion) && (!in_array($exclusion, $processed))) {
          context_set('context', $exclusion, FALSE);
        }
      }
      // Add the current context to $processed so it is not removed by other contexts
      $processed[] = $context->name;
    }
  }
}
CommentFileSizeAuthor
#13 context_disable_context.zip2.18 KBlucio.ferrari

Comments

yhahn’s picture

Wow. Interesting. Will think about this.

indytechcook’s picture

@tauno, which hook do call the execute from?

does this really unset a active context? awesome!

context_set('context', 'context_name', FALSE);
te-brian’s picture

I would be interested in where this leads.

In Context 2.0, you could exploit the nature of how the contexts were tested by having a number of attribute-value contexts that shared the same attribute. The last context in the loop would be the one that 'wins'.

For example:

attribute - value
---------------------
page - front
page - donate
page - landing_page
page - default

With these contexts you could set up a default for all pages (using sitewide), and then for the three special case pages you could provide completely different blocks and other settings.

In Context 3.0, if you make a sitewide context, there is no way that I can see to override it.

I like the idea of these 'exclusive' contexts. My ideal UI would be a tag group who is set to 'exclusive' mode and the contexts in that group would have a weight (drag and drop). Either the first or last match (whichever makes logical sense) would load and all the other contexts in that tag group would be ignored.

budda’s picture

@te-brian How is the order of all matching contexts selected in v2.0 ?

tim.plunkett’s picture

Wasn't about to get this working.
context_isset() wasn't returning true for contexts that should have been set, and context_active_contexts() was returning an empty array.
I messed around with module weights and it seemed to fix part of that.

yhahn’s picture

Version: 6.x-3.0-beta3 » 6.x-3.x-dev
Assigned: Unassigned » yhahn
Priority: Normal » Critical

On my list.

yhahn’s picture

Status: Active » Closed (duplicate)
webflo’s picture

hi, i think its not a 100% dup. its very usefull in some cases. i've implemented this in a small module. its nice if you want to override some context. http://github.com/webflo/context_disable_context

webflo’s picture

Priority: Critical » Normal
Status: Closed (duplicate) » Needs review

change status.

socialnicheguru’s picture

subscribing

shaundychko’s picture

@webflo: thank you! Works great!

lucio.ferrari’s picture

@webflo:

Great! Exactly what I was looking for, thank you!

About the 'TODO' in the plugin's code, what about inserting this?

<?php
function options_form($context) {
    $defaults = $this->fetch_from_context($context);
    $values = context_context_list();
    unset($values[$context->name]);     //<----- THIS seems to do the job
    ksort($values);
    
    // TODO: exclude current context from $values
[...]
?>

IMHO, this plugin deserves to be listed amongst Context Plugin Extras (where I uselessly looked for such).

lucio.ferrari’s picture

StatusFileSize
new2.18 KB

Webflo's module here.

brad.bulger’s picture

i agree, this is usefully different from adding a context exclusion condition. for instance, it lets Feature modules define a context that turns off some other context, instead of having to additionally update that context's conditions when the feature is enabled. (unless there's some other way to do that....)

although, i guess because it's a reaction, it happens too late to affect other contexts. if context B is dependent on context A being enabled or not, and context C uses this plugin to disable context A, context B still acts as if A was enabled. i think that's just how things work, but maybe someone else will have some ideas.

it'd be nice to see this either added to Context Extras or set up as its own project - maybe for 7.x?

guillaumev’s picture

Status: Needs review » Closed (fixed)

I took the initiative of creating this as a project of its own. This can be viewed here:
http://drupal.org/project/context_disable_context

webflo > I can give you maintainers access if you want, just let me know.

Closing this issue, please add any further issue in the project's issue list.

tim.plunkett’s picture

Status: Closed (fixed) » Fixed

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.