Theming MODx
From ThemesWiki
| Official Page |
| Project Documentation |
| Download |
|
MODx allows menus to be dynamically created, based on the content available, as documents. Menus are basically a list of documents, and submenus are a list of lists (list within a menu list). In MODx, the simplest way to create lists of all the documents from the nested tables to the simple lines of text is with the use of the wayfinder snippet.
Contents |
[edit] Getting to know WayFinder
WayFinder is a snippet that outputs the structure of the documents as reflected in the document tree. It creates the lists of all the documents that can be accessed by the current user, and those that have been marked as Shown in Menu in the document properties. Let's try out an exercise to discover WayFinder.
1.Create a new document
2.Set the name as testing wayfinder
3.Choose the template as Empty
4.Place the following as the content:
[[Wayfinder?startId=`0`]]
5.Save the document and preview it
You will see a screen like the following:
Notice that it has created a list of all the documents, even the ones from the sample site. And each item is a link, so clicking on it leads you to the corresponding document. The generated HTML will look like the following:
<ul><li><a href="http://localhost/learningMODx/" title="Home"
>Home</a></li>
<li><a href="/learningMODx/index.php?id=2" title="Blog"
>Blog</a></li>
<li><a href="/learningMODx/index.php?id=15" title="MODx Features" >
Features</a><ul><li><a href="/learningMODx/index.php?id=16" title="Ajax" >Ajax</a></li>
<li><a href="/learningMODx/index.php?id=22" title="Menus and Lists"
>Menus and Lists</a></li>
<li><a href="/learningMODx/index.php?id=14" title="Content
Management" >Manage Content</a></li>
<li class="last"><a href="/learningMODx/index.php?id=24"
title="Extendable by design" >Extendability</a></li>
</ul></li>
<li><a href="/learningMODx/index.php?id=33" title="Getting Help"
>Getting Help</a></li>
<li><a href="/learningMODx/index.php?id=39" title="Template Examples" >
Templates</a><ul><li><a href="index.php?id=39" title="MODxHost" >MODxHost</a></li>
<li><a href="/learningMODx/index.php?id=42" title="MODxCSS Wide"
>MODxCSS Wide</a></li>
<li class="last"><a href="/learningMODx/index.php?id=43"
title="MODxCSS" >MODxCSS</a></li>
</ul></li>
<li><a href="/learningMODx/index.php?id=32" title="Design"
>Design</a></li>
<li><a href="/learningMODx/index.php?id=6" title="Contact Us"
>Contact us</a></li>
<li><a href="/learningMODx/index.php?id=57" title="SignUp Form"
>SignUp Form</a></li>
<li><a href="/learningMODx/index.php?id=58" title="Getting to know
ditto" >Getting to know ditto</a></li>
<li><a href="/learningMODx/index.php?id=59" title="Sports Rss"
>Sports Rss</a></li>
<li class="last active"><a href="/learningMODx/index.php?id=60"
title="testing wayfinder" >testing wayfinder</a></li>
</ul>
Let's go step by step in understanding how the above output can be customized and themed, starting with menus of one level.
[edit] Theming
To be able to theme the list generated by WayFinder to appear as menus, we need to understand how WayFinder works in more detail. In this section, we will show you step by step how to create a simple menu without any sub-items, and then proceed to creating menus with sub-items.
[edit] Creating a simple menu
Since, for now, we only want a menu without any submenu item, we have to show documents only from the top level of the document tree. By default, WayFinder will reflect the complete structure of the document tree, including the documents within containers as seen in the preceding screenshot. WayFinder lets you choose the depth of the list with the &level parameter. &level takes a value indicating the number of levels that WayFinder should include in the menu. For our example, since we only want a simple menu with no submenu items, &level is 1.
Now let us change the testing wayfinder document, which we just created, to the following code:
Wayfinder?startId=`0` &level=`1'
Preview the document now, and you will see that the source code of the generated page in place of Wayfinder is:
<ul><li><a href="http://localhost/learningMODx/" title="Home"
>Home</a></li>
<li><a href="/learningMODx/index.php?id=2" title="Blog"
>Blog</a></li>
<li><a href="/learningMODx/index.php?id=15" title="MODx Features"
>Features</a></li>
<li><a href="/learningMODx/index.php?id=33" title="Getting Help"
>Getting Help</a></li>
<li><a href="/learningMODx/index.php?id=39" title="Template Examples"
>Templates</a></li>
<li><a href="/learningMODx/index.php?id=32" title="Design"
>Design</a></li>
<li><a href="/learningMODx/index.php?id=6" title="Contact Us"
>Contact us</a></li>
<li><a href="/learningMODx/index.php?id=57" title="SignUp Form"
>SignUp Form</a></li>
<li><a href="/learningMODx/index.php?id=58" title="Getting to know
ditto" >Getting to know ditto</a></li>
<li><a href="/learningMODx/index.php?id=59" title="Sports Rss"
>Sports Rss</a></li>
<li class="last active"><a href="/learningMODx/index.php?id=60"
title="testing wayfinder" >testing wayfinder</a></li>
</ul>
Now, if we can just give ul and li respective classes, we can style them to appear as a menu. We can do this by passing the class names to the parameter &rowClass.
Change the contents of the preceding testing wayfinder to:
<div id="menu"> !Wayfinder?startId=`0` &level=`1` %rowClass=`menu`! </div>
Now, open style.css from the root folder, and change the CSS to the following. What we are doing is styling the preceding generated list to appear like a menu using CSS:
* { padding:2; margin:0; border:1; }
body { margin:0 20px; background:#8CEC81; }
#banner { background: #2BB81B; border-top:5px solid #8CEC81; border-
bottom:5px solid #8CEC81; }
#banner h1 { padding:10px; }
#wrapper { background: #8CEC81; }
#container { width: 100%; background: #2BB81B; float: left; }
#content { background: #ffffff; height:600px; padding:0 10px 10px
10px; clear:both; }
#footer { background: #2BB81B; border-top:5px solid #8CEC81; border-
bottom:5px solid #8CEC81; }
.clearing { clear:both; height:0; }
#content #col-1 {float:left;width:500px; margin:0px;padding:0px;}
#content #col-2 {float:right; width:300px; margin:0px; padding:30px 0
10px 25px; border-left:3px solid #99cc66; height:500px;}
#content #col-2 div {padding-bottom:20px;}
#menu {
background:#ffffff;
float: left;
}
#menu ul {
list-style: none;
margin: 0;
padding: 0;
width: 48em;
float: left;
}
#menu ul li {
display: inline;
}
#menu a, #menu h2 {
font: bold 11px/16px arial, helvetica, sans-serif;
display: inline;
border-width: 1px;
border-style: solid;
border-color: #ccc #888 #555 #bbb;
margin: 0;
padding: 2px 3px;
}
#menu h2 {
color: #fff;
background: #000;
text-transform: uppercase;
}
#menu a {
color: #000;
background: #2BB81B;
text-decoration: none;
}
#menu a:hover {
color: #2BB81B;
background: #fff;
}
Now preview the page and you will see something like the following:
The HTML code returned will be similar to the following:
<ul><li class="menu"><a href="http://localhost/learningMODx/"
title="Home" >Home</a></li>
<li class="menu"><a href="/learningMODx/index.php?id=2" title="Blog"
>Blog</a></li>
<li class="menu"><a href="/learningMODx/index.php?id=15" title="MODx
Features" >Features</a></li>
<li class="menu"><a href="/learningMODx/index.php?id=33"
title="Getting Help" >Getting Help</a></li>
<li class="menu"><a href="/learningMODx/index.php?id=39"
title="Template Examples" >Templates</a></li>
<li class="menu"><a href="/learningMODx/index.php?id=32"
title="Design" >Design</a></li>
<li class="menu"><a href="/learningMODx/index.php?id=6"
title="Contact Us" >Contact us</a></li>
<li class="menu"><a href="/learningMODx/index.php?id=57"
title="SignUp Form" >SignUp Form</a></li>
<li class="menu"><a href="/learningMODx/index.php?id=58" title=
"Getting to know ditto" >Getting to know ditto</a></li>
<li class="menu"><a href="/learningMODx/index.php?id=59"
title="Sports Rss" >Sports Rss</a></li>
<li class="menu last active"><a href="/learningMODx/index.php?id=60"
title="testing wayfinder" >testing wayfinder</a></li>
</ul>
Notice that for each menu item, the class menu has been applied. Though we have not applied any custom style to the menu class, we have shown you that when you are building more fine-grained menu systems, you have the ability to have every item associated with a class.
[edit] Nested menus
When we have more than one level of the menu structure, we will want different styling for the top menu and the menu items. This effectively means that we need to have different classes for different levels. Also, some menu systems have different styling for the first and the last elements. Such flexibility in styling is also possible with the WayFinder. Let us consider a two-level structure with the class names that we might want illustrated in the side. For this example, the list will be:
<ul>
<li> Menu1 Name </li> outer first
<ul>
<li> Menu item 1</li> inner first
<li>Menu item 2</li> inner
<li>Menu item 3</li> inner
<li>Menu item 4</li> inner last
</ul>
<li> Menu2 Name</li> outer
<ul>
<li> Menu item 1</li> inner first
<li>Menu item 2</li> inner
<li>Menu item 3</li> inner
<li>Menu item 4</li> inner last
</ul>
<li> Menu3 Name</li> outer last
<ul>
<li> Menu item 1</li> inner first
<li>Menu item 2</li> inner
<li>Menu item 3</li> inner
<li>Menu item 4</li> inner last
</ul>
</ul>
The following are the list of parameters that we will need to use to be able to have the respective class names in the generated list:
| Parameter | Definition |
|---|---|
| &firstClass | CSS class denoting the first item at a given menu level |
| &lastClass | CSS class denoting the last item at a given menu level |
| &hereClass | CSS class denoting the "you are here" state, all the way up to the chain |
| &selfClass | CSS class denoting the "you are here" state, for only the current doc |
| &parentClass | CSS class denoting that the menu item is a folder (has children) |
| &rowClass | CSS class denoting each output row |
| &levelClass | CSS class denoting each output row's level; the level number will be added to the specified class (that is, level1, level2, level3, and so on) |
| &outerClass | CSS class for the outer template |
| &innerClass | CSS class for the inner template |
| &webLinkClass | CSS class for weblinks |
Now change the content in the testing wayfinder document to:
<div id="menu"> [Wayfinder?startId=`0` &level=`2` &outerClass=`outer` &innerClass='inner' &lastClass=`last` &firstClass=`first` &hereClass=`active`!] </div>
This code will result in an output similar to the following. Notice that the class names are similar to the structure that we wanted as outlined earlier.
<div id="menu">
<ul class="outer"><li class="first"><a href="http://localhost/learningMODx/"
title="Home" >Home</a></li>
<li><a href="/learningMODx/index.php?id=2" title="Blog"
>Blog</a></li>
<li><a href="/learningMODx/index.php?id=15" title="MODx Features" >
Features</a><ul class="'inner' "><li class="first">
<a href="/learningMODx/index.php?id=16" title="Ajax" >Ajax</a></li>
<li><a href="/learningMODx/index.php?id=22" title="Menus and Lists"
>Menus and Lists</a></li>
<li><a href="/learningMODx/index.php?id=14" title="Content
Management" >Manage Content</a></li>
<li class="last"><a href="/learningMODx/index.php?id=24"
title="Extendable by design" >Extendability</a></li>
</ul></li>
<li><a href="/learningMODx/index.php?id=33" title="Getting Help"
>Getting Help</a></li>
<li><a href="/learningMODx/index.php?id=39" title="Template Examples" >
Templates</a><ul class="'inner' "><li class="first"><a href="index.php?id=39"
title="MODxHost" >MODxHost</a></li>
<li><a href="/learningMODx/index.php?id=42" title="MODxCSS Wide"
>MODxCSS Wide</a></li>
<li class="last"><a href="/learningMODx/index.php?id=43"
title="MODxCSS" >MODxCSS</a></li>
</ul></li>
<li><a href="/learningMODx/index.php?id=32" title="Design"
>Design</a></li>
<li><a href="/learningMODx/index.php?id=6" title="Contact Us"
>Contact us</a></li>
<li><a href="/learningMODx/index.php?id=57" title="SignUp Form"
>SignUp Form</a></li>
<li><a href="/learningMODx/index.php?id=58" title="Getting to know
ditto" >Getting to know ditto</a></li>
<li><a href="/learningMODx/index.php?id=59" title="Sports Rss"
>Sports Rss</a></li>
<li><a href="/learningMODx/index.php?id=61" title="Lifestyle RSS"
>Lifestyle RSS</a></li>
<li><a href="/learningMODx/index.php?id=62" title="IT Rss" >IT
Rss</a></li>
<li class="last active"><a href="/learningMODx/index.php?id=60"
title="testing wayfinder" >testing wayfinder</a></li>
</ul>
</div>
Now preview the page and it will look like the following:
Notice that the inner items are also shown. We will change this behavior by adding some CSS styling to show this inner menu only on hover.
Now, edit style.css to the following:
* { padding:2; margin:0; border:1; }
body { margin:0 20px; background:#8CEC81; }
#banner { background: #2BB81B; border-top:5px solid #8CEC81; border-
bottom:5px solid #8CEC81; }
#banner h1 { padding:10px; }
#wrapper { background: #8CEC81; }
#container { width: 100%; background: #2BB81B; float: left; }
#content { background: #ffffff; height:600px; padding:0 10px 10px
10px; clear:both; }
#footer { background: #2BB81B; border-top:5px solid #8CEC81; border-
bottom:5px solid #8CEC81; }
.clearing { clear:both; height:0; }
#content #col-1 {float:left;width:500px; margin:0px;padding:0px;}
#content #col-2 {float:right; width:300px; margin:0px; padding:30px 0
10px 25px; border-left:3px solid #99cc66; height:500px;}
#content #col-2 div {padding-bottom:20px;}
#menu {
background:#ffffff;
float: left;
}
#menu ul {
list-style: none;
margin: 0;
padding: 0;
width: 48em;
float: left;
}
#menu ul li {
display: inline;
}
#menu a, #menu h2 {
font: bold 11px/16px arial, helvetica, sans-serif;
display: inline;
border-width: 1px;
border-style: solid;
border-color: #ccc #888 #555 #bbb;
margin: 0;
padding: 2px 3px;
}
#menu h2 {
color: #fff;
background: #000;
text-transform: uppercase;
}
#menu a {
color: #000;
background: #2BB81B;
text-decoration: none;
}
#menu a:hover {
color: #2BB81B;
background: #fff;
}
#menu li {position: relative;}
#menu ul ul {
position: relative;
z-index: 500;
}
#menu ul ul ul {
top: 0;
left: 100%;
}
div#menu ul ul,
div#menu ul li:hover ul ul,
div#menu ul ul li:hover ul ul
{display: none;}
div#menu ul li:hover ul,
div#menu ul ul li:hover ul,
div#menu ul ul ul li:hover ul
{display: block;}
Now preview the page; it will look like the following, with submenu items on hover working fine.
Note again that the class name generated above is only for informative purpose, to have a finer-grained menu system when you need it. Had you replaced the call to Wayfinder with [!Wayfinder?startId=`0` &level=`2`!], it would have still worked.
Now that we have the menus appearing in this page, let us make them appear in all the pages. Note that we created this page only for testing, and to find out how WayFinder works. We will need to use the code we have come up with in this page in the default Learning MODx template.
Change the default Learning MODx template to the following:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Learning MODx</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-
8859-1" />
<link rel="stylesheet" type="text/css" href="style.css" />
</head>
<body>
<div id="banner">
<h1>Learning MODx</h1>
</div>
<div id="wrapper">
<div id="container">
<div id="content">
<div id="col-1">
<div id="menu">
[!Wayfinder?startId=`0` &level=`2` &outerClass=`outer`
&innerClass='inner' &lastClass=`last`
&firstClass=`first` &hereClass=`active`!]
</div>
<div id="wrapper">
<div id="container">
<div id="content">
<div id="col-1">
<div id="menu">
[!Wayfinder?startId=`0` &level=`2` &outerClass=`outer`
&innerClass='inner' &lastClass=`last`
&firstClass=`first` &hereClass=`active`!]
</div>
<h1>[*pagetitle*]</h1>
<br/>
[*#content*]
</div>
<div id="col-2">
<div > [!WebLogin!] </div>
<div>
[!Ditto? &parents=`47` &tpl=`dittofrontpage`!]
</div>
</div>
</div>
</div>
<div class="clearing"> </div>
</div> <!-- end of wrapper div -->
<div id="footer">It is fun and exciting to build websites with
MODx</div></body>
</html>
Save the template and preview the Home page. It will look like the following:
Now that you have learned how to theme lists that are two-levels deep, you may be wondering how to theme lists that are more than two-levels deep. You can theme such lists using the levelClass parameter. For example, if you set &levelClass = `level`, then the level items will have the classes level1, level2, level3.
[edit] Changing the name in the menu
Let us change the name of the menu title for the page called 'Getting to know ditto', which lists all the blog entries in RSS format that we created in the previous tutorial on tags. Let us give it a different name for the menu. To do that, perform the following steps:
1.Click on the document and edit.
2.Change the menu title to Feeds.
3.Save the document.
4.Repeat the above steps for the document SignUp Form and change the menu name to Register.
[edit] Doc Manager
Doc Manager is a module that allows you to change the template, template variables, and other document properties of one or more documents. Using the Doc Manager makes it easier to make changes to multiple documents simultaneously. Doc Manager can be accessed from the Doc Manager menu item in the Modules menu. The following is a screenshot of the Doc Manager:
As you can see, it has five tabs:
| Tab Name | Functionality |
|---|---|
| Change Template | Change the template of one or more documents |
| Template Variables | Change the values in the template variables for one or
more documents |
| Document Permissions | Add or remove one or more documents to or from a document group |
| Sort Menu Items | Provides a drag-and-drop menu ordering functionality for the child documents of a selected parent |
| Other Properties | Set document dates, authors, and other Yes/No options such as cacheable, published, and so on, for one or more documents |
The following is the screenshot of Sort Menu Items after selecting the Parent as Learning MODx (root folder) by clicking on it.
Except for Sort Menu Items, all the other actions have a field in the bottom called Specify a Range of Document IDs. The documents on which the changes have to be made are selected by entering the appropriate value in this field. You can specify a single document, or a range of documents, with the – operator. You can specify a document and all its immediate children by entering the document ID followed by an *. You can specify a document and all its children by entering the document ID followed by **. You can have a list of all these syntaxes separated by commas; for example: 10,20-30,5*,8**. This will make the selected changes in:
- Document 10
- Document 20 to document 30
- Document 5 and all its immediate children
- Document 8 and all its children
[edit] Removing pages from the menu
You might notice that menu items are generated even for the pages from the MODx sample site. Since our purpose for having these pages is only to look at them and learn, we do not want them to be appearing in our menus. Also, there are a few pages that we have created to test the functionalities; we will hide them too. You can hide the documents one by one by selecting the document, clicking on Edit, un-checking the Shown in Menu checkbox, and saving the document. Alternatively, you can use the Doc Manager to change the properties for a set of documents.
To change the Shown in Menu setting using the Doc Manager:
1.Click on the Modules menu and the Doc Manager menu item.
2.Click on the Other Properties tab in the right content area.
3.Change Available Settings to Show/Hide in Menu.
4.Select the Hide in Menu checkbox.
5.In Specify a Range of Document IDs, list the IDs for all the documents that you want to hide separated by commas. It can be something like 2*,15*,33,39*,32,6,60. Notice that * stands for the document with the given ID and its immediate children.
Note that the above ID list could be different for you depending on the order you created the documents.
Now click on Preview and the page will look like the following:
[edit] Additional References
For instructions on Installing MODx, click here
[edit] Source
The source of this content is Chapter 7: Theming MODx of MODx Web Development by Antano Solar John (Packt Publishing, 2009).
