Доступ к текущей области в собственном теге в DotLiquid

Когда я зацикливаюсь на IEnumerable в своем шаблоне DotLiquid

{% for block in Blocks -%}

    // this works
    {{ block.Structure }}

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

{% endfor -%} 

Я могу визуализировать член напрямую через block.Structure, но я не знаю, как получить доступ к этому объекту структуры в моем собственном классе тегов 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 = ?

person Marc    schedule 05.10.2012    source источник


Ответы (1)


Вы можете использовать объект context, переданный вашему методу RenderObject.Render. На Context есть индексатор, который преобразует имена переменных в переменные. (И тег For помещает переменную цикла, то есть block в вашем примере, в context.)

Остается проблема с получением имени переменной ("block.Structure"). К счастью, именно для этого и предназначена переменная markup, переданная в RenderObject.Initialize.

Итак, это должно работать:

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];
    }
}
person Tim Jones    schedule 06.10.2012
comment
О, да, вы правы, но это объект DropProxy, и мне действительно нужно проверить, реализует ли проксируемый объект определенный интерфейс моего приложения. Есть ли способ получить доступ к объекту? Потому что я знаю важность прокси для безопасности в шаблоне, но было бы здорово получить доступ к реальному объекту в моем теге RenderObject? - person Marc; 06.10.2012
comment
Это другой вопрос :) Нормальным решением будет создание собственного класса, производного от Drop, который позволит вам реализовать любые интерфейсы, которые вам нравятся. Или вы можете создать собственную версию DropProxy и зарегистрировать ее в Template.RegisterSafeType(myType, x => new MyDropProxy(x)). - person Tim Jones; 10.10.2012
comment
Большое спасибо, я придумал изменить сборку DotLiquid и зарегистрировать свое приложение, чтобы я мог оттуда получить доступ к внутренностям DotLiquid - потому что у вас уже есть метод .GetObject() в вашем DropProxy... :) - person Marc; 10.10.2012