A PartiallyDeferredValue is one which does not need to be reconstructed separately when it isn't resolved in an expression.
Such that if I have a normal Map {'a': 'b'} for the key foo, given {{ foo }}, it needs to be reconstructed if it needs to be deferred: {% set foo = {'a': 'b'} %}{{ foo }}
For a PartiallyDeferredValue, it is always deferred so it won't get an explicit {% set %} tag reconstruction, and certain calls to the object may resolve.
So on its own, a PartiallyDeferredValue should be marked as a meta-context variable or specify a pyish serialization that will work without relying on a {% set %} tag prefix.
Giving a bit of a real example for what this means, at HubSpot, we when pre-rendering with eager execution we will pre-populate many variables onto the context. Some of these will be DeferredValueImpl some can be PartiallyDeferredValue. An example is the key request, which holds some HttpServletRequest data as documented here. Some of these values can be resolved when pre-rendering while others (such as query parameters) cannot. We mark it as a meta-context variable as it will never require reconstruction as we'll always pre-populate the context with its value. So deferring {{ request.query_dict.foo }} does not require a PrefixToPreserveState since request is a meta-context variable. However, if is aliased into another variable, for example:
We need a way to reconstruct config. If the request object isn't able to be serialized properly, we'll end up deferring the {{config.data...}} node (meaning we aren't able to process it at all). But if the request object defines a PyishSerialization that will always succeed, such as saying that it should just be represented with the variable name request, then we end up with an output like:
Config foo param: {{ request.query_dict.foo }}
As previously stated, we always pre-populate the context with the request variable so despite nothing in the reconstructed output explicitly defining what request is, it will have a value if we pass it through jinjava again with a re-populated context.
A
PartiallyDeferredValue
is one which does not need to be reconstructed separately when it isn't resolved in an expression. Such that if I have a normal Map{'a': 'b'}
for the keyfoo
, given{{ foo }}
, it needs to be reconstructed if it needs to be deferred:{% set foo = {'a': 'b'} %}{{ foo }}
For aPartiallyDeferredValue
, it is always deferred so it won't get an explicit{% set %}
tag reconstruction, and certain calls to the object may resolve.So on its own, a PartiallyDeferredValue should be marked as a meta-context variable or specify a pyish serialization that will work without relying on a
{% set %}
tag prefix.Giving a bit of a real example for what this means, at HubSpot, we when pre-rendering with eager execution we will pre-populate many variables onto the context. Some of these will be
DeferredValueImpl
some can bePartiallyDeferredValue
. An example is the keyrequest
, which holds someHttpServletRequest
data as documented here. Some of these values can be resolved when pre-rendering while others (such as query parameters) cannot. We mark it as a meta-context variable as it will never require reconstruction as we'll always pre-populate the context with its value. So deferring{{ request.query_dict.foo }}
does not require aPrefixToPreserveState
sincerequest
is a meta-context variable. However, if is aliased into another variable, for example:We need a way to reconstruct
config
. If therequest
object isn't able to be serialized properly, we'll end up deferring the{{config.data...}}
node (meaning we aren't able to process it at all). But if therequest
object defines aPyishSerialization
that will always succeed, such as saying that it should just be represented with the variable namerequest
, then we end up with an output like:As previously stated, we always pre-populate the context with the
request
variable so despite nothing in the reconstructed output explicitly defining whatrequest
is, it will have a value if we pass it through jinjava again with a re-populated context.