Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • David 16 posts 127 karma points
    Jan 31, 2020 @ 14:26
    David
    0

    Add a class the 'main template' using ViewBag inside of a PartialView

    I ideally need to be able to set a body class using MVC @ViewBag

    I have a View that returns a PartialView (set by a Controller)

    /Views/Master_Template.cshtml

    <div class="o-wrapper @ViewBag.PageTheme">
          **content**
    </div>
    

    View

    /Views/artist.cshtml

    @{ Html.RenderAction("Index", "Artist", new { model = Model }); }
    

    Controller

    /Controller/SurfaceController/ArtistController.cs

      public class ArtistController : SurfaceController
        {
            public ActionResult Index(Artist model)
            {
                if (model.IsUpAndComing)
                {
                    return PartialView("UpAndComingArtist", model);
    
                }
                //tried @ViewBag.PageTheme = "is-dark" here too. 
                return PartialView("MainArtist", model);
            }
        }
    

    And then inside my Partial View, I am setting my ViewBag

    /Partials/MainArtist.cshtml

    @{ 
        ViewBag.PageTheme = "is-dark";
    }
    
    **fun stuff**
    

    I did try this article on here first but with no luck, the class 'is-dark' does not seem to get added.

    Is there another way I can do this?

    Thanks so much :D

  • Marc Goodson 2142 posts 14345 karma points MVP 8x c-trib
    Feb 02, 2020 @ 09:44
    Marc Goodson
    100

    Hi David

    I'm wondering if you could make use of MVC sections here...?

    In your master layout view could you establish a 'Section' that isn't always 'required'... eg

    <div class="o-wrapper @RenderSection("Theme", required: false)">
          **content**
    </div>
    

    and then in your page template (not partial view) I'm presuming that the theme change depends on whether the artist is Up and Coming, and that in this page template you have the Artist model and so can check this state before rendering the partial views...

    like so:

    @section Theme { 
        @(!model.IsUpAndComing ? "is-dark" : "";
    }
    

    The @section definition of Theme means that anything entered here will appear in the master layout view, positioned wherever @RenderSection("theme" is called, It doesn't matter where in the page template the @section is specified, usually at the bottom, or before the Html starts - but it's not clever enough to be defined in the partial view!

    You can have multiple sections defined in a master layout view,

    regards

    Marc

  • David 16 posts 127 karma points
    Feb 02, 2020 @ 11:19
    David
    0

    Thanks, Marc. Appreciate this :-)

    Do you mean like this? In the /Views/Artist.cshtml file?

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<Artist>
    @{
      Layout = "master.cshtml";
    }
    
    @section Theme {
      @(!model.IsUpAndComing ? "is-dark" : "";
    }
    
    @{ Html.RenderAction("Index", "Artist", new { model = Model }); }
    

    If so, and apologies if I have this wrong, the compiler is returning

    the name model does not exist in the current context, the name  isUpAndComing does not exist in the current context
    
  • Marc Goodson 2142 posts 14345 karma points MVP 8x c-trib
    Feb 02, 2020 @ 11:34
    Marc Goodson
    0

    Hi David

    Yes, (you'll need uppercase m on model I think, and also in my clumsyness not put the close round bracket in :-( )...

    @section Theme {
      @(!Model.IsUpAndComing ? "is-dark" : "");
    }
    

    apologies!

    marc

  • David 16 posts 127 karma points
    Feb 02, 2020 @ 11:40
    David
    0

    Thanks so much, Marc. This has solved it. And they say MVC is old tech ;-) !!! Beautiful. Thanks again!!!!!!!!! :D

  • Marc Goodson 2142 posts 14345 karma points MVP 8x c-trib
    Feb 02, 2020 @ 11:49
    Marc Goodson
    0

    cool... there is also another really neat trick with MVC sections that's worth being aware of, that essentially you can provide some 'default' implementation in the master layout view, and then allow individual page templates to override it on a page template by page template basis eg

      @if (IsSectionDefined("PageHeaderOverride"))
        {
            @RenderSection("PageHeaderOverride", false)
        }
    else {
              <div class="default-page-header">
                    <h1>Some Page Header</h1>
                    etc etc etc
              </div>
    }
    

    All page templates inheriting from this layout would get the default page header implementation - but on a page that needed specific markup or no page header at all you could just define the override section and do something specific:

    @section PageHeaderOverride { //page template specific stuff here}
    

    not relevant for your theme situation but worth being aware of anyway... secrets from the old tech :-)

  • David 16 posts 127 karma points
    Feb 02, 2020 @ 12:42
    David
    0

    Very handy to know. Thanks again.

    Just quickly,

    You see this

    @section Theme {
      @(!model.IsUpAndComing ? "is-dark" : "";
    }
    

    Say it was also going to apply to another doc type as well, say for example

    /Views/StandardPage.cshtml (which wouldn't have it own Model or Controller) is there a way I could assign this too? Something like?

    @section Theme {
      @(Model.CurrentPage ? "is-dark" : "";
    }
    
  • Marc Goodson 2142 posts 14345 karma points MVP 8x c-trib
    Feb 02, 2020 @ 19:35
    Marc Goodson
    0

    Hi David

    If I understand correctly, then yes, you can now use the same section in other templates, to 'send back up' to the master layout other css class names, based on logic specific to the type of page template and underlying document type throughout the site.

    When running training courses I used to describe the creation of a 'section' as being a little like creating a letterbox into the master layout template that you can post things into, as long as you address them right... if that makes sense :-P

    your other pages might have different css classes they need to set, or different logic to determine whether to set them:

    So in your standardpage template you could have:

    @section Theme {
      @(Model.HasValue("aliasOfSomeThemeProperty") ? Model.Value<string>("aliasOfSomeThemeProperty") : "no-theme";
    }
    

    where "aliasOfSomeThemeProperty' is the alias of a text box where a custom theme css class is entered...

    ... or however complicated the logic needs to be...

    @section Theme {
      @(Model.HasValue("backgroundImage") ? "has-background-image" : "no-background-image";
    }
    

    using HasValue and Model.Value is independent of 'what type' the underlying document type is for the page, eg where you have @Inherits UmbracoViewPage at the top instead of @inherits UmbracoViewPage<Artist>

    if that answers the question!!

    regards

    marc

  • David 16 posts 127 karma points
    Feb 03, 2020 @ 09:37
    David
    0

    Thanks so much :D

Please Sign in or register to post replies

Write your reply to:

Draft