Twig "is defined" always returning true I am trying to code defensively and check whether a field exists before accessing it:

{% if e.someField is defined %} {{e.someField}} {% endif %}


And I get a CException


  Craft\EntryModel and its behaviors do not have a method or closure named "someField".


Because is defined is always returning true.

Any clue what's wrong?
I believe I have a workaround and can (roughly) explain what's going on here.

First, the workaround:

Use array syntax to test the existence of your custom fields instead of object syntax.

{# This works #}
{% if entry['someField'] is defined %} ... {% endif %}


Using array syntax for your conditional will result as true if your field does exist and false if it does not. Using object syntax results in false positives where the conditional always returns true even if a field doesn't exist:

{# FALSE POSITIVES: These return true if a field doesn't exist #}

{% if entry.someField is defined %} ... {% endif %}
{% if attribute(entry, 'someField') is defined %} ... {% endif %}


I believe the false positive occurs using object syntax when the object has or is extending another object that uses a __call() method. Twig will test to see if it can find an attribute or a method.  In the case it can't find an attribute on an object, it will look for a method.  And if it can't find a method on the object, it will check for the existence of a __call() method and if the _call() method exists it returns true, creating the undesired result of also returning true for any variable that doesn't exist on an object that uses a __call() method.

I haven't dug into the code, but it seems that using the array syntax doesn't trigger a search for a potential method associated with the __call() behavior.



A couple related articles can be found on Straight Up Craft:


How to check if a variable or value exists using Twig
Testing if something exists: is defined, length, is not null, is not empty