MVC 3 Razor, Helpers with custom markup/section

前端 未结 4 585
囚心锁ツ
囚心锁ツ 2021-02-05 21:16

I\'m not even sure if this is possible, but I thought I would check to see if there is any way to make this easier.

First, I have some repeated markup in my site that lo

相关标签:
4条回答
  • 2021-02-05 21:33

    @TheKaneda, Thanks for the insight. I took your idea and extended it, such that you supply a PartialView name and it knows how to parse it.

    <Extension()> _
    Public Function UseTemplate(ByVal html As HtmlHelper, ByVal PartialView As String) As IDisposable
        Return New TemplateWrapper(html, PartialView)
    End Function
    
    Public Class TemplateWrapper
        Implements IDisposable
    
        Private _HtmlHelper As HtmlHelper
    
        'Index 0 is header
        'Index 1 is footer
        Private _TemplateWrapper As String()
    
        Public Sub New(ByVal Html As HtmlHelper, ByVal PartialView As String)
    
            _TemplateWrapper = Html.Partial(PartialView).ToHtmlString.Split("@@RenderBody()")
    
            _HtmlHelper = Html
            _HtmlHelper.ViewContext.Writer.Write(_TemplateWrapper(0))
    
        End Sub
    
        Public Sub Dispose() Implements IDisposable.Dispose
    
            _HtmlHelper.ViewContext.Writer.Write(_TemplateWrapper(1).Substring(12))
    
        End Sub
    
    End Class
    

    Use the same usage as @TheKaneda's example. In your partial view, instead of calling @RenderBody(), just put @@RenderBody() which acts as a flag for the middle part of your content. Sorry for the VB translation.

    Uses an example of my usage.

    Using Html.UseTemplate("ContentWrapper")
    
        @Html.EditorFor(Function(m) m.Var1, "TemplateHint")
        @Html.EditorFor(Function(m) m.Var2, "TemplateHint")
        @Html.EditorFor(Function(m) m.Var3)
    
    End Using
    

    My Partial looks like this...

    <div class="content"> 
        @@RenderBody()
    </div>
    
    0 讨论(0)
  • 2021-02-05 21:42

    There's also the other way, without disposable trick, which also requires a little less work, great for little helpers.

    @helper MyHelper(string title, Func<object, object> markup) {
        <div class="module">
            <h3>Title</h3>
            <div>
                <p>@markup.DynamicInvoke(this.ViewContext)</p>
            </div>
        </div>
    }
    

    Usage of this helper looks like this:

    @MyHelper("This is my Title", 
        @<p>Here is my custom markup</p>
    )
    

    Or with multiple lines:

    @MyHelper("This is my Title", 
        @<text>
            <p>More than one line</p>
            <p>Of markup</p>
        </text>
    )
    

    Telerik MVC controls used this trick for example to let you add your javascript code at the document load.

    Here's also a nice example. There's also some information here.

    0 讨论(0)
  • 2021-02-05 21:52

    If you are using Razor and MVC 3 it's real easy to write a quick helper method that would go inside the app_code folder, (I'll name it MyHtmlHelpers)

    I'd try something a little different and a little easier such as:

    @helper myTemplate(string title, string markup){
        <div class="module">
            <h3>@title</h3>
            @markup
        </div>
    }
    

    And the way you use it from a .cshtml file is as followed:

    @MyHtmlHelpers.myTemplate('title','markup')
    

    It should work, if I understand you correctly.

    0 讨论(0)
  • 2021-02-05 21:56

    Well, here's a "standard" way of doing something close to it, using an HTML helper extension. A very simple version of what Html.BeginForm() does.

    Approach: Simply return an IDisposable, and let the using statement take care of the rest.

    This is just an example of the concept (although it works). Not intended for immediate reuse. Written quickly with lots of shortcuts, not production code, plenty of opportunities for improvement and optimization, may have silly mistakes, could use TagBuilder etc. etc. Could easily be modified to reuse the Wrapper class for different... wrappings (there may even be a generic one already in ASP.NET MVC - haven't had a need for one).

    public static class WrapHelper
    {
        private class Wrapper : IDisposable
        {
            private bool disposed;
            private readonly TextWriter writer;
    
            public Wrapper(HtmlHelper html)
            {
                this.writer = html.ViewContext.Writer;
            }
    
            public void Dispose()
            {
                if (disposed) return;
    
                disposed = true;
    
                writer.WriteLine("  </div>");
                writer.WriteLine("</div>");
            }
        }
    
        public static IDisposable Wrap(this HtmlHelper html, string title)
        {
            TextWriter writer = html.ViewContext.Writer;
    
            writer.WriteLine("<div class=\"module\">");
            writer.WriteLine("  <h3>" + html.Encode(title) + "</h3>");
            writer.WriteLine("  <div>");
    
            return new Wrapper(html);
        }
    }
    

    Usage:

    @using (Html.Wrap("Title"))
    {
        <p>My very own markup.</p>
    }
    
    0 讨论(0)
提交回复
热议问题