The term “skinning” refers to a software architecture process that gives the Web professional a manageable way to manipulate the presentation of content without affecting the logic of the website/application. Skinning involves the use of templates or “skins,” which contain presentation and layout attributes and are separate from application logic. An intelligent skinning engine is then used to assemble the assets into a final product. This approach to content management affords both developers and designers more independence when it comes to maintaining a website. It also substantially reduces the time and effort required in the post-release phases of any Web-based development project.
Although ASP.NET’s user controls include template management, they are foreign to many professional Web designers. Web designers can certainly learn to use them; however, the learning curve could involve accidental technology mangling or removing critical server controls. Ideally, Web designers would be able to use their tool of choice for creating skins while the details of user controls remain safely quarantined. With DotNetNuke (DNN), this is the case.
To make the process of creating and maintaining skins as easy and flexible as possible, DNN enables designers to use familiar HTML. Within the skin, DNN designers can include placeholders, which indicate the insertion of predefined code that corresponds with the placeholder. Placeholders are simply [TOKEN] text, which identify a particular skin object, such as a menu. To mitigate the performance impact of replacing these placeholders at runtime, we created an easy skin-upload mechanism, which does the substitution of placeholders with the skin objects to produce a user control file, which then can be rendered by the engine. This pre-processing occurs only once (when the skin is uploaded). This technique provides us with the performance benefit of user-control skinning, yet also enables Web designers to work independently from Web developers.
In terms of layout, DNN employs a free-form skinning approach, which empowers skin designers to organize the page in any fashion they desire. For the injection of content modules into the page, the designer can create an unlimited number of content panes, which can be associated to the placement of modules in the database. This free-form approach offers the ultimate in design flexibility but also imposes some complications. For true plug-and-play skinning, the layout, name, and quantity of content panes would have to consistent in each skin.
Skin Creation
There is not a mandatory order to this process, but the order below seems to work the best.
-
Set up your skin development environment:
To simplify the development of skin files and to expedite the packaging process later, it is recommended that you use the following organizational folder structure:
e.g.,
-
Design your skin(s):
The free-form nature of DNN skinning provides almost unlimited creative freedom with your design. Designers typically create the initial prototypes as full graphical images in Adobe Photoshop or some other professional design tool. One thing to be aware of when creating skins is that you need to include all user interface elements in your design. This includes static elements, such as graphics and text, but it should also include active elements, such as login links, a navigation/menu system, and more. Because this is a portal system that injects dynamic content at runtime, you will need to leave room in your design for this content.
Once the design is finalized, the designer will move onto the next step of “cutting up” the image into an HTML document. This is a process during which some of the more technical issues arise, regarding the most effective way to partition the various graphical elements into an HTML representation. HTML layout is much more “boxy” than free-flow graphics and the translation from a graphical image to an HTML document is critical to the presentation of the final product. Because HTML also has some of its own dynamic properties, you will need to tackle these behavioral issues as well. For example, you will need to decide whether you want portions of the skin to scale according to the client browser screen resolution or remain as a fixed width.
-
Choose an HTML or ASCX editor:
If you are comfortable with HTML tables and related HTML attributes, and you can handle simple CSS settings, you can build a skin. A WYSIWYG editor makes it particularly easy. You can use FrontPage, HotMetal, ColdFusion, Dreamweaver, VS.NET, or whatever editor you prefer – they’re all HTML-based, after all.
The HTML must be “well formed.” That is, all HTML container tags must be closed. For instance, if you have a <div> tag, it must be closed with a corresponding </div&g t; close tag. All tag attributes must have no spaces around the equal (=) signs, and attribute values must be in double quotes (e.g., <div class="cssclass">… </div> ). Generally a professional HTML editor handles all this for you, but preferences can often be set for other renderings; therefore, it is best to double check. For more info about coding practices check our XHTML Coding practices.
-
Manage graphics:
Graphics are an integral part of any skin design. In order for the skinning engine to be able to locate your graphics files, you must specify the image references in a specific format. It is generally a good idea to place your graphics in the subfolder as the skin file.
In order for DNN to locate your graphics files, the skinning engine uses two different methods to locate your graphics and media files: the “portable” method and the “localized” method. By default, the Skin Uploader will try to make a “portable” skin file. This means that the Skin Uploader and parsing routines will add the <% = SkinPath %> tag the beginning of relative graphical references.
-
Add skin objects and content panes:
Skin objects are objects that will be rendered dynamically at runtime. If you are creating ASCX skins, you will need to specify the @Register and actual user-control tag in your skin file (e.g., <dnn:Login runat="server" id="dnnLogin" /> ). If you are creating HTML skins, you simply need to specify the token (e.g., [LOGIN] ). It is important to understand the functionality of each skin object so that you can design the skin accordingly.
Content panes are the containers for the content modules, which are automatically injected at runtime. Content panes are simply HTML tags with some pre-specified custom attributes, which allow them to interact with the DNN skinning engine. The allowable content pane HTML tags include <TD&mt;, <DIV>, <SPAN>, and <P>. At a bare minimum you must have at least one content pane, and it must be appropriately named “CONTENTPANE.” Content panes do not need to be adjacent – they can be located anywhere on the page. Content panes are collapsible as well, which means that if the content pane contains no content at runtime, it will be become invisible. If you are creating HTML skins, you can use the [CONTENTPANE] skin object to identify areas in your design where content will be injected.
Skin objects support the concept of named instances. For example, if you want to have two menu controls in your skin, you can specify [MENU:1] and [MENU:2] in your skin file. In most cases you will only be using a single instance of a skin object in your skin, and in these cases it is acceptable to use a singleton instance specification (e.g., [MENU] ). Named instances are important for content panes, because in most cases you will have more than one content pane defined in your skin. In this case you would use [CONTENTPANE:1], [CONTENTPANE:2], etc.; however, you would still need to have one pane named [CONTENTPANE] because this is the default skin pane.
Skin objects also contain a feature known as attributes. Attributes allow you to customize the appearance of the skin object in your skin. Each skin object has its own set of supported attributes (Appendix B). If you are creating ASCX skins, you will need to specify the attribute directly in your skin file (e.g., <dnn:Login runat=”server” id=”dnnLogin” Text=”Signin” /> ). If you are creating HTML skins, you must include your attributes specifications in a separate file, thereby preserving the presentation of the HTML skin file for the designer. A skin package can contain a global attributes specification named “skin.xml” (or “container.xml” for containers), and this applies to all skin files in the package. In addition, you can also override the global skin attributes specification with a skin-specific attribute specification by providing a “skinfilename.xml” file. The Skin Uploader will merge the skin attributes with the HTML presentation file to create an ASCX skin file. The following XML fragment represents the structure of the attributes file:
Please note there is a one-to-one correspondence between the skin object declarations in your skin file (e.g., [MENU] ) and the attribute specification in the XML file. This is also true for named instances. For example, if you want to include a vertical and horizontal menu in your skin, you can specify [MENU:1] and [MENU:2] named instances in your skin file and then create definitions for each with different attributes in your XML file.
When creating HTML skins and specifying multiple content panes, you will need to specify the “ID” attribute in the attributes file.
-
Create a style sheet:
DNN uses an external style sheet (or CSS) specification, which takes full advantage of their cascading nature. Essentially this means that DNN has multiple external style sheet references on a page, and each style sheet reference is specified in a prioritized order so that hierarchical overriding can occur. The cascading order of style sheets is summarized below, with each item overriding the previous items:
- Modules – styles for custom modules defined in PortalModuleControl.StyleSheet
- Default – default host level styles – default.css
- Skin – skin styles – skin.css or skinfilename.css
- Container – container styles – container.css or containerfilename.css
- Portal – custom styles defined by portal Administrator – portal.css
A skin package can contain a global style sheet named “skin.css” (or “container.css” for containers), and this applies to all skin files in the package. In addition, you can also override the global skin style sheet with a skin specific style sheet by providing a “skinfilename.css” file. The default DNN style sheet ( /Portals/_default/default.css ) contains a number of default CSS "classes" (the entries that start with a period), which the portal relies on for a consistent user interface experience. You are free to add your own styles but at a bare minimum you should override the default styles to match your skin design.
-
Publish the skin:
In order for the skin to be viewable in the Skin Gallery, you need to create a high-quality screenshot of your skin. For each skin or container source file you should also have a corresponding screenshot stored with a .JPG file extension (e.g., if your skin file is named “skin.html” then your screen shot needs to be named “skin.jpg” ).
-
Package the skin:
All of the files associated to a skin are packaged as a compressed *.zip file. If you use Windows XP, or have "Compressed Folders" installed in Windows ME, you can right-click on the folder where you saved everything, choose "Send to >", and click "Compressed (zipped) folder." The operating system will Zip it up for you, and it is ready for upload. If you don't have one of these operating systems, use WinZIP or some other Zip file-compression utility.
In many cases, you will want to package a complementary set of skin files and container files in one distribution file. In order to do this, you must package your container files in a compressed *.zip file named “containers.zip.” Similarly, you must package your skin files in a compressed *.zip file name “skins.zip.” Then you must package these two files into a single *.zip file which is named after your skin. This will enable other users to install the full skin package (skins and containers) by uploading a single file through the Skin Uploader.
Optionally, you may also add an “About.htm” page to the skin package that will give info and credits about your entire skin package. A link to this file will be shown on the Skin Gallery page when viewing your skin package.
Container Creation
As mentioned previously, containers are skin definitions that can be applied to content modules. A container is defined in exactly the same manner as a skin except for the fact that there are a different set of skin objects used in containers.
The only additional restriction that applies to the creation of containers is that an Actions control must be included in the container skin. The Actions control is a feature in DNN that acts as the glue that binds the content module functionality to the portal framework. The Actions control is essentially a user-interface control that exposes the content module functionality. General functions include the ability to edit module settings as well as the ability to manage the positioning of modules within skin content panes. Custom functions related to a specific module are also exposed, enabling you to edit content and navigate to other controls. There are a number of Actions controls included with DNN. The default actions control is the SolPartActions control, which behaves as a pop-up menu when you hover over the “edit” icon in the upper left corner of the default container skin. Because this Actions control is best suited for higher-level browsers, there is also a DropDownActions control, which behaves like a simple dropdown combobox for down-level browsers.
Although skins and containers are created, packaged, and deployed independently, it is likely that you will create a skin and container combination that are intended to work together. This can be accomplished by uploading both the skin and the container and then applying them to your portal user interface. To simplify this operation and to provide a higher degree of granularity, Pane Level skinning is also available. Pane level skinning can only be configured during the design process, when the skin designer constructs the skin. It involves the use of some custom attributes, which can be included in the markup for the pane. The ContainerType, ContainerName, and ContainerSrc attributes can be used to identify a specific container to be used with all modules injected into the pane. In order for this to work correctly, the container must exist in the location specified; otherwise, the default container will be displayed.
Skin Upload
Skins can be uploaded via Admin or Host menu on a Skins tab. To upload skins to a specific portal, you must browse to the portal’s URL, log in, and use the Skins option in the Admin tab. To upload skins which are available to all portals, the Host should use the Skins option in the Host tab. The Skin Gallery has an option to upload your skin and container packages. Select the appropriate option to upload a package
Please note that if you are installing a skin package that contains both skins and containers (containers.zip and skins.zip), you should choose the “Upload Skin Package” option.
The Skin Upload will unZip the skin package, creating the necessary folder and decompressing the files. It will convert any HTML files to their ASCX user-control equivalent by replacing the placeholder tokens with the actual ASP.NET script. This replacement is performed according to the skin objects defined in the ModuleControls database table. ASCX user control files and CSS style sheet files will also be parsed to include the relative path references for graphics files.
Please note that depending on the Skin Upload Permission, some of the options may not be available to you.
Skin Gallery
DNN has a Skin Gallery, which allows administrators to view a thumbnail image of a skin, prior to applying it to your site. In order for a thumbnail to be displayed, the skin designer must create a high-quality screenshot of the skin, save it with a .JPG extension, and package it with their skin package. By adding an about.htm file with their skin, an informational credits page link will also be available in the Skin Gallery.
Skin Administration
Skins can be applied to your application at a variety of levels. A generic skin selection control is used to expose the available skins in various areas of the portal user interface. Each portal has access to its own skins as well as skins uploaded by the host. Skins are assigned in a hierarchical manner where child skins will override parent skin assignments. For example, a skin applied at the tab level will always override a skin assigned at the portal level.
Host Level
Host level skins apply to all portals in your site. They can be assigned by logging in as the SuperUser and selecting the Host / Host Settings tab. You are able to assign a skin and/or container for both the public portal and private admin interfaces.
Portal Level
Portal level skins apply to a specific portal. They can be assigned by logging in as the Administrator for a portal and selecting the Admin / Site Settings tab. You are able to assign a skin and/or container for both the public portal and private admin interfaces.
Tab Level
Tab level skins apply to a specific tab in a portal. They can be assigned by logging in as the administrator for a portal and selecting the Edit Tab Settings option from the tab admin control. You are able to assign a skin and/or container for a tab.
Pane Level
Pane level skins are actually module containers that apply to a specific pane on a portal tab. They must be configured by the skin designer when creating the skin and cannot be managed through the portal user interface. Module level skins assigned to a specific module will override the pane level skins.
Module Level
Module level skins are referred to as containers and apply to a specific content module instance on a tab. The can be assigned by logging in as the Administrator for the portal and selecting the Edit Module Settings option on the module Actions menu.
Control Panel
In order to achieve WYSIWYG usability, a Control Panel control is dynamically injected into the page when administrators identify themselves. The Control Panel contains a variety of administrative options for managing tabs and modules. By default, the Control Panel is displayed as a horizontal bar at the top of your browser window. The placement of this bar at the top of the page is intended to minimize the distortion to the overall appearance of the page.
The Skinning solution also offers the ability for you to override the default Control Panel behavior by including a pane named “ControlPanel” in your skin. This pane could be anywhere on your page, but the Control Panel control will only be displayed for the administrator or host. You also have the ability to create and leverage a custom Control Panel through the Host Settings.