About StyleHelper Skin Object for DNN

The 40FINGERS Style Helper Skin object allows you to manipulate the CSS, Javascript links and meta tags DNN loads by default.
You can remove them, change them and add your own.

The StyleHelper also allows you to do this only when certain conditions are met.
Some examples of the available conditions are: browser type / version, username, role, query string etc.
These filters can be positive (include) or negative (exclude).

If you find any issues please log them here

Important note about DNN 09.07.02 & Style Helper.

Due to a change in DNN 09.07.02 Style Helper will crash on that version of DNN.
DNN Issue on gitHub

This will be fixed in DNN 9.8.0

Stylehelper documentation

How to Add the skin object to your skin

Add to ASCX skin:
<%@ Register TagPrefix="fortyfingers" TagName="STYLEHELPER" Src="/portals/0/~/DesktopModules/40Fingers/SkinObjects/StyleHelper/StyleHelper.ascx" %>
<fortyfingers:STYLEHELPER ID="STYLEHELPER1" AddCssFile="Red.css" runat="server" />

 

Options and attributes


Remove (unload) CSS links from the head

Attribute:
RemoveCssFile

Use:
You can remove one or more of the CSS files DotNetNuke injects in the head of the page by default.
You do this by passing a comma separated list of filenames.
The skin objects looks if the value you pass is part of the complete path to the CSS file.

Examples:
RemoveCssFile="default.css" will remove CSS file where the path contains default.css
RemoveCssFile="module.css" will remove all module.css files (for all modules)
RemoveCssFile="/" will remove all CSS files
 
Please note that to avoid accidentally unloading the wrong stylse-heets, make sure your path is specific enough.
You can use Regular Expressions for this
Example: Remove DNN core default.css Style Sheet:
 
<fortyfingers:STYLEHELPER ID="sh1" RemoveCssFile="/Resources/Shared/stylesheets/.*/default.css" runat="server" />
 
 
 

Add "something" to Head of the Page.

As I got some requests to allow adding all kind of content to the head of the page, I decided to create an attribute to allow adding anything to the head of your DotNetNuke page.
You can pass multiple strings, but to make sure not conflicts arise, you have to use 2 pipe characters ("||") to seperate them.

Attribute: AddToHead
Example: AddToHead='<script types="text/javacript">alert("Inject to Head Example")</script>||<meta property="og:title" content="my title" />'

Tokens:
You can use also use the tokens that are listed under AddBodyClass in the AddToHead attribute.

 

Add CSS/JS files

Attribute:
For CSS files: AddCssFile
For JS files: AddJSFile

Use:
Comma separtated list of CSS or JS files to link from the page head.
Use AddCssFiles for css files and AddJsFiles for javascript files.
By default the skin path is used as basepath for the files.
(use the following tokens if you want to use another path)

File Paths

The path to the files can be set using the BasePath attribute, which default to the skinpath.
You can use tokens for the "BasePath" or for the individual files (in AddCssFile/AddJSFile);
[S] for the SkinPath
[P] for the current Portal folder
[M] for this Skin objects install folder
[R] for the root folder ("/")
[D] for the DesktopModules Folder ("/DesktopModules/")

If you use path tokens for a file the value for BasePath will be ignored.

Other Tokens:

PortalId
You can use: [PortalId] to load a portal specific stylesheet
Example: AddCssFile="Portal-[PortalId].css" will result in this style sheet being added: Portal-0.css, for the first portal.

Querystring parameter
You can load stylesheet with a querystring parameter in it's name
Format: [QS:Parameter]
Example: AddCssFile="File[SQ:Style].css" will result in this file being added if you pass a query string parameter with the name "Style"
So this url: mywebsite.com?Style=V2 would load a stylesheet with the name FileV2.css.
If you don't pass the querystring parameter, the stylesheet does not get loaded.
(I use this to test the different skin variations)

Css Media Type

You can set the default Media Type using the "CssMedia" attribute.
The default value = "screen"

You can also set the CSS media type attribute for a filename like so; "myfile.css:print".
This will add the myfile.css file with a media type "print".
If you want to pass multiple Media types for a file, separate them by colons; "myfile.css:print:handheld".
If you don't pass a media type for a file, the "CssMedia" value will be used.

Css file link location

Attribute: AddAtEnd

Use:
With this attribute you set the location where your js / css / meta tag / etc. is injected.
When you use AddCssFile / AddJsFile this location will be before module.css (start) or just before portal.css (end).
When using AddToHead, the location will at the top or bottom of the <head> element.

By default injection occurs at the end.

Possible Values: True / False

Default Value: True

 

Correct Module.cssload order

Attribute: ForceSkinCssOrder

Use:
Some extensions do not follow the DNN style sheet load order.
(where all CSS should be loaded before Skin.css & Portal.css)
This can be quite annoying if you want to overwrite certain styles.
With this setting you can correct that for extensions that use CRM to load style sheets.
It will force the CSS Load order of Skin.css to 1000 and for Portal.css to 1001

Possible Values: True / False

Default Value: False

<fortyfingers:STYLEHELPER ID="SH1" CorrectModuleCss="True" runat="server" />

 

Add Meta Tags

Attribute: AddMetaTags

Use:
You can add meta tags to the page head.

Possible Values:
The Format used is "Name:Value"
As of version 1.8.3 you have to separate Multiple Meta tags by using a single pipe sign: |
This was changed because a meta tag can contain commas.

Default Value:

Example:

<fortyfingers:STYLEHELPER ID="STYLERHELPER5" AddMetaTags="Name1:Value1|Name2:Value2" runat="server" />

 If you want to inject Meta tags that use different attributes (not Name="x" Value="y"), use the AddToHead attribute.

 

Change DNN Meta Tags.

You can change some of the existing default DNN meta tags.
The ones that have an ID in the page source can be changed.

Attribute:ChangeMeta
A Meta tag to change is passed like this: id=xxx|content=yyy
Where xxx is the id of the meta tag
yyy is the new content
Example: ChangeMeta='id=MetaRobots|content=noindex, nofollow'
This will set the DNN page to NoIndex from the skin.

 

Remove Meta Tags.

You can now remove the existing default DotNetNuke meta tags.
For now only the ones that have an ID (you can check in the page source or the default.aspx file on the server).
To make sure not conflicts arise, you have to use 2 pipe characters ("||") to separate different values.
This is useful if you for instance want to set a custom description meta tag, and remove the original one.

Attribute: RemoveMeta A Meta tag to remove is passed like this: id=xxx (no spaces) Example: RemoveMeta="id=MetaKeywords||id=MetaRefresh||id=MetaRobots"

 

Add Content to your page

This will inject content at the position of the SH skin obejct in you skin. You can use this with the supported filters to add conditional texts.

Attribute: Content
Example: IfRole="Administrators" Content="Hello Administrator!"

Add Content to the Top/Bottom of the BODY element

This can be used in case you need to inject content at the top or bottom of the Body Element in DNN.
Google Tag Manager for instance ask you to inject an iframe for users without Javascript at the top of the Body.
Please note that these two attributes (if used) will always be injected independent of the used filters.

Attribute: AddToBodyTop
Example: AddToBodyTop = "<!-- Google Tag Manager (noscript) -->
        <noscript><iframe src='https://www.googletagmanager.com/ns.html?id=XXX'
        height='0' width='0' style='display:none;visibility:hidden'></iframe></noscript>
        <!-- End Google Tag Manager (noscript) -->"

Attribute: AddToBodyBottom
Example: AddToBodyBottom = "<script>alert('Hi from the bottom of the Page!')</scriipt>"

Add CSS class to the body tag

Add CSS class to the body tag

You can add a CSS class to the body element of your DNN page. You can use a static text or a template. This allows you to address specific pages based on their name, id, order in the menu or a users role. There are 4 attributes you can use.

Attribute: AddBodyClass (True/False)

Use: This will inject the body class with the default template.
This is False by default unless you set "BodyClass" or "AddToBodyClass".

Attribute: FilterBodyClass (True/False)

Use: By default the BodyClass will ignore any filters you have as this attribute is False by default.
Set it to true if you want the BodyClass injected based on filters.

Attribute: BodyClass (String)

Use: The template for the class. If you set this attribute you don't have to set the AddBodyClass attribute.
The default template is: "Page-[Page:Name] Level-[Page:Level] [BcName] [BcId] [BcNr] CP-[CPState] [PageType] [UserPageRoles] Cult-[Culture] Lang-[Language] [IE]"

Attribute: AddToBodyClass (String)

Use: Add something to the existing / prevously set body class, used when you insert a class conditinally. (this is filtered, contrary to the BodyClass)

 

Portal Tokens

Token Description Results(s)
[Portal:Id] ID of the Portal 59
[Portal:Alias] Portal Alias dnn6dev.com/test-site
[Portal:Alias.Root] Portal Alias without Child portal part dnn6dev.com/
[Portal:Alias.Protocol] Current Protocol http/ https
[Portal:Name] Portal Name My Website
[Portal:Logo] Logo file name logo.png
[Portal:Logo.Path] Full Path to the Logo https://www.mysite..../logo.png
[P] PortalFolder 0

Current Page tokens

Token Description Result(s)
[Page:Name] Page Namen  Body_Class_All
[Page:Level] Page Level  1
[Page:Title] Title of the page  Body_Class_All
[Page:Description] Description of the page  
[Page:Url] URL of the page  
[Page:RelativeUrl] ID of the Portal  
[Page:Id] ID of the Page  
[Page:IconFile] The page's Icon File  
[Page:IconFileLarge] The page's Large Icon File  
[Page:Skin] Skin name  
[Page:Container] Container Name  
[CPState] ID of the Portal  
[Culture] Current Page Culture  
[Language] Current Page Language nl, en, fr

Other Tokens

[DnnVersion] Dnn Version, but only when the Control panel is visible (for security reasons)
You can use the IfDnnVersion condition in combination with "AddToClass" for custom logic.
DNN06
[CPState] State of the control panel None, View, Edit, Layout
[PageType] Type of the page PageType_Home, PageType_Splash, PageType_Login, PageType_Register, PageType_User, PageType_Search, PageType_Admin, PageType_Normal
[IE] Is the browser is Internet Explorer add a class  

[UserPageRoles]

This will render a class showing the roles the current user is a member that have view rights set for the current page.

This allows you to address certain user roles with your css (make the background of a site red if your logged in as an administrator for instance)

Example: On a page that has view set for all users, the following classes will be rendered:

- Anonymous user: <body id="Body" class="UPR_All_Users">

- Registered user: <body id="Body" class="UPR_Registered_Users UPR_All_Users">

Tokens related to the current page's Breadcrumb

Token Description Result
[BcName] Will render the Page Names in the breadcrumb as classes

L0_Add_CSS_Classes L1_Body_Class_All

[BcId] Will render the Page Ids in the breadcrumb as a classes Explanation: L0_RootPage > The current pages parent on level 0 named "RootPage" L1_SubPage > The current page on Level 1, named "SubPage" Id68 > The "RootPage" Id = 68 Id100 > The "SubPage" Id = 100 L0_Nr3 > "RootPage" is the third page on level 0 L1_Nr2 > "SubPage" is the second page on level 1
[BcNr] Will render the Page Order in the breadcrumb as a classes L0_Nr4 L1_Nr2

Please note that there's also a Filter based on Tokens, see "IfToken"

Set the Doctype of a skin

Attribute: doctype

Use: You can now set the doctype of a skin using the Style Helper skin object.
This means you don't need to create any skinname.doctype.xml files.

Possible Values:
HTML 5, XHTML 1.0 Strict, XHTML 1.0 Transitional, XHTML 1.1, HTML 4.01 Strict

Example:
<fortyfingers:STYLEHELPER ID="STYLERHELPER1" doctype="HTML 5" runat="server" />

Note: the doctype is always set if you use this, it is not influenced by the filters.

Redirect another URL.

Attribute: RedirectTo

Use: This can be used to redirect certain (mainly mobile) browsers to another page or website.
The way the redirect is handled is set with the "RedirectMode" Attribute

Example: RedirectTo="/"

 

Stop redirecting

With this attribute you set how you on what conditions redirecting is refused.
It depends on the RedirectMode attribute what happens the next time the user visits the site.

Attribute: RedirectStop

Possible Values:

Revisit: Will NOT redirect after the first redirect

RedirectUrl: Will not redirect if the Referrer URL is the Redirect URL

BaseRedirectUrl: Will not redirect if the Referrer URL contains the Base Redirect URL

QueryString: Will not redirect if the following Query String Parameter is passed: "NoRedirect=True".
These values can be combined, comma separated.

Default Value: "RedirectUrl,QueryString"

 

Persistence of a Redirect.

Attribute: RedirectMode

Use: With this attribute, you can set what happens after the Redirect has stopped


Session: Will not redirect again during this visit, the next browsing session the user visits the site he will be again redirected once.

Once: will redirect once, write a cookie (valid for a year) and will not redirect the next time the user visits the site (unless he clears the cookie).

Always: will always do the redirect next time

Never: will never redirect next time (for testing purposes)

Default value: Session

 

Multiple Redirects on one site / skin

You can give a redirect a name, to separate several redirects used on one site.
2 redirect with a different name will not influence each other, this way you can for instance have a Mobile redirect and a redirect for Internet Explorer 6 in the same skin.
It also allows you to share the same redirect over different skins using the same RedirectName.

Attribute: RedirectName

Default Value: "Default"

 

Redirect Handling

If the referrer page is the page to redirect to, no redirection is done.
So if you have the skin object on your home page with a redirect to Mobile.aspx, if the user comes from the Mobile.aspx page he does not get redirected back to that page.

In combination with RedirectMode set to "Always", the can lead to strange effects.
I suggest you set the RedirectMode to "Session" (previously "OncePerSession")

Backlink to the page that redirected.

The Style Helper Skin Object now support two ways for you can get a back link to the page that did the redirect:

Cookie
A Cookie with the name "40Fingers.StyleHelper.RedirectedFrom" can be written on redirect.
It contains the original page url of the page that caused the redirect.
You can use Javascript (or .NET) to read its value.

Query String Parameter
The url of the original page can also be added to the redirect url as a querystring parameter.
The result will look like this:
http://www.mysite.comt/Mobile.aspx?RedirectedFrom=http%3A%2F%2Fwww.mysite.com

As you can see the parameter is URL encoded.
Again, you can use Javascript to read the value and provide a "backlink"

Attribute: RedirectInfo
With this attribute you set how the Original page URL is made available, use:
     "QS" for QueryString
     "Cookie" to set a cookie
     "Cookie,QS" for both.

Example: RedirectInfo="Cookie"

 

 

Add Attributes to the HTML element

Attribute: AddHtmlAttribute

Use: This can be used for instance if you want to add support for the Open Graph protocol to a page. In that case you need to add attributes to the HTML element.

Basic: AddHtmlAttribute="Attribute,Value"
You can separate multiple values with a | character.
Example:
<fortyfingers:STYLEHELPER ID="SH1" AddHtmlAttribute="xmlns:fb,http://www.facebook.com/2008/fbml|xmlns:og,http://opengraphprotocol.org/schema/" 
runat="server" />
Would add opengraph and Facebook attributes.

 

Filtering

The filters are for both Js, CSS and Meta tags.
If you need different filter for JS and CSS for instance, you have to add the skin object to the page twice.
You can however switch filtering on/off for removal/adding.

FilterRemove attribute
Used to switch filtering for CSS file removal on or off (defaults to true).

FilterAdd attribute
Used to switch filtering for CSS / JS / Meta tag file removal on or off (defaults to true).

Effect or filters

Only filters that have a value set are used.
Most filters accept a comma (,) separated list.
If one of them fits, the filter passes.
The result is an OR combination of the different values.
If you use IfUserName="Timo,Peter" the filter is passed if the Username of the current User = Timo OR Peter.

Excluding values

You can exclude values too, you do this by starting the value with an exclamation sign (!).
IfUserName="!Timo" will pass for all authenticated users but Timo.
IfUserName="!Timo,!Peter" passes for all users but Timo and Peter

Filter Matching

Most filter use a regular expression meaning that "Tim" will match both "Tim" and "Timo".
If you want to match only "Tim" you should add a $ at the end; "Tim$".
$ references the end of a string in regular expressions.

The Filters are not case sensitive.

Debug you filters

Attribute:
ShowInfo

Use:
If the filters don't behave the way you expect them, you can force the skin object to write some of the detected values to the page.
This includes the Browser version, current user name, Roles, etc.

All filters listed at the bottom of this page

  

Supported Filters / Conditions


Browser (+ version)

Attribute:
IfBrowser

Use:
Will filter on the visitors browser and version.
You can also exclude browsers.
Pass a list of comma separated browsernames. Browsers = "ie,firefox" would only add the files if the visitor uses ie or firefox.
You can also filter on browser version, for that you need to add the version and an equals sign.
The version can be passed as as a number with major and sub version number.
You set how the version is interpreted by adding a an equasion sign.
Use = for this specific browser version.
Use > n, for browser version higher then n
Use < n, for browser version lower then n
You can exclude a certain browser by starting with an exclamation sign.

Examples:
Browser = "Firefox" Will render for all Firefox browsers
Browser = "!Firefox" Will render for all browsers that are not Firefox
Browser = "IE=6" Will render only for Internet Explorer 6
Browser = "IE<8" Will render for IE browsers below version 8
Browser = "!IE<7" Will render for any browser but IE below 7

Notes on browser detection:
The browser is tested against how ASP.NET detects the browser.
This is done using browser files in the App_Brosers folder of DNN.
This is not always 100% correct, especially for not so common browsers
You can always (find an) update for the browser files, to make ASP.NET detect the browser correctly

Alternatively you could use the UserAgent attribute to interpret the raw user agent string.

Check the DNN version (From SH version 02.10.00)

Attribute: IfDnnVersion="[<>=]#.#"

Use: With this filter you can filter on the DNN version

You can use the floowing values:
"8" for DNN 8
"7.2.0" for DNN DNN 7.2.0 only
">8" for all above DNN 8
">=8" for DNN 8 and above
"<=8" for DNN 8 and below
"<8" for all below DNN 8


Example:
<fortyfingers:STYLEHELPER ID="FFSH1" IfDnnVersion="=>6.1" Content="DNN 6 and above" runat="server" />

Will insert the content if the DNN is version 6.1 or higher.

Check for mobile browsers

Attribute: IfMobile="True/False"

Use: With this filter you can filter on "Mobile visitors".
It uses this technique to check if the users browser is a mobile browser based on the a regular expresion

If you don't set the attribute, there is no filtering.
You set the attribute to True if you want to filter on Mobile browsers.
You set the attribute to False if you want to filter on NON-Mobile browsers.

Example:
<fortyfingers:STYLEHELPER ID="FFSH1" IfMobile="True" AddCssFile="[S]//Mobile.css" runat="server" />

Will load Mobile.css if the users uses a Mobile browser

IfMobile uses 2 regular expressions (match 1 OR 2)  to detect mobile browsers. You can reset these two Regular Expression through the DetectMobileRegex1 and DetectMobileRegex2 attributes. (set the second to "" if you need only one).

Filter on Cookie values

Attribute: IfCookie

Use: With this attribute you can use conditions based on Cookies you either set yourself or that are set by DNN.
Example:

    <fortyfingers:STYLEHELPER ID="STYLERHELPER2"
        RedirectName="Cookie"
        IfCookie="dnn_IsMobile:True"
        RedirectTo="m.mywebsite.com"
        RedirectMode="always"
        
    runat="server" />

 

Attribute: IfNoCookie

Use: With this attribute you can use conditions based on the fact that a cookie does not exist.

UserAgent String Conditions

Attribute:
IfUserAgentString

Use:
Compares your values with the detected user agent string (using regular expressions)
An example user agent string for Firefox looks lik this:
"Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3"

Example:
IfUserAgentString="firefox" would match all firefox browsers (ASP.NET independent)
 

 

Username

Attribute:
IfUserName

Use:
Checks if the current user name is one of the values you pass.

Examples:
IfUserName="Timo,Peter", will pass if the username containIfUserName="!Timo,!Peter", will pass if the username does not contain Timo nor Peter.

UserRole

Attribute:
IfRole

Use:
Checks if the current user is in any of the roles you pass.
You can pass multiple roles (comma separated).
Please note that the test function exits as soon as one of the passed values is found so this works as an OR for multiple values.
So IfRole="editor,manager' will be true if a user is a member of one or both roles.
IfRole="editor,!manager' will not work as "Editor but not Manager" the second value will not be tested.

Wildcard Support:
There is currently no wildcard support for this filter

Examples:

IfRole="None", will match all users not in any roles (unauthenticated users)
IfRole="Administrators" will match all users in the Administrators role.
IfRole="!Administrators" will match all users not in the Administrators role.
IfRole="SuperUsers" will match all Host / Superusers
IfRole="!Administrators,!SuperUsers" will match all users that are not an Administrator nor a Superusers

 

State of the Control Panel

Attribute: IfUserMode
Values: None,View,Edit,Layout

Use: Filters on the state of the ControlPanel

URL

Attribute:
IfURL

Use:
Tests if the value you pass is part of the current pages URL.
You can also use this to test for certain pages, portal alias etc.

Example
IfURL="Contact" matches all pages with contact in the URL.
IfURL="!Contact" matches all pages without contact in the URL.
IfURL=" www.mydomain.com" will match a certain domainname (or portal alias)

Current Culture

Attribute:
IfCulture

Use:
Tests if the current ASP.NET culture, matches one of the passed values.
The format used is the ASP.NET culture format: en-US, fr-FR, NL-nl etc)

Examples:
IfCulture="fr-FR" will match if the culture is fr-FR.
IfCulture="fr-" will match all cultures using French.
IfCulture="!fr-" will match all cultures, but the ones using french.

Token(s)

Attribute: IfToken

Use:
Conditional Content using Style Helper based on Tokens. "IfToken" will be true if the passed Token String returns anything but an empty String
Examples

Examples:
<fortyfingers:STYLEHELPER ID="SH0" IfToken="[Page:Title]" Content="Page Title: [Page:Title]" ContentFalse="No Page Title" runat="server" />
<fortyfingers:STYLEHELPER ID="SH1" IfToken="[Page:IconFile]" Content="Page Icon: [Page:Icon]" ContentFalse="No Page Icon" runat="server" />
<fortyfingers:STYLEHELPER ID="SH2" IfToken="[Page:IconFileLarge]" Content="Page Large Icon: [Page:IconLarge]" ContentFalse="No Page Large Icon" runat="server" />

External condition

Attribute: IfExternal

Use:
Conditions for StyleHelper based a value passed from the skin, this allow you to add custom condition code to your Skins ASCX to influence the behavior of the StyleHelper
 
Examples:
<script runat="server"> Function Random() As String Dim RandGen As New Random Return RandGen.Next(0, 2).ToString End Function </script>
<fortyfingers:STYLEHELPER ID="SH0" IfExternal="<%#True%>" Content="External Value = True" runat="server" />
<fortyfingers:STYLEHELPER ID="SH1" IfExternal="<%#Random()%>" Content="Randomly True" runat="server" ContentFalse="Randomly False" />

Text Direction

Attribute:
IfTextDir

Use:
Tests the current text direction.
You can use either "rtl" or ltr"

Example
IfTextDir="rtl" will pass for RTL languages

Query String

Attribute:
IfQS

Use:
Filter with the querystring parameter.
This means you could switch a CSS file off or on using a query string parameter.
You pass the parameter name and value separated by a semicolon.
"Parameter:Value"

Example:
IfQS="color:red" could load a css file using this URL:
www.domain.com/?color=red.
You can use IfQS="!color" to detect the lack of a parameter
You can use IfQS="!color:black" to detect the lack of a parameter value


Please note that this is not persistent, the next page without the querystring parameter, the file will not be loaded.
In a future version I'll add support for cookies, so the file will be persistent.