4

我一直在编写一些声明性的Razor Helpers(使用 @helper 语法),用于现在支持 Razor 视图引擎的Umbraco 4.7(尽管我认为这同样适用于 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 片段,只要 URL 有值,该片段就会包裹在生成的超链接 HTML 周围,这将是一件好事。我基本上希望能够做这样的事情:

@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>)

并且根本没有输出。

我在 Phil Haacked 的博客中阅读了有关Templated Razor Delegates的文章,但无法掌握如何在这种情况下使用它们——如果确实有可能的话。我觉得我错过了一些东西或在错误的树上吠叫。

4

2 回答 2

1

我认为问题出在@link. 模板化的 razor 代理使用“魔术”参数获取数据@item。尝试在您的模板中替换@link为。@item

此外,发布执行模板的代码 - 您的HtmlLink方法采用Func<dynamic, object>.

于 2011-08-12T13:43:44.923 回答
1

万一其他人正在寻找这个..我将以下内容放在一起,这将起作用。它适用于空字符串,并且如果委托为空(基于我下面的不完全详尽的测试。)

正如 Jakub 所说,关键是使用魔法@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>)
于 2012-03-26T09:30:51.780 回答