0

我一直在尝试找到一种方法,以编程方式将外部 CSS 文件的链接<head><body>Castle MonoRails 和 NVelocity 视图引擎中的标记中的标记添加到标记。任何人都知道如何做到这一点?

我需要解决这个问题,因为我处理的页面可能包含许多“小部件”,并且每个小部件都会以最佳方式获取额外的资产,例如 JS 和 CSS,而不是放在<link ..>body 标记内并冒着渲染问题的风险。

4

4 回答 4

1

您是在谈论从视图将其添加到布局中吗?因为视图是在布局之前渲染的,这意味着如果您创建一个负责渲染样式块的 Helper,那将解决您的问题。

这意味着,在您的视图或视图组件中,您将能够调用如下内容:

$Style.Add("/static/style1.css")

并在您的布局(头部)中:

$Style.Render()

这是一个示例帮助程序(继承 AbstractHelper 是可选的):

public class StyleHelper : AbstractHelper
{
    private readonly HashedSet<string> sheets = new HashedSet<string>();

    public void Add( string styleSheet )
    {
        Add( styleSheet, "all" );
    }

    public void Add( string styleSheet, string media )
    {
        this.sheets.Add( String.Format( "media=\"{0}\" href=\"{1}\"", media, styleSheet ) );
    }

    public string Render()
    {
        var str = new StringBuilder();

        this.sheets.ToList().ForEach( sheet => str.AppendLine( String.Format( "<link rel=\"stylesheet\" {0} />", sheet ) ) );

        return str.ToString();
    }
}

AbstractHelper 是 Castle.Monorail.Framework.Helpers 的一部分。除非您想利用该抽象实现所公开的功能,否则您不需要继承它。然后,将它添加到您的控制器中,无论是您的基本控制器还是特定控制器:

[Helper( typeof( StyleHelper ), "Style" )]
public class YourController
于 2011-05-31T17:49:10.730 回答
1

此处发布的解决方案无法正常工作。更好的方法是将脚本添加到 httpContext.Current.Items

使用与@jishi 相同的结构:

在您的视图或视图组件中,您将能够调用如下内容:

$Style.Add("/static/style1.css")

并在您的布局(头部)中:

$Style.Render()

您的助手包含 2 个使用 httpcontext 存储和检索文件列表的简单方法。

    public class StyleHelper
{
    public static void Add(string file) {
        if (string.IsNullOrWhiteSpace(file))
            return;

        var obj = HttpContext.Current.Items["AssetFiles"] as List<string>; // get the collection which might be empty
        if (obj == null || obj.Count == 0) {
            IList<string> list = new List<string>();
            list.Add(file.ToLower());
            HttpContext.Current.Items.Add("AssetFiles", list); // adds your first asset to your collection and returns
            return;
        }

        if (obj.Contains(file.ToLower()))
            return; // asset is already added

        // new asset ready to be added to your collection
        obj.Add(file.ToLower());
        HttpContext.Current.Items.Add("AssetFiles", obj);
    }

    public string Render() {
        var obj = HttpContext.Current.Items["AssetFiles"] as List<string>;
        if (obj == null || obj.Count == 0)
            return ""; // you never added anything to the collection. Nothing more to do.

        // not using linq here for the sake of readability:
        string res = string.Empty;
        foreach (var item in obj) {
            res = res + string.Format("<link rel=\"stylesheet\" {0} />", item);
        }
        return res;
    }

}

在您的控制器(最好是基本控制器)中添加:

[Helper( typeof( StyleHelper ), "Style" )] 公共类 YourController

于 2013-02-09T09:41:17.957 回答
0

捕获

我发现有一个组件正是我在这里寻找的。

在视图中:

#capturefor(capturefortest)
    Default way of printing. Use this for unique variables, such as title.
#end

#blockcomponent(CaptureFor with "id=capturefortest" "append=before")
    This will append before 1.
#end

#blockcomponent(CaptureFor with "id=capturefortest" "append")
    This will append after 1.
#end

#blockcomponent(CaptureFor with "id=capturefortest" "append")
    This will append after 1 and 3.
#end 

#blockcomponent(CaptureFor with "id=capturefortest") 
    Overrides everything defined before this. 
#end

布局/母版页:

$capturefortest

转义#:

在#blockcomponent(CaptureFor) 中放置#,例如在jQuery ID 选择器中时,你会得到一个错误。这可以通过在 AssetFilter 中设置一些全局可用的变量并使用 ${HASH} 来打印 # 来避免。单引号和引号也很不错:

controllerContext.PropertyBag.Add("HASH", "#");
controllerContext.PropertyBag.Add("Q", '"');
controllerContext.PropertyBag.Add("sq", "'");

现在您可以安全地执行以下操作:

#blockcomponent(CaptureFor with "id=capturefortest" "append=before")
    <script type="text/javascript">
        jQuery('#container').html('Awesomeness!')
    </script>
#end
于 2012-06-05T06:24:11.870 回答
-1

这要归功于 Javascript!这是我将样式附加到的方式<head>

<script type="text/javascript">
    var cssNode = document.createElement('link');
    cssNode.setAttribute('rel', 'stylesheet');
    cssNode.setAttribute('href', 'http://path.to/your/file.css');
    cssNode.setAttribute('type', 'text/css');
    document.getElementsByTagName('head')[0].appendChild(cssNode);
</script>
于 2011-05-31T14:15:34.873 回答