Umbraco Nested Masterpages - asp.net

I'm trying to create nested master pages in Umbraco 4.7.1 and I'm having issues.
I've got a masterpage doctype and an index doctype which is a child of masterpage.
Then I have a separate doctype called slide show.
My content looks like this:
Index
SlideShow
My master page template has the reference to the index like this:
<asp:ContentPlaceHolder ID="Content" runat="server" />
then inside the index my code is between
<asp:Content ContentPlaceHolderID="Content" runat="server">
</asp:Content>
and inside the Index template I reference the next level which is an Image slider
<asp:ContentPlaceHolder ID="SlideShow" runat="server" />
and the SlideShow template has code between
<asp:Content ContentPlaceHolderID="SlideShow" runat="server">
</asp:Content>
It worked for the Index but not for the slideshow.
The only difference I can think of off hand is the doctype for index is actually a child doctype of the master. And the SlideShow doctype is actually it's own doctype. Not a child of any of them.
Any ideas how to get this working?

Having nested pages inside Umbraco is perfectly fine. In fact, it's actually an ASP.Net mechanism which doesn't necessarily relate to any heirachy in Umbraco. So it's possible to have unique Umbraco document types which don't inherit from each other, yet one master template is nested in the other.
Master templates work in a way where a master doesn't specify which templates inherit from it, it's always the child template referring to the master template, much like inheritence in object orientated programming languages. The <asp:Content /> tag in the child specifies which <asp:ContentPlaceHolder /> it uses from the parent.
I'm a bit confused how you've setup the master templates from the description, but you should try to have it setup like the following ...
Root Master Template:
<asp:ContentPlaceHolder ID="Content" runat="server" />
Index Master Template:
<asp:Content ContentPlaceHolderID="Content" runat="server">
<!-- your html -->
<asp:ContentPlaceHolder ID="IndexLeft" runat="server" />
<!-- your html -->
<asp:ContentPlaceHolder ID="IndexRight" runat="server" />
<!-- your html -->
</asp:Content>
Slide Show Master Template:
<asp:Content ContentPlaceHolderID="IndexLeft" runat="server">
<!-- your html -->
</asp:Content>
<asp:Content ContentPlaceHolderID="IndexRight" runat="server">
<!-- your html -->
</asp:Content>
You can create as many nested templates as you want, sanity-permitting. Making a document type use the template Index won't include the slide show. You'd need to give it the Slide Show template instead.
There's more info on it here: http://msdn.microsoft.com/en-us/library/ie/x2b3ktt7.aspx
Hope it helps.

Related

Failure to implement external css file in .aspx content page in asp.net WebForms application

I am struggling to implement an external CSS file in the content pages of my asp.net WebForms application. The content page thus have a master page (Site.Master) in which I included the following code in the head section:
<asp:ContentPlaceHolder ID="HeadContent" runat="server">
<link href="Styles/pokerpsych.css" rel="stylesheet" type="text/css" />
</asp:ContentPlaceHolder>
The asp:ContentPlaceholder tag thus contains the link to the CSS file that I want to apply to all pages. The styling in this link is thus successfully applied to the content in the body tag of the Site.Master page however the styles specified in this file is not applied to IDs that are specified for content pages. In one of my content pages I have for instance the following code:
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="PostHand.aspx.cs" Inherits="PokerPuzzleWebforms.PostHand" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<header>
<h1>Post your hand here</h1>
</header>
<main>
<label runat="server" for="titleBox" id="titleLabel" >Title</label>
<input type="text" id="titleBox" name="titleBox" runat="server" />
</main>
</asp:Content>
I am thus trying to apply styling to the label for the textbox (id="titleLabel") although I have not been successful.
I have validated the CSS file and there seems to be no errors. I have also tried to override the pokerpsych.css with another external CSS file by adding the following code in the content page:
<asp:Content ID="Head" ContentPlaceHolderID="HeadContent" runat="server">
<link href="Styles/posthandstyle.css" rel="stylesheet" type="text/css" runat="server"/>
</asp:Content>
I also tried embedding a style tag within the asp:Content tag although this was not successful. I am however only able to apply the styles to the id when I make use of inline styles although I would prefer to include an external file to apply the styles.
Below is the CSS file (pokerpsych.css):
body {
}
#test{
color:red;
}
#titleLabel {
color:red !important;
margin-right:100px;
}
From user1429080's comment:
This is probably caused by dynamic ID handling in Web Forms. The ID of the textbox in the rendered HTML is likely different from just titleLabel. Check by View source on the rendered page.
The easiest workaround might be to use class-based CSS and refer to the correct class on the control in the ASPX page instead of the IDs.

Form tag inside master page and content page

I have one master page and several content pages , I need to put a form tag inside a master page to handle sending data from my html elements and do this for my content pages as well .but I need to understand what is the best way to structure for such this scenario and what would be the effect of form tag of master page on content pages ? is it possible to put form tag in content pages when the master page has this tag inside itself ? I appreciate if I have in detail explanation ?
The <form runat="server"> element lives in the master page by default when you add a new one to your project; all child pages are implemented using ContentPlaceHolders.
For example, the master page: -
<form id="form1" runat="server">
<div>
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
You can have as many ContentPlaceHolders as you need (often only one is needed though). If you then add a "child page using master page", the page-specific content is added inside the relevant <asp:Content> element - these are added by default once you have specified the master page to use when adding a "child page using master page": -
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<!-- your markup, controls etc.. -->
</asp:Content>
Have a read of the MSDN docs for more - http://msdn.microsoft.com/en-us/library/aa581781.aspx

How to add master page to already created webform?

I have a asp.net webform application. Now I have to add master page in this application, but I don’t know how to merge or add new created master page with old webforms? How to handle html in webforms like <head> , <body> ? Any link in this regard will be helpful.
1- Define the fixed elements in your design, and put them inside the newly created master page
2- Define the dynamic ones, and add asp:ContentPlaceHolder for them ( most commonly one for HEAD, one for main content in your BODY , and one for side content "if applicable")
<asp:ContentPlaceHolder ID="CphHead" runat="server">
</asp:ContentPlaceHolder>
3- In your pages, add MasterPageFile="~/MASTER_PAGE_PATH" inside the Page directive.
4- Add asp:Content sections inside your pages which will hold the dynamic content in your pages, and don't forget to reference the correct ContentPlaceholder ID.
<asp:Content ID="HeadContent" ContentPlaceHolderID="CphHead" runat="server">
// Your content goes here...
</asp:Content>
5- Copy your page content inside these asp:content sections, and BOOOOM....you are done.
at the top of the new page in the '<%# page #>' tag add 'MasterPageFile="~/Site.Master"'
then add the needed placeholders
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
</asp:Content>
of course modify these to the names you are using
you can add the content holder tag in master page. So when you add 'MasterPageFile="~/Site.Master"' then you able to add content of other pages.

How to hide a content place holder in a .aspx page?

My master page has 3 content place holders:
1. left side bar
2. middle content area
3. right side bar
So it looks like:
<div id="left"></div>
<div id="content"></div>
<div id="right"></div>
On a particular view page (.aspx) that inherits the master page, I want to now show #3 (right side bar).
So I don't want the to be rendered at all.
How can I do this?
Another thing to consider is nested master pages. I have a similar design layout I'm doing in a current project, and we have a "base" master page that does all of our script includes, header and footer, and has just a single ContentPlaceHolder that represents everything between the header and footer. We then have a nested master page that uses the base master page, but adds a right "aside" column. For pages where we want the right column visible, we use the nested master page. For pages where we don't want it rendered, we use the base master page.
A strategy like this would definitely prevent your column #3 from being rendered at all (as opposed to being rendered and just being empty, which might not achieve the layout you're going for).
It looks something like this:
Base master page:
<%# Master Language="C#" AutoEventWireup="true" CodeBehind="MasterBase.Master.cs" Inherits="MasterBase" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
...
<asp:ContentPlaceHolder ID="head" runat="server" />
</head>
<body>
<form id="form1" runat="server">
<!-- HEADER -->
...
<!-- CONTENT -->
<asp:ContentPlaceHolder ID="bodyContent" runat="server" />
<!-- FOOTER -->
...
</form>
</body>
</html>
Nested Master Page
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<asp:ContentPlaceHolder ID="head" runat="server" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="bodyContent" runat="server">
<!-- CENTER COLUMN -->
<div id="centerCol">
<asp:ContentPlaceHolder ID="bodyContent" runat="server" />
</div>
<!-- RIGHT COLUMN -->
<div id="rightCol">
<asp:ContentPlaceHolder ID="rightColumn" runat="server" />
</div>
</asp:Content>
There's a few ways you can achieve this depending on what you mean by "render".
One way is to apply an id to each page's body tag and then use CSS to hide the divs you don't want to be 'rendered' using something like
#myPage #right{display:none;}
Alternatively, if by 'render' you mean output in the HTML response then you could replace your divs with a partial view. At run time you could then decide which partial views to include in your page, either as part of a base controller that all controllers inherit or as part of each controller individually.
Using a base controller is one of the ways I replicate general code in a similar way as you might have done in a master pages codebehind in webforms.
It would be best if you used the content place holders for formatting and placed the actual content inside the .aspx files that inherit from the .master page.
This way you assign your 3 column divs in you master without content but float them left or however you want to format them with your css and use the content reference in your .aspx to place the content into the desired column.
PS. if your looking to create 3 column layout I would suggest using jquerys .ui-layout plug-in instead of trying faux columns, etc..
As per the documentation from System.Web.UI.WebControls, you can use the Visible property of the ContentPlaceHolder class.
To do this, you need to go to the CodeBehind file for the webpage. For example:
Child.aspx
<asp:ContentPlaceHolder id="HideMe" runat="server">
....
</asp:ContentPlaceHolder>
Child.aspx.vb
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
HideMe.Visible = false
End Sub
Alternatively, and as pointed out by Jamie Dixon, you can also hide the div with the css rule display:none;
Master Page
<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
....
</asp:ContentPlaceHolder>
<asp:Panel ID="PanelRightMenu" runat="server">
<asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
....
</asp:ContentPlaceHolder>
</asp:Panel>
Child Page code binding
this.Master.FindControl("PanelRightMenu").Visible = false;

Do script tags and link tags go inside asp:content or outside

I have a page which has a masterpage. Do I put script and link tags inside the asp:content place holders or outside or does it matter.
When I put it outside, I get the following warning:
Only Content controls are allowed directly in a content page that contains Content controls.
I can see five (or 8) ways of doing it:
In the codebehind (.cs or .vb) using:
Scriptmanager.RegisterClientScriptinclude - using an absolute/relative path
Scriptmanager.RegisterClientScriptInclude - using an embedded resource
Scriptmanager.RegisterSlientScriptBlock - with your source inside
Adding it inline to your ASPX page in the designer
Sticking it inside the asp:content where the content lives inside the body tag.
Sticking it inside the asp:content where the content lives inside the head (You've said this isn't an option, so ignore this).
Adding it programmatically using the ScriptManager inside a control you use on the page as above.
"Only Content controls are allowed directly in a content page that contains Content controls" - did you forget the runat="server"?
If it's scripts and links for all pages, it should go outside any ContentPlaceHolders. If it's scripts and links for this page, it should go inside a Content inside the head. If it's default scripts, put it inside a head ContentPlaceHolder, and it can be replaced by the child page if needed. (VS usually complains about a ContentPlaceHolder in the head, but it works fine for me).
// master Page
<head runat="server">
<asp:ContentPlaceHolder id="head" runat="server">
<!-- Default scripts and CSS -->
<link rel="stylesheet" type="text/css" href="default.css" />
<script type="text/javascript" src="jquery.js"></script>
</asp:ContentPlaceHolder>
<!-- Mandatory scripts and css -->
<link rel="stylesheet" type="text/css" href="all.css" />
<script type="text/javascript" src="all.js"></script>
</head>
<body>
Master Page!
<asp:ContentPlaceHolder id="body" runat="server" />
</body>
// Child (no JQuery)
<asp:Content ContentPlaceHolderID="head" runat="server">
<link rel="stylesheet" type="text/css" href="default.css" />
<!-- Don't need JQuery -->
<script type="text/javascript" src="prototype.js"></script>
</asp:Content>
<asp:Content ContentPlaceHolderID="body" runat="server">
Child Page!
</asp:Content>
// Child 2 (with JQuery)
<asp:Content ContentPlaceHolderID="body" runat="server">
Child Page!
</asp:Content>
If you are referring to <asp:Content /> tags, you can't put anything outside of them in an .aspx page. So you're limited to putting them inside the <asp:Content /> tag. If you want <script /> and <link /> tags you need to either put a <asp:ContentPlaceHolder /> in the <head> of your master page, or add them dynamically via the Page's Controls collection.
Outside. Tthe inside of the ContentPlaceholders is going to be replaced with content from your pages anyhow so it doesn't make much sense to put anything in there.
outside. in the master page
The place holders are the wrapping controls for pages which descend from master pages.
Use asp.net scriptreference tag in master page to add reference to javascript file and you will be able to access all you need in the javascript file as if you would have added to the local page.

Resources