Как передать HTML-фрагмент (в качестве делегата?) Декларативному Razor Helper? - PullRequest
4 голосов
/ 12 августа 2011

Я пишу некоторые декларативные Razor Helpers (с использованием синтаксиса @helper) для использования с Umbraco 4.7 , который теперь поддерживает механизм представления Razor (хотя я мог бы представить это применяется в равной степени к WebMatrix или ASP.NET MVC). Все они работают нормально. Тем не менее, я хотел бы сделать их немного более гибкими, чтобы я мог передать им фрагмент HTML, который можно «обернуть» вокруг вывода (но только при наличии вывода). Например, у меня есть помощник (очень упрощенный), который может генерировать HTML-ссылку из некоторых параметров:

@helper HtmlLink(string url, string text = null, string title = null, 
string cssClass = null, bool newWindow = false)
{
    if (!String.IsNullOrEmpty(url))
    {
        System.Web.Mvc.TagBuilder linkTag = new System.Web.Mvc.TagBuilder("a");

        linkTag.Attributes.Add("href", url);
        linkTag.SetInnerText(text ?? url);

        if (!String.IsNullOrEmpty(title))
        {
            linkTag.Attributes.Add("title", title);
        }

        if (!String.IsNullOrEmpty(cssClass))
        {
            linkTag.Attributes.Add("class", cssClass);
        }

        if (newWindow)
        {
            linkTag.Attributes.Add("rel", "external");
        }

        @Html.Raw(linkTag.ToString())
    }
}

Вызов @LinkHelper.HtmlLink("http://www.google.com/", "Google") сгенерирует вывод HTML <a href="http://www.google.com/">Google</a>.

Однако было бы неплохо, если бы я мог по желанию передать фрагмент HTML, который будет обернут вокруг сгенерированного гиперссылки HTML, если URL-адрес имеет значение. Я бы хотел сделать что-то вроде этого:

@LinkHelper.HtmlLink("http://www.google.com/", "Google", @<li>@link</li>)

и получите вывод

<li><a href="http://www.google.com/">Google</a></li>

или @LinkHelper.HtmlLink("", "", @<li>@link</li>)

и вообще не выводить.

Я читал в блоге Фила Хаакеда о шаблонных делегатах бритвы , но не могу понять, как их можно использовать в этом контексте - если это действительно возможно. У меня такое ощущение, что я что-то упускаю или лаю не на том дереве.

Ответы [ 2 ]

1 голос
/ 26 марта 2012

В случае, если кто-то еще ищет это .. Я собрал следующее, которое будет работать. Это работает для пустых строк, и если делегат имеет значение null (на основании моего не совсем исчерпывающего тестирования ниже.)

Ключ, как говорит Якуб, использовать магический параметр @item.

@helper HtmlLink(string url, string text = null, 
    Func<IHtmlString, HelperResult> formatterFunction = null,  
    string title = null, string cssClass = null, bool newWindow = false)
{
    if (!String.IsNullOrEmpty(url))
    {
        System.Web.Mvc.TagBuilder linkTag = new System.Web.Mvc.TagBuilder("a");

        linkTag.Attributes.Add("href", url);
        linkTag.SetInnerText(text ?? url);

        if (!String.IsNullOrEmpty(title))
        {
            linkTag.Attributes.Add("title", title);
        }

        if (!String.IsNullOrEmpty(cssClass))
        {
            linkTag.Attributes.Add("class", cssClass);
        }

        if (newWindow)
        {
            linkTag.Attributes.Add("rel", "external");
        }

        // This is the part using the delegate
        if (formatterFunction == null)
        {
            @Html.Raw(linkTag.ToString())
        }
        else
        {
            @formatterFunction(Html.Raw(linkTag.ToString()))
        } 
    }
}

@HtmlLink("http://www.google.com", "Google")
@HtmlLink("http://www.google.com", "Google", @<b>@item</b>)
@HtmlLink("http://www.google.com", "Google", @<text><i>@item</i><br/></text>) @* <br/> fails otherwise *@
@HtmlLink("http://www.google.com", "Google", @<b>@item</b>)
@HtmlLink("", "", @<b>@item</b>)
1 голос
/ 12 августа 2011

Я думаю, что проблема с @link. Шаблонированные делегаты-бритвы берут данные, используя магический параметр @item. Попробуйте заменить @link на @item в вашем шаблоне.

Кроме того, опубликуйте код, который выполняет шаблон - ваш метод HtmlLink, который принимает Func<dynamic, object>.

...