Avia Afer
Avia Afer

Reputation: 866

layouts and different content and styles, complex MVC4 application

I was viewing lot's of tutorials , moving from web-forms and .master vs MVC Master layout.

the issue i have is regarding the embedded global files vs individual pages own files.

(files= styles and scripts)

Side note in my views i have implemented a little naming convention/rule so that layouts-masters has a LO postfix, so if my app named "SAdmin", then my layout(master)-chtml will be named :_SAdminLO.cshtml

and in my layout-master i have :

(for simplicity)just a main bar - links (so that all pages has the "links" top-bar)

this is the main layout

   [textlink1] | [textlink2] | [textlink3] | [textlink4] ....

then i have index page(it's name is cpanel)

in my index cpanel.chtml i have added icons in addition to the main layout's textual bar ... replication of the top bar in a form of icons menu

  [IMG]           [IMG]
  page_name     page_name

  [IMG]           [IMG]
  page_name     page_name

so together Layout-master _SAdminLO.cshtml + cpanel.chtml - froms the "home page" of my app

now i have individual pages that are totally independent in their actions

but all they need is the css + html of the top bar, as opposed to cpanel (the index)

so my situation is that: in rightclick-> view-source, i can see that all my pages has double html tags -

<html> + <head> + <body> markup of `LO`

&

<html> + <head> + <body> markup of `individual.cshtml `

the files :

-master-

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />

        <link href='@Href("~/Content/css/GlobUtils.css")' rel='stylesheet' type='text/css' />

    <title>@ViewBag.Title</title>
    @Scripts.Render("~/js")// C# bundle 

    @RenderSection("head", false)
</head>
<body id="bodid">
<h2>Cpanel</h2>



     <div id="navbar">

        <ul id="nav">

            <div class="menu-main-container">
                <ul id="menu-main" class="menu">
                    <li id="menu-item-0" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-0 current_page_item menu-item-0">
                            @Html.ActionLink("Cpanel", "Cpanel", "ControlPanel")
                    </li>
                    <li id="menu-item-1" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-1 current_page_item menu-item-1">
                            @Html.ActionLink("Templates Generator", "TemplateGenerator", "ControlPanel")
                    </li>
                    <li id="menu-item-2" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-2 current_page_item menu-item-2">
                            @Html.ActionLink("Content Editor", "ContentEditor", "ControlPanel")
                    </li>
                     <li id="menu-item-3" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-3 current_page_item menu-item-2">
                            @Html.ActionLink("Files Uploader", "FilesUploader", "ControlPanel")
                    </li>
                    <li id="menu-item-4" class="menu-item menu-item-type-post_type menu-item-object-page current-menu-item page_item page-item-4 current_page_item menu-item-2">
                            @Html.ActionLink("Code Dev", "CodeDev", "ControlPanel")
                    </li>

                </ul>
            </div>
       </ul>

   </div>
    @RenderBody()

</body>
</html>

someindividualpage.chtml

@{
    Layout = "~/Views/Shared/_EvProAdminLO.cshtml";
}
@model MvcE.Models.IndexModel.CreatedTemplateJPacket

<!DOCTYPE html>
    @{
        ViewBag.Title = "TemplateGenerator";
}
<html>
<head>
    <!--[if lt IE 9]>
    <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Template Generator</title>

    <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />


    <script src="http://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.0/jquery-ui.js"></script>
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>

    <link href='@Href("~/Content/css/Chrm_TemplateGenerator.css")' rel="stylesheet" type="text/css" />


</head>
<body id="bodid">
    <div id="DivEditor">
         <h1 id="ContH"> ControlPanel -  TemplateGenerator</h1>
        <div class="container-fluid">



           <div>
                    <a class="btn btn-CtrlsTmplt" id="save" href="#">save</a>
                    <a class="btn btn-CtrlsTmplt" id="load" href="#">load</a>
                    <a class="btn btn-CtrlsTmplt" id="clear" href="#">clear</a>
                    <input type="text" id="scr1" class="input_Border_AndBGClear" />
           </div>



            <hr/>
     @*----------------------------------localData-------------------------------------*@
            <div id="localData">

                <input id="DataValue_FormFileds" type="hidden" />
            </div>
        </div>


    </div>


    <div id="SaveNewTmpltWwrap">

    </div>



        <script src='@Href("~/Js/jspart2.js")' type="text/javascript"></script>

</body>

Upvotes: 5

Views: 1871

Answers (1)

Jasen
Jasen

Reputation: 14250

Maybe I'm not quite understanding but it seems you can use custom sections.

_Layout

<html>
    <head>
        <title>@ViewBag.Title</title>
        @* common script, css *@
        <script src="jquery.js"></script>

        @* variable script, css *@
        @RenderSection("customHead", required: false)
    </head>

    <body>
        <!-- nav bar here -->
        @RenderBody()

        @RenderSection("footer", required: false)
    </body>
</html>

SomePage.cshtml

@{
    Layout = "~/Views/Shared/_EvProAdminLO.cshtml";
    ViewBag.Title = "Some Page 1";
}

@section customHead {
    <script src="page1.js"></script>
}

@* no <html>,<head>,<body> *@

@* inserted into RenderBody() *@
<div id="page1content">
    ...
</div>

Because the section declared required: false it will won't try to render anything unless the view contains that section.

You can change the section content per page.

SomePage2.cshtml

@{
    Layout = "~/Views/Shared/_EvProAdminLO.cshtml";
    ViewBag.Title = "Some Page 2";
}

@section customHead {
    <script src="page2.js"></script>
}

@section footer {
    <div>footer</div>
}

<div id="page2content">
</div>

Rather than multiple layouts -- you can also use Partial Views and Child Actions to do variable content rendering.

SomePage3.cshtml

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "Some Page 3";
}

@Html.Partial("widget")
@{Html.RenderAction("UserInfo");}

Now much of the layout content is removed and it becomes content inclusion rather than defining everything with exclusion rules.

I find fewer layout pages and using partials is more maintainable and the pages easier to understand what will render by looking at just the view page.

Upvotes: 5

Related Questions