Using Pebble version 3.0.6.
I need to check if value 'v' has a specific variable (translated to Java: if Object v has a specific property). Looking for something like
{% if v instanceof test.MyClass %}
...
{% endif %}
or
{% if v has myProperty %}
...
{% endif %}
Both are not available as far as i know. What is the best way to achieve this with Pebble?
UPDATE
Context:
- Using
strictVariables
=true
- property is not a boolean, String or Number
Not a builtin one but pebble allows you to write custom extensions. In java
instanceof
is an operator, which is something pebble allows you to write an extension for.We need 3 things to write a custom extension for an operator:
implements BinaryOperator
)extends BinaryExpression<Object>
)implements Extension
.Step 1
We define the operator as
instanceof
with a precedence of30
, according to java the precedence ofinstanceof
is the same as< > <= >=
, in pebble these operators have a precedence of30
so we use that. The node which evaluates this operation isInstanceofExpression.class
, which is the class we will create in step 2.Step 2
We now must write what the operator evaluates to, in this case we will return
true
ifleft instanceof right
. For the right part of this evaluation we use aString
which must contain the full qualifying name for the class, for example1 instanceof "java.lang.String"
which will returnfalse
, or1 instanceof "java.lang.Long"
which will returntrue
.An exception will be thrown if the
right
class cannot be found/loaded withClass.forName
.Step 3
We now must create an extension for Pebble, this is quite simple. We create an instanceof our custom
InstanceofOperator
and return that as binary operator:Alternatively instead of the entire Step 1 you can implement the
getBinaryOperators
method as such:Profit!
We can now add our custom extension with
.extension(new InstanceofExtension())
:The
Person
class which we are processing above is defined as such that it extendsEntity
. To prove the concept works we also have a classFruit
which does not extendEntity
. We test both of these different classes inv
:home.html we check if
v
which isPerson
orFruit
is an instance ofcom.mypackage.test.Entity
orcom.mypackage.test.Fruit
:The output is:
Comments
The "left not instanceof right" version is: