Search code examples
c#dotliquid

Access current scope in own tag in DotLiquid


When I loop though an IEnumerable in my DotLiquid template

{% for block in Blocks -%}

    // this works
    {{ block.Structure }}

    // this doesn't
    {% RenderObject block.Structure %}

{% endfor -%} 

I can render a member directly via block.Structure but I don't know how to access this Structure object in my own tag class RenderObject:

public class RenderObject : Tag
{
    private string _tagName;
    private string _markup;

    public override void Initialize(string tagName, string markup, List<string> tokens)
    {
        _tagName = tagName;
        _markup = markup.Trim();
        base.Initialize(tagName, markup, tokens);
    }

    public override void Render(Context context, TextWriter result)
    {
        // HERE COMES THE QUESTION
        // How to access the block.Structure object here?
        var structure = ?

Solution

  • You can use the context object that's passed in to your RenderObject.Render method. There's an indexer on Context that resolves variable names into variables. (And the For tag places the loop variable, i.e. block in your example, into the context.)

    The remaining problem is getting the variable name ("block.Structure"). Fortunately, that's exactly what the markup variable, passed in to RenderObject.Initialize, is there for.

    So this should work:

    public class RenderObject : Tag
    {
        private string _tagName;
        private string _markup;
    
        public override void Initialize(string tagName, string markup, List<string> tokens)
        {
            _tagName = tagName;
            _markup = markup.Trim();
            base.Initialize(tagName, markup, tokens);
        }
    
        public override void Render(Context context, TextWriter result)
        {
            var structure = context[_markup];
        }
    }