[Grok-dev] view predicates in Grok?

Martijn Faassen faassen at startifact.com
Mon Jan 4 15:08:29 EST 2010


Hey Paul,

This is extremely helpful, thank you very much (and to Chris for helping 
him). It becomes easier to talk about it.

Do I understand correctly that a predicate function's return value is 
what is being checked here? I.e. in this case:

    grok.predicate(foo="some value")

a predicate 'foo' is looked up and called with context and request, and 
if it returns "some value" then the predicate applies.

Paul Wilson wrote:
[snip]
> It's also worth noting that the BFG system allows you to define a list of
> predicate functions that are also involved in the view selection process.
> For example, you can define a function:
> 
> def predicate1(request, context):
> 	if request.header['foo'] == 'bar' and
> 	   context.foo == 'bar':
> 		return True
> 
> and specify it as follows:
> 
> class FooView(grok.View):
> 	grok.context(...)
> 	grok.name(...)
> 	grok.predicate(containment=MyContainer,
> 		       custom_predicates=[predicate1,
> 		                          predicate2,
> 					  predicate3])
> 	...
> 
> This allows any kind of logical spelling to be given as part of the view
> matching process, inside or outside of the domain of requests and contexts.
> Want your views to be selected based on prevailing weather conditions? No
> problem!
> 
> I did entertain the idea of allowing the provided predicates to be used within
> your predicate function:
> 
> class FooView(grok.View)
> 	grok.context(...)
> 	grok.name(...)
> 	grok.predicate.containment(MyContainer)
> 	grok.predicate.custom_predicates=predicate1 # Can also be a sequence
> 	...
> 
> def predicate1(request, context):
> 	if grok.predicate.request_method('POST') and
> 	   context.foo == 'bar':
> 		return True
> 
> Using some deep Python magic this is probably possible, but it is
> unnecessary magic;
> the request API is simple enough anyway for you to be able to feasibly
> recreate any of
> the predicate's work anyway! However, splitting the predicates out
> like this would allow us
> to use martian's built in checkers to perform validation on predicates
> in a natural way. Also,
> we could inherit predicates from parent views too:
> 
> class POSTView(grok.View):
> 	grok.predicate.request_method('POST')
> 
> Any thoughts?

Are the "standard" BFG predicates registered globally? Would it make 
sense to register custom predicates through Martian, perhaps with a 
decorator like this?

@grok.view_predicate('predicate1')
def predicate1(request, context):
    ...

This might also make it easier for predicates to reuse each other, as 
the decorator would just help to register the predicate itself and not 
alter the function's behavior otherwise. Validation on grok.predicate 
could then also be done pretty easily.

Or is it not good to be global here and better to register this stuff 
locally? The main issue I can see is naming clashes as there is only a 
single namespace available, but that may be acceptable.

Regards,

Martijn



More information about the Grok-dev mailing list