Context offers the ability to trigger a context based on another context, or even on the absence of another context. However, the ability to trigger on absence of another context only works one level deep.

For instance this works!

Context 1 -> active when path = blog/*
Context 2 -> active when Context 1 is active
Context 3 -> active when Context 1 is NOT active

But this won't

Context 1 -> active when path = blog/*
Context 2 -> active when Context 1 is active
Context 3 -> active when Context 2 is NOT active

Context 3 will always be active.

This is because Context 3 is evaluated in the same pass of context_condition_context->execute() as its blocker Context 2. Context 3 will be activated because Context 2 is not active when the evaluation pass starts.

context_condition_context->execute() has built in recursion to give these second level activations a chance to happen, but it will only turn contexts on, not turn them off again. Context 3 has already been activated by the first pass, and the recursion function cannot turn it off again.

Part of the problem is that the ->match() function is doing double duty for paths and for context conditions. While a page can only have one path, it could have multiple other conditions that need to be evaluated in a given order to be either true or false. It doesn't really make sense to use the same logic matching logic for both types of matches, or at least we need to handle negative matches differently. match() only returns true or false, and if false, we don't know whether something wasn't matched, or whether it WAS matched NEGATIVELY.

I don't know if there is only a documentation issue here (nested negative contexts don't work!) , or whether we need to refactor the code. I've played around with it today, and realized that I don't understand the context system enough to roll a patch right off today. If someone understands what I am saying and groks the code well, maybe they can take a shot at fixing this.

There are numerous workarounds for the current limitation. One can easily work around this without changing any code by simply making your negative contexts dependent on contexts farther up the tree (Context 3 depend on Context 1 not being active). Still, it's often nice to have a complexly synthetic positive context, and have a nice simple negative one that shows up when it's not there.

Comments

yareckon’s picture

See also #580324: Option to negate conditions for earlier discussion of negative contexts.

tekante’s picture

Status: Active » Fixed

Documentation has been updated in the help text for the context condition field via work on issue #1416260: Problem with context-filter. You may also want to look into #1421104: Fix process order of negated context conditions to see if the patch there may allow you to do what you are requesting.

Status: Fixed » Closed (fixed)

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