MODx 2.0 Web Development [2nd New edition] 1849513481, 9781849513487

This book is an example-driven tutorial, which will take you from the installation of MODx through to configuration, cus

269 147 13MB

English Pages 288 Year 2011

Report DMCA / Copyright


Table of contents :
Cover ......Page 1
Copyright......Page 3
Credits......Page 4
About the Author......Page 5
About the Reviewers......Page 7 9
Table of Contents......Page 10
Preface......Page 18
Manage content......Page 24
An application framework......Page 25
Old school—conventional three tiers......Page 26
Advantages of the conventional three tiers......Page 27
Disadvantages of the conventional three tiers......Page 28
Disadvantages of templating......Page 29
Disadvantages of application frameworks......Page 30
Advantages of content management systems......Page 31
Why MODx?......Page 32
So, why MODx?......Page 33
Summary......Page 34
Prerequisites......Page 36
Windows......Page 37
MAC......Page 38
Verification......Page 39
Downloading MODx......Page 40
Creating a database......Page 41
Starting the installation......Page 43
Installation status and diagnostics......Page 45
Documentation......Page 48
Getting support......Page 49
Web forums......Page 50
Summary......Page 51
Site configuration......Page 52
Configuring the site......Page 53
Default Manager interface page......Page 54
Changing the name of the site......Page 55
The basic element of MODx: Resources......Page 56
MODx Manager interface......Page 57
Using the HTML editor......Page 58
Creating the Front Page......Page 60
DocManager module......Page 62
Editing documents......Page 63
General tab......Page 64
Access permissions......Page 65
Summary......Page 66
Changing the template of a resource......Page 68
HTML......Page 70
CSS......Page 71
Steps to create the new template......Page 72
Choosing a default template......Page 75
Modifying the template to add dynamic behavior......Page 76
Changing existing templates......Page 77
Creating template variables......Page 78
Template variable values......Page 80
Widgets......Page 81
Using a Snippet......Page 82
Creating a resource......Page 83
Blog entry......Page 84
Generating output......Page 86
Using a custom form for the Post a Blog! page......Page 88
Steps to create a chunk......Page 89
Using a chunk as a form template......Page 90
Checking the Post a Blog! page......Page 91
Chunk and template variable......Page 93
NewsEditor and the Rtcontent field......Page 95
Summary......Page 97
Creating a web user......Page 98
Other user properties......Page 100
Add the login snippet......Page 101
Resource group for friends......Page 105
Restricting access for a resource......Page 106
User: User group......Page 107
Creating a role......Page 109
Creating a Manager user......Page 110
Checking the new role......Page 111
Showing a signup form......Page 112
Link the signup form in the log in snippet......Page 113
Snippets and authorization......Page 114
Summary......Page 115
Ditto......Page 116
More flexibility with parameters......Page 117
Aggregated data in a template......Page 118
Theming MODx—chunks and placeholders......Page 120
Introducing tagging......Page 122
Assigning resources to a category......Page 123
Machine-readable formats and readers......Page 124
Ditto and XML formats......Page 125
Creating RSS views for each category......Page 127
Multiple clauses......Page 129
Summary......Page 130
Menu details in document properties......Page 132
Getting to know WayFinder......Page 133
Theming......Page 134
Creating a simple menu......Page 135
Nested menus......Page 138
Changing the name in the menu......Page 144
Doc Manager......Page 145
Removing pages from the menu......Page 148
Breadcrumb navigation......Page 149
Multiple calls......Page 151
Summary......Page 152
Working of snippets......Page 154
Learning about snippets......Page 155
Jot with the minimal configuration......Page 156
Snippet parameters......Page 158
Placeholders......Page 165
Adding a snippet......Page 168
Copying the required files......Page 170
Using the snippet......Page 171
Summary......Page 174
PHx in action......Page 176
Adding Family and Friends resources......Page 177
Template Code:......Page 179
The PHx notation......Page 186
Simple usage......Page 187
Using the PHx placeholder......Page 188
Multiple conditions......Page 189
Summary......Page 190
Installing SMF......Page 192
Installing the SMF module......Page 197
Image gallery......Page 199
Emailing from forms......Page 204
Installing WebLoginPE......Page 208
Edit profile......Page 209
List users and view their profiles......Page 210
Link to edit a profile......Page 211
Similar posts......Page 213
Summary......Page 216
Learning to create a snippet......Page 218
Returning output......Page 219
Returning placeholders......Page 220
Processing a chunk......Page 221
Using parameters......Page 222
$MODx->db->select......Page 224
$MODx->db->makeArray......Page 225
Creating the table......Page 226
Code for fortunes......Page 227
Testing the snippet......Page 228
Chunks, placeholders, and parameters......Page 229
Summary......Page 231
SEO......Page 232
Search engine-friendly URLs......Page 233
Meta tags and keywords......Page 237
Site map......Page 238
Alternative text......Page 240
Filesystem......Page 241
FTP......Page 242
WebDAV......Page 244
Exporting......Page 245
Importing......Page 246
Configuration file......Page 247
Security......Page 248
Captcha......Page 249
Manager configurations......Page 250
Summary......Page 251
Plugins and events......Page 252
Using an existing plugin......Page 253
Configuration......Page 255
System events......Page 256
Using custom plugins......Page 257
Learning about the plugin......Page 259
Creating plugins......Page 260
Modules......Page 262
Executing a module......Page 263
Module's Manager interface......Page 264
Dependent plugins......Page 265
Summary......Page 267
What is similar?......Page 268
What to expect?......Page 269
Tags......Page 270
A peek into Revolution......Page 271
Summary......Page 275
Index......Page 276
Recommend Papers

MODx 2.0 Web Development [2nd New edition]
 1849513481, 9781849513487

  • 0 0 0
  • Like this paper and download? You can publish your own PDF file online for free in a few minutes! Sign Up
File loading please wait...
Citation preview

MODx Web Development Second Edition

Build dynamic websites with MODx PHP application framework and CMS

Antano Solar John


MODx Web Development Second Edition Copyright © 2011 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book. Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information. First Edition: March 2009 Second Edition: March 2011 Production Reference: 2020311 Published by Packt Publishing Ltd. 32 Lincoln Road Olton Birmingham, B27 6PA, UK. ISBN 978-1-849513-48-7

Cover Image by Asher Wishkerman ([email protected])


Author Antano Solar John Reviewers Thayub Hashim Munnavver Ravishankar Somasundaram Development Editor Swapna Verlekar Technical Editors Prashant Macha Manasi Poonthottam Copy Editor Leonard D'Silva Indexer Tejal Daruwale

Editorial Team Leader Mithun Sehgal Project Team Leader Ashwin Shetty Project Coordinators Poorvi Nair Zainab Bagasrawala Proofreader Dirk Manuel Graphics Nilesh R Mohite Production Coordinator Kruthika Bangera Cover Work Kruthika Bangera

About the Author Antano Solar John is a tech evangelist who is passionate about using technology to revolutionize the learning experience. Antano has always had the unique ability of learning new technologies quickly when confronted with the challenge of helping experts in that domain. As an accomplished tech-consultant, many organizations turned to Antano when they had tried almost everything and given up. He got involved in training accidentally and has since then trained thousands of programmers. In the early stages of his career when he was a consultant, he irst came across MODx in its infant stages. He mastered it and went on to author the irst book to be written on MODx. After which he wrote his next book on a Perl MVC framework called Catalyst. Eventually Antano was delivering @ Learning, Business and Technology solutions. Later, he joined NuVeda Learning Pvt Ltd as the Chief Technology Oficer. Here, he co-authored the patent pending learning methodology titled @ CALF(tm) (Continuous Application of Learner's Feedback) Antano in his free time focuses on research in Cybernetics and Neuro Linguistic Programming (NLP) as he aspires to build – "School of Excellence" with the vision of Patterning Scalable Methods for Unconscious Excellence. Antano's irst technical publication while in college was "Help AI Help You - Swiss Knife of Communication" in which he attempted to use the machine's intelligence as a feedback device of human communications. Following which he authored "802.11 MAC Enhancements - Breaking Barriers of Wireless Speed" which was published in an IEEE Journal. Some of Antano's other interests include Music, Dance, Martial Arts and Chess. He used to play Chess professionally as a child-teen. Antano also used to run a successful gaming business when he was in high school through college.

He has also won the yahoo hack award twice, once for developing a Collaborative Browsing Mechanism and consecutively for building a Hybrid Search Engine from scratch.

To those who prepared me, My Mom & Dad – For all the Hope, Faith, Love, and Wise Counsel. And to those who made it happen.

About the Reviewers Thayub Hashim Munnavver has been fascinated by computers and the technologies involved since childhood. He did his tertiary education in Electronics & Communication Engineering at Anna University. Upon graduating, he joined Infosys Technologies Private Limited as a Software Engineer, and worked on the .Net platform, after which he worked as a consultant in Singapore. Currently, he works for NuVeda Learning—a concern that promotes accelerated learning solutions, using technology for people's needs.

I would like to thank my mother without whom none of this would have been possible, and also Shireen and Vinoshini.

Ravishankar Somasundaram has over ive years of experience in providing solutions to clients across multiple sectors and domains. Being more passionate about learning and teaching, he too strongly believes that the sole purpose of learning is to make our minds think in different perspectives, and facilitates the same in his training sessions through a blended learning approach mainly focused on how to "learn to learn". A Junior Scientist in his lower schoolings, in addition to winning several prizes in science projects, being awarded a prize, by a committee consisting of people from ISRO, the Title in an Inter school Science Fest, for a model display on the "Evolution of Airplanes through Aerodynamics", is one of his childhood achievements. His inal-year college project, which was aimed at eliminating the scenario of English alone being the medium of programming in all programming languages, which restricts people who don't know English from getting into the IT ield and implementing their ideas, was selected and funded by MIT NRCFOSS, and is considered a landmark.

Being one of the seven people from India and the only one from Tamilnadu as an oficial third-party developer of Moodle code, Ravi shares his knowledge by helping people on the Moodle oficial forum and on its IRC, he has also presented a paper in the 9th International Tamil Internet conference on "Moodle: For Enhanced Learning". Ravi was a Freelance IT Consultant delivering solutions to irms irrespective of Technical, Non-Technical or Business domains; recently he joined Thirdware Technologies as a Technical Analyst and a Chief Architect heading the R&D Division. Though I am thankful to all of the people I have met till date, for they contributed to the cause of my growth by becoming an inspiration to me, or by personally guiding and pointing me in the right direction when facing challenging situations or by throwing critiques continuously, making me recognize there is always room for improvement in my career and personal life as well, Meeting a few of these people namely Mr.Madhivanan at my lower schooling as Geography teacher, Mr.Baluchamy at my higher schooling as Physics teacher, Mr.L.Sridhar at SISI as my Hardware and Networking course teacher, Mr.Thiyagarajan and MR.Arul at PAV boxing club as my coaches, Mr.Srinivasan at MIT as Project scientist in NRCFOSS as a guide to my inal year B.Tech project, Mr.Antano Solar John at Lynus Academy as my facilitator for perl, Mr.Bala Krishnan at NuVeda as CEO, who completely changed the way I looked at and went about doing things, I am indebted to them. And, of course, I am thankful to my friends Deepak, Karthik Prabhu, Sesha Gopal, Gopinath, Senthil, Siva, Chandru, Venkat, Naveen, Prem, Sarvothaman, Karthikeyan, Rajesh, Pradeep Kumar, Ranjith Kumar, Rajaram, Mangai, Sridevi , Ramya , Shiva Smruthi and more importantly the IRC community and all the wonderful people dwelling there. Last but the foremost I dedicate all of my accomplishments to my parents, sister, and other relations, for all the faith, hope, love and support. Support iles, eBooks, discount offers and more

You might want to visit for support iles and downloads related to your book. Did you know that Packt offers eBook versions of every book published, with PDF and ePub iles available? You can upgrade to the eBook version at www.PacktPub. com and as a print book customer, you are entitled to a discount on the eBook copy. Get in touch with us at [email protected] for more details. At, you can also read a collection of free technical articles, sign up for a range of free newsletters and receive exclusive discounts and offers on Packt books and eBooks.

Do you need instant solutions to your IT questions? PacktLib is Packt's online digital book library. Here, you can access, read and search across Packt's entire library of books.

Why Subscribe? • • •

Fully searchable across every book published by Packt Copy and paste, print and bookmark content On demand and accessible via web browser

Free Access for Packt account holders If you have an account with Packt at, you can use this to access PacktLib today and view nine entirely free books. Simply use your login credentials for immediate access.

Table of Contents Preface Chapter 1: What is MODx? Content management system Manage content Content management rules Deine content An application framework Web development methodologies Old school—conventional three tiers Advantages of the conventional three tiers Disadvantages of the conventional three tiers

Templating Advantages of templating Disadvantages of templating Advantages of application frameworks Disadvantages of application frameworks

Content management systems Advantages of content management systems Disadvantages of content management systems

Why MODx? Why a CMS? Why an application framework? So, why MODx? Overview of the book Summary

Chapter 2: Getting Started Setting up the development environment Prerequisites Linux Windows

1 7 7 7 8 8 8 9 9 10 11

12 12 12 13 13

14 14 15

15 16 16 16 17 17

19 19 19 20 20

Table of Contents MAC


Veriication Downloading MODx Installing MODx

22 23 24

Creating a database Starting the installation Installation status and diagnostics

24 26 28

Documentation Oficial documentation Community-driven documentation Combined Getting support Web forums IRC Summary

31 32 32 32 32 33 34 34

Chapter 3: MODx Basics

Site coniguration Coniguring the site Default Manager interface page Noticing and ixing errors and warnings Changing the name of the site The basic element of MODx: Resources Containers MODx Manager interface Using the HTML editor Creating the Front Page DocManager module Resources revisited Editing documents Resource properties General tab Settings Access permissions

35 35 36 37 38 38 39 40 40 41 43 45 46 46 47

47 48 48



Chapter 4: Templating


Changing the template of a resource Creating a new template and giving it a category HTML CSS Steps to create the new template Making the home page use the created template [ ii ]

51 53 53 54 55 58

Table of Contents

Choosing a default template Introducing template variables Modifying the template to add dynamic behavior Changing existing templates Template variables Creating template variables Template variable values Data source binding Widgets Creating a blog site Using a Snippet Creating a resource Blog entry Snippet and chunk basics Generating output Using a custom form for the Post a Blog! page HTML for the custom blog form Steps to create a chunk Using a chunk as a form template Checking the Post a Blog! page Rich text editor for the blog content Creating the template variable Chunk and template variable NewsEditor and the Rtcontent ield Summary

Chapter 5: Authentication and Authorization Creating a web user Other user properties Add the login snippet Resource group for friends Restricting access for a resource User group: Resource group User: User group Post moderation Creating a role Creating a Manager user Checking the new role User registration Showing a signup form Joining a default group

58 59 59 60 61 61 63 64 64 65 65 66 67 69 69 71 72 72 73 74 76 76 76 78 80

81 81 83 84 88 89 90 90 92 92 93 94 95 95 96

[ iii ]

Table of Contents

Link the signup form in the log in snippet Snippets and authorization NewsPublisher and authentication Summary

Chapter 6: Content Aggregation

96 97 98 98


Ditto More lexibility with parameters Aggregated data in a template Theming MODx—chunks and placeholders Introducing tagging Creating a template variable to hold the category Assigning resources to a category

XML formats Machine-readable formats and readers Readers Ditto and XML formats Creating RSS views for each category

99 100 101 103 105 106 106

107 107 108 108 110



Multiple clauses


Extenders Summary

113 113

Chapter 7: Creating Lists


Menu details in document properties Authentication and authorization Getting to know WayFinder Theming Creating a simple menu Nested menus Changing the name in the menu Doc Manager

115 116 116 117 118 121 127 128

Removing pages from the menu


More theming using chunks Breadcrumb navigation Multiple calls Summary

132 132 134 135

Chapter 8: Snippets


Working of snippets Finding snippets Learning about snippets Jot with the minimal coniguration Snippet parameters

137 138 138 139 141 [ iv ]

Table of Contents

Placeholders Using non-bundled snippets Installing a snippet

148 151 151

Downloading and extracting a snippet Adding a snippet Copying the required iles Using the snippet Snippet without dependent iles

151 151 153 154 157

Snippeting skills Summary

157 157

Chapter 9: PHx


PHx in action Installing PHx Adding Family and Friends resources Template Code

159 160 160 162

The PHx notation Simple usage Conditional statements Using the PHx placeholder Multiple conditions Summary

169 170 171 171 172 173

Chapter 10: Simple Recipes


Forums Installing SMF Installing the SMF module Image gallery E-mailing from forms User proiles Installing WebLoginPE Edit proile List users and view their proiles Link to edit a proile Similar posts Summary

175 175 180 182 187 191 191 192 193 194 196 199

Chapter 11: Creating Snippets


Learning to create a snippet Returning output Returning placeholders Processing a chunk Using parameters MODx API

201 202 203 204 205 207 [v]

Table of Contents



$MODx->db->select $MODx->db->getRecordCount $MODx->db->makeArray

207 208 208

Fortunes Creating the table Code for fortunes Testing the snippet Chunks, placeholders, and parameters Using iles Summary

Chapter 12: SEO, Deployment, and Security SEO Search engine-friendly URLs Meta tags and keywords Site map XHTML Strict Other SEO tweaks

209 209 210 211 212 214 214

215 215 216 220 221 223 223

Using CSS to control the layout Content irst Hidden text Descriptive text Alternative text Cross links Tracking Inbound links Quality content

223 223 223 223 223 224 224 224 224

Deployment Filesystem

224 224


225 227 227



Exporting Importing Coniguration ile

228 229 230

Conigurations Security File permissions Installer Writable coniguration ile Captcha mod_security Unused iles

231 231 232 232 232 232 233 233 [ vi ]

Table of Contents

Manager conigurations


User tab File Manager tab

234 234



Chapter 13: Plugins and Modules


Plugins and events Using an existing plugin

235 236

Using custom plugins


Coniguration System events Exploring other plugins

238 239 240

Learning about the plugin


Creating plugins Event-triggering snippets Modules Using modules

243 245 245 246

Creating a module Executing a module Module's Manager interface Dependent plugins

246 246 247 248

Learning to use custom modules Summary

250 250

Chapter 14: MODx Revolution


Why Evolution, why Revolution… What is similar? What to expect? Tags A peek into Revolution Core technology changes xPDO Sencha and Smarty Join the community Summary

251 251 252 253 254 258 258 258 258 258



[ vii ]

Preface MODx is a content management system and PHP web application framework rolled into one. With the ease of a CMS and the extensibility of a framework, MODx allows you to develop professional-looking, intricate websites via its easy-to-use interface and lexible architecture. MODx provides reusable code called snippets, most of which are so generic that, without any modiication, they can serve multiple purposes. The generic nature of snippets makes it possible to achieve the perfect customization that is so hard to achieve with other CMSes. This book will have web developers up-and-running with MODx. With the use of step-by-step examples and illustrative screenshots, you will be guided through installation, coniguration, and customization of MODx. By the end of the book, you will have created a powerful, dynamic website by using the individual elements of MODx, and without the need for programming know-how.

What this book covers Chapter 1, What is MODx: In this chapter, you learn the general concepts of web development, and also been assured as to why MODx, as a tool, is a good choice for developing your website. The various development methodologies, especially a CMS and a Web Application Framework are explained. With these brieings on the fundamentals, you will have a clear understanding of what MODx is and why you would want to use it. Chapter 2, Getting Started: In this chapter, you learn how to set up a working platform for developing websites with MODx that includes the installation and coniguration of the prerequisites such as Apache, PHP, and MySQL. To make the process easier, you will use XAMPP, which is a bundle containing all of these packages. Finally, you will install MODx and will verify that everything is set and ready.


Chapter 3, MODx Basics: In this chapter, you learn about resources and containers and how every page that is displayed gets it's content from a resource. You also learn to create, edit, and manipulate resources and manage their conigurations, and also receive an explanation of the TinyMCE editor. This chapter also explains each and every coniguration option available for documents, and also the general conigurable options of the site. Finally, you create a Front Page by using what you have learned, and are introduced to the convenience of the DocManager. Chapter 4, Templating: In this chapter, you learn about templates, how to create and add them, and the low of rendering. We learn about template variables and resource speciic variables, data types, Widgets, data sources, snippets, and chunks. You also create a template for the site, a snippet from the web, blog functionality, a custom form template for the blog page, and a rich text editor for the blog. Chapter 5, Authentication and Authorization: In this chapter, you will learn how MODx facilitates authentication and authorization. You will build your site to include user registrations, logins, and user types, and will also set rules on who can do what. Chapter 6, Content Aggregation: In this chapter, you learn about one very useful snippet, called Ditto. You see how to create aggregation and feeds, and how to create feeds for separate categories. You also learn about tagging and how to tag resources and use them in MODx. Chapter 7, Creating Lists: In MODx, the simplest way to create lists of all of the resources is by using the [[wayfinder]] snippet. In this chapter, you learn how MODx allows us to create these lists dynamically, and you also learn how to present these lists as menus. Chapter 8, Snippets: In this chapter, you learn how to use the hundreds of snippets that available, and in detail learn how to use a snippet and navigate its custom functionalities. You also learn how to search for snippets that do not come packaged with MODx, and how to use them. Along the way, you will add the functionality required to post comments and to navigate posts via their posting date. Chapter 9, PHx: In this chapter, you learn how to format the values in template variables, and also see how to make conditional decisions based on the value of template variables, and accordingly present a different output either from the HTML in the expression or from a chunk or snippet. Chapter 10, Simple Recipes: In this chapter, we will use what we have already learned to study how certain commonly-required functionalities can be implemented. We will learn how to integrate a forum, include an image gallery, and develop forms that can send mail, create web user proiles, and identify similar posts for blogs.



Chapter 11, Creating Snippets: In this chapter, you learn how to create snippets and the different ways of rendering their output. You also learn how to use the available MODx APIs as well as why you should use them. You create a new snippet for the site to display a random fortune. The snippet accepts a parameter for a chunk and renders the output by using chunks and placeholders. You also learn how snippets can make use of external iles. Chapter 12, SEO, Deployment, and Security: In this chapter, you learn how to optimize the site for search engines. You learn about clean URLs, meta tags, site maps, and other tweaks. Having developed the site on a local machine, you learn, in this chapter, how to deploy it to a remote server. Finally, you look into what has to be done in order to make your MODx site secure. Chapter 13, Plugins and Modules: In this chapter, you learn about plugins and modules. You learn how to use plugins and how to customize plugins. You also learn how to create new plugins, and analyze the code of the prettify code plugin. Finally, you learn how to use modules by using the Autolink module and plugin. Chapter 14, MODx Revolution: In this chapter, you take a quick look into MODx Revolution, to understand when to upgrade, what to expect, and how to contribute.

What you need for this book No knowledge of PHP programming or any templating language is needed, but the more advanced chapters towards the end of the book will allow more conident developers to extend their applications even further by creating their own snippets. Software required for this book is only the LAMP Stack and, of course, the MODx installation.

Who this book is for This book is ideal for newcomers to MODx. Both beginners and experienced web developers will beneit from this comprehensive guide to MODx. The more advanced chapters towards the end of the book will allow more conident developers to extend their applications even further by creating their own snippets.

Conventions In this book, you will ind a number of styles of text that distinguish between different kinds of information. Here are some examples of these styles, and an explanation of their meaning.



Code words in text are shown as follows: "We can set this right by passing the value of the new template variable using the rtcontent parameter." A block of code is set as follows:

Learning MODx


It is fun and exciting to build websites with MODx

Changing existing templates Follow these steps to change the code of an existing template: 1. Click on the Elements menu in the top navigation panel. 2. Click on the Manage Elements menu item. 3. Click on the template to be edited—in this case, the Learning MODx default template. 4. Replace the existing HTML with the preceding HTML. 5. Click on the Save button to store the changes. 6. Click on the Preview menu item in the Site menu to see the preview. You will see something like the example shown in the following screenshot:

[ 60 ]

Chapter 4

As you can see, the template now displays the page title (Home) before the content.

Template variables We have already discussed a special type of template variable called resourcespeciic variables. In this section, we will cover the creation of template variables that are speciic to templates. We will be using the concepts covered here, throughout the book, for practical examples. This section provides you with a theoretical background that eases the understanding when using template variables in the corresponding chapters. To explain template variables, let us consider a blog site. Each blog entry can have some values attached to it, such as a tag and a rating. A tag is just a value assigned to a blog page that speciies which category this blog page belongs to, and a rating allows the visitors to rate the quality of the blog. All these values, which can be different for each resource, can be stored by using template variables. Hence a template variable is a property of a template that has individual values for each resource using the template. In this section, you will learn the following: • • • • •

Creating template variables The types of values that a template variable can store Different ways that you can allow a user to change the value of a template variable Different sources from which template variables can take their value Different presentational methods for the value of template variables

Creating template variables In this section, you will learn how to create template variables and their various properties, in detail. Start creating your template variable by following these steps: 1. Click on the Elements menu in the top navigation panel. 2. Click on the Manage Elements menu item. 3. Click on the Template Variables tab in the rightmost content area. 4. Click on New Template Variable.

[ 61 ]


You will see a screen like the one shown in the following screenshot:

The following is an explanation of the ields, as displayed on the screen. (You don't have to enter anything at this stage.) •

• • • • • •

Template Variable Name—the name of the template variable that is to be created. Caption—it is like the title of a template variable that makes it easier for you to remember which template variable does what. It is recommended that you use the same name for Caption as the Template Variable Name. Description—a description of the template variable, which will help you to remember its purpose. Input type, Input option values—this is related to the type of value that a variable can store (discussed in the next section). Default Value—the value that this template variable will hold for every document, unless a different value is assigned. Widget, Sort Order—this is related to the presentation methods for the value of template variables (discussed in the following sections). Template Access—this allows you to select which templates can make use of this variable. [ 62 ]

• •

Chapter 4

Access Permissions—this is related to permissions (explained in the next chapter). Category—this is similar to the category concept for templates, as explained in the section Creating a new template and giving it a category. The category is just for your easy identiication.

Template variable values In this section, we will discuss the different kinds of values that a template variable can store. The input type drop-down box allows you to choose the input types for template variables. These will be the input ields that will be added to the document editing page in the Manager. They will appear as new ields below the main Content ield in documents. The following are the different data types that a template variable can store: • • • • • • • • • • • • • • •

Text Textarea Textarea (Mini) RichText DropDown List Menu Listbox (Single-Select) Listbox (Multi-Select) Radio Options Check Box Image File URL Email Number Date

Data types that allow a user to select from choices must deine what those choices are, for example, the drop-down box and listbox values that are deined in the Input Option Values ield. Each option that is available is separated using the following sequence of characters: ||. For example, if you want the user to select between red and yellow, you would change the Input Option Values ield to red || yellow. Such sequences of characters that separate different elements in a list are generally called delimiters. You can also provide a default value for any of the data types, in the Default Value ield. [ 63 ]


Data source binding Data source bindings allow the input option values and the default value to be retrieved from an external source, such as a ile or a database. This can be helpful when there are a lot of values, or values that will change over time. The following is a list of keywords that function as a data source when used in the Input Option Values or Default Value ield: •

• • •

@FILE—gets the data from the contents of the speciied ile; for example, @FILE colors.txt. @DOCUMENT—gets the data from the contents of the given resource ID; for example, @DOCUMENT 22. @CHUNK—gets the data from the contents of the given chunk. Chunks are

discussed in the following sections. @SELECT—gets the data by querying a database. @EVAL—gets the data from the result returned by the given PHP code. @INHERIT—gets the data from the given content. If no content is given,

it looks for the content of the same variable in the parent document, and continues up to the root document until it inds a value. @DIRECTORY—shows the list of iles within a speciied folder

Widgets Widgets format the output of the template variable to be displayed on the inal web page. So Input Type determines what will be displayed when editing the document, and Widgets determine how this will be displayed in the inal web page output. The following is a list of the available widgets in MODx: •

Data Grid



HTML Entities



View Port

• •

Date Formatter Unixtime Delimited List [ 64 ]

Chapter 4

HTML Generic Tag



String Formatter

Each of these options has conigurations attached to it. Certain widget options will be explained in detail, as we use them, in the remaining chapters.

Creating a blog site Now that we have created a template, we can create any number of resources that can use the same template. Now let us extend this behavior further to allow a user to create a resource by using some interface in the site without having to use the Manager interface. In the next section, you will ind the required theory behind what we are going to do. All that we do here is create a resource that shows a form that contains ields relating to a blog post to the end user. When the end user ills in the content and submits the data, a new resource is created.

Using a Snippet For continuing with the rest of the section, we are going to use a snippet called NewsEditor. Previously, this snippet was included with MODx. Later in the book, we further discuss installing and creating your own snippets. For the purpose of this chapter, it is enough to get the snippet installed and functioning by doing the following: 1. Download the Snippet folder from dl.html?file=506, and extract it. 2. In the Manager interface, click on the Manage Elements menu item in the Elements menu. 3. Click on the Snippets tab, and then click on the New Snippet link. 4. Give the snippet name as NewsEditor. 5. Paste the code from the ile NewsEditor.txt from the downloaded folder into the snippet code area. 6. Make sure that you have copied and pasted the code from the ile within , such that the start of the code is after . You may ill in a description, if you like, and then click on the Save button.

[ 65 ]


Creating a resource We will now create a resource to show a basic blog form and then process the posted data. Create the new resource by clicking on the new resource icon in the left panel. Populate the following ields, and then save the document: Field Name Title

Field Post a Blog!

Long Title

Post a Blog!


This page allows a user to post a blog entry


Learning MODx default template (should have been selected by default)

You will ind the newly-created document and its assigned ID. You will be using this ID in the following steps. It will be referred to as PID. 1. Click on the document, and then click Edit. 2. Change the Editor of Document Content to none. 3. Fill the Document Content with the following content: [!NewsEditor &folder=`PID` &makefolder=`1`!]

Use the back-tick character (`) and not a single quote ('). There should not be any line breaks between [! and !]. In other words, do not click Enter in the middle of the statement. Sometimes, when the string is longer, the browser displays it in multiple lines. That is ine, but there should not be line breaks. There should not be any spaces between the [! and the template variable name like [! TVName. 4. Replace PID with the ID of the current document. (The ID is highlighted in the following image.)

[ 66 ]

Chapter 4

The preceding screenshot shows the ID of the document and that being used as the PID in the snippet call. 7. Save the document.

It is possible to refer to the current resource by using [*id*].

Blog entry Now that you have created a mechanism to post a blog entry, let us see how it works. Right-click on the newly-created document, and then click on Preview.

[ 67 ]


You will see a page like the one shown in the following screenshot:

Fill in the ields with the following information, and then click on the Submit button: •

Page title: My First Blog

Description: Posting a blog using the Post a Blog! page

Unpublished date: leave empty

Long title: My First Blog in my own site

Published date: leave empty

Summary: Blogging is fun Content: Let's all start blogging

A new resource is created and displayed. Now, in the manager folder, click on the refresh icon in the left panel, and you will notice that the blog creation page has turned into a folder with a + symbol. If you click on it, you will see that it contains the newly-created resource.

[ 68 ]

Chapter 4

You have now successfully created a basic blog interface and have also posted a blog entry. It is time to understand what is happening and to tweak the interface a bit.

Snippet and chunk basics Snippets are executable PHP code objects that provides some functionality when called. In the previous example, NewsEditor is a snippet. The only content of the Post a Blog! page was the call to the NewsEditor snippet; the snippet takes care of displaying a form and storing the values entered through it as a new document. There is a whole chapter on Snippets in this book (Chapter 8, Snippets). In this section, you will learn the bare minimum about snippets that is necessary to follow along in the ensuing chapters.

Generating output Most snippets return an output that gets shown in the template at the same location from which the call to the snippet was made.

[ 69 ]


Such output can be returned by snippets in two ways: •

Return the HTML: In this method, there is less control over what the snippet returns. Changes in the returned output can only be made by editing the snippet code, as the snippet has the HTML that has to be returned within the snippet code. Use chunks: Snippets can render output by using chunks that use placeholders in the same way that a template does. The snippet can create these placeholders and store values in them. When a snippet uses chunks to render output, each placeholder that the chunk will be using is created and its value is assigned by the snippet. Then the template renders a chunk by replacing the placeholders in the chunk with their values.

Let us look into the call that we made to the NewsEditor, again. [!NewsEditer? &folder=`PID` &makefolder=`1`!]

There are a few things to note here: •

• •

Calls to snippets can be made by enclosing the snippet name within [! and !] A snippet can accept parameters that can alter its behavior, such as folder and makefolder in the last example Parameters are passed as a key and value pair in the format key=value The snippet name and the parameters are separated by the ? symbol, which follows immediately after the snippet name Every parameter has an & symbol appended to the key The values of parameters are contained within ` symbols

Snippet calls can also be made by enclosing the snippet name within [[ ]]. The difference between [[ ]] and [! !] is that the former is cached and the latter is uncached. Caching is a technique that is used to improve performance by saving a processed value to avoid processing it again on further calls. In MODx, resources can be cached. When we use the uncached notation for calling snippets, the snippet will still be processed, in order to ensure that the content of the snippet is always dynamic, even in a cached page. It does not matter in an uncached page as in an uncached page, the snippet is always processed, irrespective of the notation. NewsEditor is a snippet that displays a form and stores the posted information as

a resource. It can be conigured to work in many different ways, depending on the parameters passed along. We will discuss this in more detail in the chapter on Snippets. The following list explains a few parameters that are of interest in this chapter:

[ 70 ]

• • • • •

Chapter 4

folder—speciies under which container the newly-created resources should

be placed makefolder—if the given value for the parameter above is only a resource

and not a container then, the value in this parameter controls whether or not the resource is automatically converted to a container formtpl—a customized form is shown from a chunk speciied by this parameter rtcontent—when this is speciied, the given ield will be treated as rich text instead of raw text Template—the resource that is created by NewsEditor will use the template

mentioned here Having created a simple blog interface, we are going to make two enhancements by using what we have learned, which will be explained in the following sections.

Using a custom form for the Post a Blog! page To customize the form, all that we need to do is create a form in HTML, save it as a chunk, and then pass the name of this chunk as the value of formtpl to NewsEditor. We need a mechanism by which we can let the NewsEditor snippet know which text ield, from the resource, gets stored as which property. For example, we might have a title, summary, and content, and we will want the title to be saved as the resource-speciic variable longtitle, the summary as the resource-speciic variable description, and the content ield as the content of the resource. This has to be explicitly speciied, as NewsEditor has no ability to make guesses about which ield gets stored as what in the resource. When using a chunk as a form template along with NewsEditor, the speciication of what ield gets stored as what variable in the resource is done by setting the name attribute of the form element to the resource-speciic variable. The following is the HTML for the custom blog form. There are more concepts to discuss on snippets like NewsEditor and how to use chunks with them. These are dealt with in the later chapters.

[ 71 ]


HTML for the custom blog form The following is the code for the chunk that will be used by the NewsEditor snippet, in order to render a custom form:

Blog Entry

Summary [+introtext+]
Content [+content+]

Steps to create a chunk Now that we have the HTML ready for the chunk, we will create the chunk in this section. 1. Click on the Manage Elements menu item in the Elements menu. 2. Click on the Chunks tab, and then click on New Chunk. 3. Fill in the following data in the new chunk page:

[ 72 ]

Chapter 4

Field Name


Chunk name



Form template for posting a blog

Existing Category

Learning MODx

Chunk code

The HTML above

Editor to use


4. Click on the Save button.

Using a chunk as a form template The following are the steps necessary to make NewsEditor use the created chunk as the form template: 1. Click on the Post a Blog! resource, and then click on Edit. 2. Replace the document content with the following: [!NewsEditor? &folder=`47` &makefolder=`1` &formtpl=`blogform` &template=`Learning MODx blog`!]

[ 73 ]


Note that you will have to replace 47 with the ID of the resource Post a Blog! and make sure that the entire snippet call is, as mentioned earlier, in a single line without a line break. It is alright if the browser displays it as two lines, but there should not be a line break in the code.

3. Click on the Save button. Also, as you can guess from the snippet call, we are creating a new template for all blogs. For now, this template will be the same as the Learning MODx default template. To create the template, carry out the steps shown below: 1. Open the Learning MODx blog template from Templates in the Manage Elements submenu. 2. Click on Duplicate, and click Ok when asked. 3. Change the template name to Learning MODx blog template. 4. Select the Category as Learning MODx. 5. Click on Save.

Checking the Post a Blog! page Now that we are using a custom form template, let us check to see if it works. 1. Right-click on the Post a Blog! page, and then click on Preview. 2. Fill in the ields with the following content, and then click on the Blog it! button: Field Name Title

Value My Second Blog Entry


Just created a custom blog template


It is simple and quick to allow well written snippets to take advantage of custom formatting using chunks

[ 74 ]

Chapter 4

You will see the posted blog entry on a new page:

[ 75 ]


Rich text editor for the blog content To provide a rich text editor for the blog content area, all that has to be done is to replace the content area with a template variable that is of the rich text type and uses the rich text widget. This way, MODx provides a rich-text editor automatically when the form is being illed in or edited. This is a three-step process: • • •

Creation of the template variable Making the form template chunk use the template variable Letting NewsEditor be aware that the content ield has changed to the new template variable

Creating the template variable 1. Click on the Manage Elements menu item in the Elements menu. 2. Click on the Template Variables tab, and then click on New Template Variable. 3. Fill in the ields with the following values: Field Name Template Variable Name

Value blogRT


Template Variable to store rich text for the blogs

Input Type

Rich Text


Rich Text

Widget width


Widget height




Template Access

Learning MODx default template

Existing Category

Learning MODx

4. Click on Save.

Chunk and template variable Now that we have created a template variable with the rich text widget, let us modify the form template to use it. The HTML of the blogform chunk has to be replaced with the following:

[ 76 ]

Chapter 4 Blog Entry

Summary [+introtext+]
Content [*blogRT*]

Instead of calling a form ield, such as textarea, with the name of the resource-speciic variable, we have replaced that line with a call to the template variable (see the highlighted line in the previous code). This single line performs all of the necessary functionalities to make the template variable editable, by using the selected widget according to the content type. To replace the previous HTML in the form template chunk, do the following: 1. Click on the Manage Elements menu item in the Elements menu. 2. Click on the Chunks tab. 3. Click on the blogform chunk. 4. Replace the HTML in the Chunk Code area with the previous HTML. 5. Click on Save.

[ 77 ]


Now, right-click on the Post a Blog! page, click Preview, and you will see something like the example shown in the following screenshot:

NewsEditor and the Rtcontent ield

You have now enabled the content ield to use the rich text editor. However, NewsEditor is still expecting the blog content to come from a form ield with the name Content. Hence, when it is saving the form, it will throw a validation error stating that the news content is missing. When you try to post a blog entry now, the following is the error that you will get:

[ 78 ]

Chapter 4

We can correct this by passing the value of the new template variable by using the rtcontent parameter. To do that, edit the Post a Blog! page, as mentioned in the previous sections, and replace the code with the following: [!NewsEditor? &folder=`47` &makefolder=`1` &formtpl=`blogform` &template=`Learning MODx blog` &rtcontent=`tvblogRT` !]

Save the document and preview it.

[ 79 ]


Now, you will be able to use the rich text editor for the content area and post blogs. Go ahead and post a few blogs to check if it works.

Summary In this chapter, you have learned about: •

Templates ° °

Flow of rendering

Template variables and resource speciic variables ° °



Data types Widgets Data sources

Snippets and chunks

You have also, during the process, created: • •

A template for the site

Blog functionality

A snippet from the web

Custom form template for the blog page A rich text editor for the blog [ 80 ]

Authentication and Authorization Authentication is the process of verifying that users are who they claim to be. Authorization is the process of granting access to authenticated users—based on their role—to perform operations such as view, edit, or delete for resources. In this chapter, you will learn how MODx facilitates authentication and authorization. You will build your site to include user registrations, logins, and user types, and will also set rules on who can do what. As you read this chapter, it is important that you keep in mind that MODx has two user types: • •

Web Users—users who use the website Manager Users—users who are allowed to log in to the Manager interface

It is vital to keep this distinction in mind in order to be able to understand the complexities explained in this chapter. You will also learn in this chapter how MODx allows the grouping of resources, users, and permissions.

Creating a web user Let us start by creating a web user. Web users are users who can access restricted resource groups in the website (frontend); they do not have Manager access. Web users can identify themselves at login by using login forms. They are allowed to log in from the user page, but they cannot log in using the Manager interface. To create a web user, perform the following steps:

Authentication and Authorization

1. Click on the Web Users menu item in the Security menu. 2. Click on New Web User. 3. Fill in the ields with the following information: Field Name






Email Address

[email protected]

4. Click on the Save button. Now you will see a page like the example shown in the following screenshot, which lists all of the web users on your site:

[ 82 ]

Chapter 5

Other user properties When you click on any user on the web users' page, a page opens that allows you to edit the existing information and also shows simple statistics, such as when the user last logged in. It is also possible to block or unblock the particular user from this page. You can also set Blocked Until or Blocked After to block a user for a certain period and to schedule such a block. When a user is blocked, MODx does not allow that user to log in. There is also a Photo tab, where you can upload a picture for a user. In the User tab, you have the following ields: • •

Login Home Page: Here you can specify the document that the user is shown immediately after login. Allowed IP Address: It is possible to allow certain users to log in only from speciic machines. This can be set for a particular user by specifying the IP address of the machines in this ield, separated by a comma.

[ 83 ]

Authentication and Authorization

Allowed Days: It is possible to allow certain users to log in only on certain days of the week. This can be set for the particular user by selecting which days the user is allowed to log in.

Add the login snippet Now that we have created a user, let us add a login form that allows the user to log in to the site. This process is very simple. All that you have to do is call the WebLogin snippet in the template where you want the login page to be shown. We are going to change the template HTML with the following HTML for the Learning MODx default template:

Learning MODx

[ 84 ]

Chapter 5

Learning MODx



It is fun and exciting to build websites with MODx

Click on Preview, and you will see something like the following:

[ 102 ]

Chapter 6

Theming MODx—chunks and placeholders Ditto, like any other snippet, allows theming using placeholders. That is, instead of the snippet returning the complete HTML for each extract of a resource, the snippet returns variables such as content, title, date created, author, and so on, which can be used in a custom chunk. Hence, the chunk will be called for every resource that Ditto is aggregating. Whatever HTML the chunk gets processed into will be the output for that resource. Let us consider a chunk code like the following: [+title+] [+introtext+]

The previous chunk shows the title of the document, along with a link and the summary. Suppose there are three resources that are aggregated by a particular Ditto call. If that call to Ditto has a parameter that mentions that the preceding chunk should be used as the template, then the chunk will be processed three times, once for each resource. The appropriate title and author name would be inserted for each iteration. The following is a list of some of the most commonly-used Ditto placeholders. •

• •

[+title+]—shows the title of the resource [+summary+]—shows the summary, if it is not empty, or shows an extract

from the resource content [+link+]—creates a Read More... link to the resource [+author+]—shows the name of the author in the Created by ield [+id+]—shows the ID of the resource

Now, let us go ahead and theme the aggregation that we have created: 1. Create a chunk with the following data: Field Name Title Chunk Code

Value dittofrontpage [+title+] [+introtext+]

2. Change the Learning MODx default template to the following:

[ 103 ]

Content Aggregation

Learning MODx

Learning MODx



[!Ditto? &parents=`47` &tpl=`dittofrontpage`!]

It is fun and exciting to build websites with MODx

Save the template, and then preview the Home page. It will look like the example shown in the following screenshot:

[ 126 ]

Chapter 7

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 by using the levelClass parameter. For example, if you set &levelClass = `level`, then the level items will have the classes level1, level2, level3. [!Wayfinder?startId=`0` &level=`5` &outerClass=`outer` &innerClass='inner' &lastClass=`last` &firstClass=`first` &hereClass=`active` &level2=`xxx` &level3=`yyy`!]

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 of the blog entries, that we had created in the previous chapter when we learned to use template variables for tagging in RSS format. To do that, perform the following steps: 1. Click on the resource Getting to know ditto and edit it. 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. [ 127 ]

Creating Lists

Notice that the menus have changed, as shown in the following screenshot:

Doc Manager Doc Manager is a module that allows you to change the template, template variables, and other resource properties of one or more resources. Using the Doc Manager makes it easier to make changes to multiple resources 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:

[ 128 ]

Chapter 7

As you can see, it has ive tabs: Tab Name


Change Template

Change the template of one or more resources

Template Variables

Change the values in the template variables for one or more resources

Document Permissions Add or remove one or more resource to or from a resource group Sort Menu Items

Provide a drag-and-drop menu ordering functionality for the child resources of a selected parent

Other Properties

Set resource dates, authors, and other Yes/No options, such as cacheable, published, and so on, for one or more documents

[ 129 ]

Creating Lists

Following is a screenshot of Sort Menu Items after selecting the Parent as Learning MODx(0) - the root folder. The parent for sort menu items was selected done by clicking on it and then clicking on Go.

Note that this module still calls resources as documents, as they were called in earlier versions of MODx. So you can safely substitute the word document with resource when you come across it here in this module. With the exception of Sort Menu Items, all actions have a ield at the bottom called Specify a Range of Document IDs. The resources on which the changes have to be made are selected by entering the appropriate value in this ield. You can specify a single resource, or a range of resources, with the operator. You can refer to a resource and all of its immediate children by entering the resource ID followed by an *. You can specify a resource and all its children by entering the resource ID followed by **. You can have a list of all of these syntaxes, as long as they are separated by commas; for example: 10,20-30,5*,8**. This will make the selected changes in: • •

Resource 10

Resource 5 and all of its immediate children

Resources 20 to resource 30 Resource 8 and all of its children [ 130 ]

Chapter 7

Removing pages from the menu You might notice that menu items are generated even for pages from the MODx sample site. Because 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 functionality; and we will want to hide these, too. You can hide resources one by one by selecting the resource, clicking on Edit, deselecting the Shown in Menu checkbox, and then saving the resource. 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, carry out the following steps: 1. 2. 3. 4. 5.

Click on the Modules menu, and then select the Doc Manager menu item. Click on the Other Properties tab. Change the Available Settings to Show/Hide in Menu. Select the Hide in Menu checkbox. In the Specify a Range of Document IDs ield, list the IDs for all of the documents that you want to hide separated by commas. It can be something like 2*,15*,33,39*,32,6,58. Notice that * stands for the document with the given ID and its immediate children.

Note that the preceding ID list could be different for you depending on the order in which you created the documents.

[ 131 ]

Creating Lists

Now click on Preview and the page will look like the example shown in the following screenshot:

More theming using chunks Now that we have learned how to give custom class names for generated
  • unordered lists, we are able to theme them by having the corresponding styles for the classes. What if we wanted to have a list that is not a
    • type? Alternatively, what if we wanted to have more control over how the list is generated? WayFinder also allows the user to customize the structure of the generated lists, by using chunks. Similar to the use of custom classes, WayFinder has separate parameters that specify which chunk to use for which level, and so on. As with any chunk, the dynamic content comes from the available placeholders that are set by the snippet (in this case it is WayFinder). In this section, we will look at breadcrumbs and discuss the parameters that are used for creating the breadcrumb trail.

      Breadcrumb navigation Breadcrumbs are those small links that you generally see at the top of a page that help you to understand which part of the site you are in and how you got there. [ 132 ]

      Chapter 7

      For example, if you are accessing a blog entry inside a blog folder, then the breadcrumb would be: home>>blog>>blogname

      In the preceding example, home and blog are links to take you to the roots of the current document. Following is the code and an explanation of how breadcrumbs can be created in MODx using WayFinder. Home » [!Wayfinder? &startId=`0` &outerTpl=`BreadCrumbOuter` &rowTpl=`BreadCrumbRow` &activeParentRowTp l=`BreadCrumbActiveParentRow` &hereTpl=`BreadCrumbHere`!]

      » gets converted to >>. The previous call to Wayfinder uses different

      chunks for different levels in order to process and create the list. It will be easier to understand the wrapper placeholders if you remember the following concepts: • • • •

      The call to WayFinder generates resource lists based on the given parameters For each resource in the resource list, the placeholders in the appropriate chunk are replaced by the values from the resource The chunks being used are determined by the value of the corresponding snippet parameter The innermost document list is generated irst, and then it is followed by the outermost document list


      Given Chunk Name


      Bread When CrumbOuter processing


      Bread Crumbrow

      For what items the chunk will be called

      Code for the chunk

      Explanation of the code


      The template variable [+wf.

      the outmost container. (What it should be instead of
      for the outermost level.)

      speciies where the innermost content will be inserted.

      When processing each resource in the resource list. (What it should be instead of
    • for every level.)

      We leave it empty, as for the breadcrumb, we want only the current item and the parent item of the current item to be shown.

      [ 133 ]


      Creating Lists


      Given Chunk Name

      For what items the chunk will be called

      Code for the chunk

      Explanation of the code

      Active BreadCrumb When [+wf. of the current linktext+] resource. » [+wf. wrapper+]

      We display a link for the parent resource by using the placeholders for link, title, and linktext. Then we specify where the inner contents should be inserted. (If it is a parent resource, it deinitely has at least the current resource as the inner level resource.)


      We show the current resource's menu title here, as we do not want a link to the resource when we are already on that page.

      Bread CrumbHere

      When processing the current resource.


      Multiple calls It is possible to have multiple calls to WayFinder within the same document or template. This might be necessary when you want to have multiple menu systems in the same page. For instance, you might want to have a primary menu at the top and additional menus on the left or right. You can have one call to WayFinder for the menus, one for the breadcrumb trail, and so on. To do this, you will only have to place the corresponding WayFinder snippet calls at the appropriate positions in the template being used.

      [ 134 ]

      Chapter 7

      Example structure: HTML

      It is fun and exciting to build websites with MODx

      [ 139 ]


      Now preview any of the posted blogs and it will look like the example shown in the following screenshot:

      To change the default form, we have to ind the parameter for the snippet that we can use to specify the chunk to use. Then we need to learn which placeholders can be used in the chunk. Let's test if Jot is actually working by posting a comment. Following is a screenshot of how it looks after posting a comment.

      [ 140 ]

      Chapter 8

      Note that some snippets vary their functionality based on whether you are logged in as a manager or not. Log out from the Manager interface, refresh the page, and it will appear like the example shown in the following screenshot:

      Notice that the moderation links are missing in this screen.

      Snippet parameters Snippet parameters, as you have already learned, are what allow you to control the functionality of a snippet. A parameter takes one or more value after the = sign. The parameter itself is preceded by an &. Now, have a look at the available Jot parameters , as listed on the web page given earlier. We want to conigure the behavior of Jot in two ways, and hence we need to identify the appropriate parameters to conigure it. •

      Restrict comments to authenticated users—&canpost Theme the comment form—&tplForm

      The value that has to be passed to &tplForm is the name of the HTML chunk to be used for the form. &canpost takes a comma-separated list of the names of the groups that are allowed to post comments. Now let us change the highlighted call to Jot, in the preceding code of the Learning MODx blog template, to the following: [!Jot? &canpost=`Registered Users`!]

      [ 141 ]


      Now log out of the Web interface, log out of the Manager interface, and preview the blog page. It will appear like the example shown in the following screenshot:

      You won't see the comment form. This is because of the preceding call where we speciied that only allow registered users should see the comment form, by assigning &canpost=`Registered Users in the Jot snippet call. Now log in through the Web interface as samira, the user that you created in a Chapter 5, Authentication and Authorization, and the page looks like the example shown in the following screenshot:

      As you can see, the comments form is now available. If you still do not see the comment form, click on the user samira from the admin manager and make sure the user is assigned to the Registered Users group. [ 142 ]

      Chapter 8

      Now that we have achieved the irst of our two objectives (to restrict comments to registered users), let's get started with the second objective (theming the comment form). First, we need to specify which chunk to use as the custom form. For this, modify the preceding call to Jot to the following. [!Jot? &tplForm=`comments` &canpost=`Registered Users`!]

      Preview any comment page and it should look like the example shown in the following screenshot:

      Notice that instead of the comments custom form, we see the static text comments. This is because Jot was unable to ind the chunk named comments. Now, just for demonstration purposes, let us create a chunk with the following details: Field Name





      Testing the comment form


      Learning MODx

      [ 143 ]


      If you preview the page now, it will look like the example shown in the following screenshot:

      As you can see, the static text from the chunk comments, "Testing the comment form" has been replaced. Now, instead of this static text, what we require is a form that Jot can understand. In the case of Jot, there is no documentation, as of the time of writing, on how to write a form chunk for Jot. When you come across situations like this, you can understand what a snippet expects in a custom form by opening its own default templates. The wiki documentation states that the default templates are in the jot/ template directory. The next section of this chapter has more details on this. For now, just understand that we are opening a ile named from the assests/snippets/jot/templates/, and this ile has the following code:

      [+form.edit:is=`1`:then=`Edit comment`:else=`Write a comment`+]

      • Required fields are marked with *.


      [+form.error:select=` &-3=You are trying to re-submit the same post. You have probably clicked the submit button more than once. &-2=Your comment has been rejected. &-1=Your comment has been saved, it will first be reviewed before it is published. [ 144 ]

      Chapter 8 &1=You are trying to re-submit the same post. You have probably clicked the submit button more than once. &2=The security code you entered was incorrect. &3=You can only post once each [+jot.postdelay+] seconds. &4=Your comment has been rejected. &5=[+form.errormsg:ifempty=`You didn't enter all the required fields`+] +]

      :strip+] [+form.confirm:isnt=`0`:then=`

      [+form.confirm:select=` &1=Your comment has been published. &2=Your comment has been saved, it will first be reviewed before it is published. &3=Comment saved. `+]



      Created on: [+form.field.createdon:date=`%a %B %d, %Y at %H:%M`+]
      Created by: [+form.field.createdby:userinfo=`username`:if empty=`[+jot.guestname+]`+]
      IP address: [+form.field.secip+]
      Published: [+form.field.published:select=`0=No&1=Yes`+]< br /> [+form.field.publishedon:gt=`0`:then=` Published on: [+form.field.publishedon:date=`%a %B %d, %Y at %H:%M`+]
      Published by: [+form.field.publishedby:userinfo=`userna me`:ifempty=` - `+]
      `+] [+form.field.editedon:gt=`0`:then=` Edited on: [+form.field.editedon:date=`%a %B %d, %Y at %H:%M`+]

      [ 145 ]

      Snippets Edited by: [+form.field.editedby:userinfo=`username`:if empty=` -`+]

      `:strip+] [+form.guest:is=`1`:then=` Name:


      `:strip+] Subject:

      Comment: *

      Help prevent spam - enter security code above:


      [ 146 ]

      Chapter 8 `+]

      Let us test what we have learned by just copying this code without any change to the comments chunk, and then preview it. You will see the same form that you saw before, but using a custom chunk.

      The preceding template uses PHx, which is explained in the next chapter. For now, let us just make a simple modiication to the rendered form. Modify the chunk comments in line two from: [+form.edit:is=`1`:then=`Edit comment`:else=`Write a comment`+]

      to: [+form.edit:is=`1`:then=`Edit comment`:else=`Write a comment`+]

      [ 147 ]


      Preview any comments page and it will look similar to the example shown in the following screenshot:

      We have successfully changed the appearance of a speciic element of the form from a heading to just bold text. Although we have changed only one line, using the same principles that you have just learned, you can change the appearance of the form to make it look any way you like.

      Placeholders Placeholders are similar to variables that can be placed within a chunk or a template. In the place of the placeholder, whatever value the snippet assigns to the placeholder will be inserted into the chunk or template during the processing of the snippet code. As we have already seen, most snippets provide placeholders that can be used in an HTML document, such as the wayfinder snippet, which we came across earlier in the previous chapter on lists.

      [ 148 ]

      Chapter 8

      Snippets like Jot provide many uses for placeholders. In the case of Jot, it has a comment form and the comments themselves. Maybe you want to change the order in which the details of comments are displayed by default. To do this, we can provide appropriate parameters to tell Jot to not output anything, but rather to set values for the placeholders that contain the details for the individual elements. Then we can place those placeholders in the templates in the order that we want. As an example, by default the comments are shown below the comment form. Let us go ahead and change this behavior to show the comments form after the comments. The irst step is to let Jot know that we are not expecting one whole output that gets inserted in the place where Jot was called, but rather we want the separate elements to be placed in the placeholders. To do that, change the call to Jot in the Learning MODx blog template to contain &placeholders=`1` & output=`0`. [!Jot? &placeholders=`1` &output=`0` &tplForm=`comments` &canpost=`Registered Users`!]

      Now if you preview any post, you will notice that the comments and the comment form have disappeared. This is as good as not having made a call to Jot at all. However, there is one difference, which is that now we have placeholders that contain the output, and we can place these placeholders anywhere in the template. A few of the available Jot placeholders are: •

      [+jot.html.navigation+]—places the navigation on the page [+jot.html.comments+]—places the comment on the page [+jot.html.moderate+]—places the moderation info on the page [+jot.html.form+]—places the form on the page

      Let us use these placeholders in the Learning MODx blog template to get the form, comments, moderation info, and navigation in the order that we want. Change the contents of the Learning MODx blog template to the following:

      Learning Modx

      Learning MODx [ 149 ]


      [!Jot? &placeholders=`1` & output=`0` &tplForm=`commentscustom` &canpost=`Registered Users`!]

      [+jot.html.comments+] [+jot.html.form+]


      It is fun and exciting to build websites with MODx

      Notice that the value of the calSource parameter must be the ID of the document that you just created. Replace 59 with the ID of your DittoCal document. Visit the home page and it will look like the following.

      [ 156 ]

      Chapter 8

      Notice the calendar below the blog posts.

      Snippet without dependent iles

      Some snippets don't require any iles. For such snippets, we don't have to perform step 3, above. An example of such a snippet is tagcloud.

      Snippeting skills Finding the right snippet for the right functionality is a skill in itself. There are many ways to search for the most appropriate snippet. First, you need to identify the most apt and speciic words that explain what you want your snippet to do, and then you can use a search engine with those words and 'MODx'. You should also search in the MODx forums, as mentioned in Chapter 2, Getting Started. Finally, you can browse through the MODx extras page. If you are not able to ind what you are looking for, you can also ask in the forums.

      Summary In this chapter, we have learned how to use the hundreds of snippets available in detail. We have also learned how to search for snippets that do not come packaged with MODx, and how to use them. Along the way, we have added the functionality to post comments and to navigate posts via their posting date. [ 157 ]

      PHx So far in this book, we have learned how to develop our MODx site by using templates, resources, and chunks, along with snippets. Snippets provide the power of having decisions made and interacting with the databases. In short, the logical component is abstracted to the snippet, whereas the resources, templates, and chunks provide a way to show the content returned by a snippet, or the contents of a variable. In some cases, it may be necessary to perform simple conditional checks within the resources, or templates themselves. PHx—Place Holders extended—is a set of notations that makes this possible by adding a logic layer directly to the placeholder. PHx also makes it possible to format the output, for example by converting a string to uppercase, and so on. In this chapter, we will learn how to use this notation.

      PHx in action Let us learn how to use PHx by building a new functionality for our site that lets us add proiles of our family members and friends. We will add a new page called Family and Friends that will display a list of all of the individuals that we add. Once the user clicks on an individual, the site will show certain details such as the individual's name, their relationship with you, their occupation, their website, and so on. This is easy to implement; all that we have to do is to create the template variables for each of the ields, and create a template that uses these template variables. So, to display the Occupation, the template will have a code similar to the following: Occupation: [*occupation*]

      Although this might appear to work initially, there is a small glitch. When we are entering the personal details of an individual, we may not want to enter all values for every individual. In the case of not having a value for the variable, it looks cleaner to not show the label at all instead of leaving it blank. In our case, if we have no value for an occupation, it will look cleaner to not show the label Occupation. So here comes a need for displaying certain text only if the template variable—in this case, occupation—has a value. We can do this by using PHx without having to write a snippet.


      Installing PHx To download PHx, use the following steps: 1. Download PHx from package/?package=342. 2. Extract the contents of the downloaded ile. 3. Create a directory called phx in the assets/plugins folder of your MODx root. 4. Copy all of the iles within the extracted folder to the assets/plugins/phx folder. (You can also use the Manage Files from the Elements menu, if you ind it easier). 5. Create a new plugin using the MODx Manager interface: a. Click on the Manage Elements menu item in the Elements menu b. Click on the Plugins tab c.

      Click on the New Plugin link

      d. Fill it with the following details: Field Name

      Field Value

      Plugin Name


      Plugin Code

      Contents of the ile phx.plugin.txt in the extracted folder

      In System Events | OnParseDocument


      6. Click on the Save button

      Adding Family and Friends resources Let us create a page that lists all of the members from the Family or Friends group. This resource will be a container that will have a resource for each member that you would like to add. Hence, just as you have learned earlier, a call to the Ditto snippet can get you all of the resources that a container holds.

      [ 160 ]

      Chapter 9

      1. Create a resource with the following details: Field Name

      Field Value


      Family and Friends

      Uses template

      Learning MODx default template


        [!Ditto? &parents=`[*id]` &tpl=`familyandfriendslist`!]
      [*id*] will be the ID of the created resource. We give the ID of this resource here as we will be adding the other resources as child resources of this resource.

      2. In the above Ditto call, we have indicated that we are using a custom chunk to control the appearance of the listing. Create a chunk with the following details. This chunk will show a neat list of the resources that represent a member with the title and a link to the resource. Field Name

      Field Value

      Chunk name


      Existing Category

      Learning MODx

      Chunk Code

    • [+title+]

    • 3. We will have to create a new template for the resources that represent the members that you add as family or friends. The template will show the various details of the member. To hold the various details of the members, we will need to create the appropriate template variables that the template can use. Create the following template variables with the given attributes, after inishing step 5: Field Name

      Field Value

      Variable Name


      Input Type


      Template Access

      Family and Friends

      Existing Category

      Learning MODx

      [ 161 ]


      Field Name

      Field Value

      Variable Name


      Input Type


      Template Access

      Family and Friends

      Existing Category

      Learning MODx

      Field Name

      Field Value

      Variable Name


      Input Type


      Template Access

      Family and Friends

      Existing Category

      Learning MODx

      4. Let us create the template that the resources representing members will use. Create a template with the following details. The highlighted section of the code represents the portion that introduces the situation discussed at the beginning of this chapter. Even if the template variable has no value, there is a corresponding label shown, because we have it so in the template. Field Name

      Field Value

      Template name

      Family and Friends

      Existing Category

      Learning MODx

      Template Code

      The following code

      Template Code

      Learning MODx

      Learning MODx

      [ 162 ]

      Chapter 9

      [!Wayfinder?startId=`0` &level=`2` &outerClass=`outer` &innerClass='inner' &lastClass=`last` &firstClass=`first` &hereClass=`active`!]

      Relationship: [*relationship*]
      Occupation: [*occupation*]
      Website: [*website*]



      [!Ditto? &parents=`47` &tpl=`dittofrontpage`!]

      It is fun and exciting to build websites with MODx

      Now preview the second test document again:

      [ 167 ]


      Notice that the label Occupation has disappeared. We still have to make sure that it is appearing in the other test resource, as Richard Stallman does have a value in the occupation ield. The preview of the irst test document is as follows:

      Now that we have learned how to hide the labels when the corresponding template variables are empty, we can continue to do the same for the rest of the template variables. Modify the template code to look like the following:

      Learning MODx

      Learning MODx

      [ 168 ]

      Chapter 9

      [!Wayfinder?startId=`0` &level=`2` &outerClass=`outer` &innerClass='inner' &lastClass=`last` &firstClass=`first` &hereClass=`active`!]

      [+phx:if=`[*relationship*]`:is=``:then=``:else=``+] [+phx:if=`[*occupation*]`:is=``:then=``:else=``+] [+phx:if=`[*website*]`:is=``:then=``:else=``+]
      Relationship: [*relationship*]
      Occupation: [*occupation*]
      Website: [*website*]



      [!Ditto? &parents=`47` &tpl=`dittofrontpage`!]

      It is fun and exciting to build websites with MODx

      What we are doing here is telling the Personalize snippet to render a chunk call to the profilelink, if the user is logged in. Now, let us create the chunk profilelink, to display the link. Place the following code in the new chunk: My Profile

      Replace 65 with the document ID of your My Profile document.

      [ 195 ]

      Simple Recipes

      Now the Front Page, if you are logged in, looks like the example shown in the following screenshot:

      Notice that the link does not appear when you are logged out. There are many ways to have user proiles in MODx; what we have shown here, using WebLoginPE, is just one of the ways. The other possibilities include associating every new user with a resource, and assigning those resources with a template that has the template variables necessary to store the user's data.

      Similar posts It would be nice to show the similar posts from a category when displaying blog entries. At irst thought, it may be tempting to think that we will need to look for a snippet that does this. This example will demonstrate that many functionalities can be implemented by the proper usage of the snippets that you already know. In this case, we will be using the Ditto snippet. The Ditto call that has to be included in the Learning MODx blog template is: [!Ditto? &parents=`47` &filter=`tvBlogcategories,[*Blogcategories*],7 |id,[*id*],2`!]

      [ 196 ]

      Chapter 10

      This section will teach you, step by step, how we came to get this snippet call. It is important that you learn the process of building a complex snippet call. When the solution for the requirement is approached logically, solving one hurdle at a time, the whole procedure becomes very simple. We already know that Ditto can be used to show all of the MODx resources from a particular container. Because all of our blogs are in a container with an ID of 47 (in an earlier chapter, we explained that this ID can be different for you), in order to display all the blogs we will call Ditto as follows: [!Ditto? &parents=`47`!]

      We have also learned that we can use ilters to display resources with a speciic template variable value. This has already been demonstrated when we created RSS feeds for a different categories of blogs. So a call of: [!Ditto? &parents=`47` &filter=`tvBlogcategories, IT, 7`!]

      will display all of the blogs from the IT category. Now, this is ine when we are in a blog page that is also of the IT category. However, when we are visiting a blog that is of the Sports category, we will want to display blogs from the Sports category. So in the ilter, instead of IT or Sports, we will have to have a variable that changes its value depending on which resource is being viewed. Here, we can use the template variable of the resource itself to achieve this. Hence, [!Ditto? &parents=`47` &filter=`tvBlogcategories,[*Blogcategories*],7

      will translate to [!Ditto? &parents=`47` &filter=`tvBlogcategories,IT,7

      in a blog with the category as IT, and to [!Ditto? &parents=`47` &filter=`tvBlogcategories,Sports,7

      in a blog with the category as Sports. The snippet call to show the similar posts is almost complete, as we show blogs from the same category. But there is one more enhancement that needs to be done. We don't want the blog page that we are currently displaying to be listed in the list of similar posts as well. Therefore, we need to ilter out the current resource. We already know that we can club ilters together by using the | operator, and also that we can ilter resources based on the ID. A iltering expression like: id,1,2

      will ilter out resource 1. What we need is to replace 1 with the current resource's ID. So the ilter expression will be: id,[*id*],2 [ 197 ]

      Simple Recipes

      By clubbing all of this together, we get: [!Ditto? &parents=`47` &filter=`tvBlogcategories,[*Blogcategories*],7 |id,[*id*],2`!]

      We can implement this by modifying the Learning MODx blog template to the contain following addition:

      Learning Modx

      Learning MODx

      [!Jot? &placeholders=`1` & output=`0` &tplForm=`commentscustom` &canpost=`Registered Users`!]

      [+jot.html.comments+] [+jot.html.form+]



      Similar Posts in [*blogCategories*] [!Ditto? &parents=`47` &filter=`tvblogCategories,[*blogCategories*],7| id,[*id*],2`!]

      [ 198 ]

      Chapter 10

      It is fun and exciting to build websites with MODx

      Now you can preview the front page and it will look similar to the following screenshot:

      Refresh the page to see if you get another fortune.

      Chunks, placeholders, and parameters We have now got the fortune snippet working, so let us enhance it. We can perform the following improvements on it: • • •

      Create placeholders for the fortune text and the author Deine a parameter to specify a chunk name Process the output using the given chunk

      We have already seen how to do all of these things in the Hello World! example.

      [ 212 ]

      Chapter 11

      To create placeholders: $modx->setPlaceholder('fortunetext',$fortune["text"]); $modx->setPlaceholder('fortuneauthor',$fortune["author"]);

      To accept parameters for the output template: $tpl = (isset($tpl))? $tpl : 'fortune';

      To process the output using the given chunk: $o = $modx->getChunk($tpl);

      Hence, the inal snippet of code will be:

      Modify the Fortune snippet to contain the preceding code. Next, you will have to create a chunk for the snippet to use. As we are not passing any parameter in the snippet call, it will use the chunk named fortunes. So let us create a chunk with the following details: Field Name

      Field Value

      Chunk name


      Existing Category

      Learning MODx

      Chunk code

      Fortune [+fortunetext+]

      Now, preview the front page again. You should be able to see the fortune, just as before. [ 213 ]

      Creating Snippets

      Using iles It is also possible that you have a large snippet that you want to split into multiple iles. In such a case, other iles can be included from within the snippet. For example, to include a ile for the fortune snippet, the line of code could be: include MODX_BASE_PATH.'assets/snippets/fortunes/filename.php';

      MODX_BASE_PATH stores the root directory of the installation.

      The convention followed when using external iles is to place them in a folder that has the same name as the snippet and that is inside the assets/snippets folder.

      Summary In this chapter, you have learned how to create snippets and the different ways of rendering output. You have also learned how to use the available MODx APIs as well as why you should use them. You have created a new snippet for the site to display a random fortune. The snippet accepts a parameter for a chunk and renders the output by using chunks and placeholders. You also learned how snippets can make use of external iles.

      [ 214 ]

      SEO, Deployment, and Security In this chapter, we will discuss all that you need to take care of once you have developed your site. We will discuss how MODx helps you to take your site to the top of the search ladder. After that, we will deal with deployment and keeping your site secured.

      SEO We all know that Search Engine Optimization (SEO) is about getting a better rank in the search engines like Google, so that your site appears towards the top of the results list when someone searches for the content that is available on your site. In this section, we will discuss the various factors that contribute to getting a site optimized for a search engine, and also discuss what MODx provides to make this possible. Please note that like the CTO of Google says—" ", it all comes down to what you really have. However, there are certain fundamentals that you can take care of so that you can optimize the results that you already get.

      SEO, Deployment, and Security

      Search engine-friendly URLs Clean URLs are URLs without the ugly ?=xxxxxxxxxx at the end. This format is used to pass parameters to a page by appending a ? and a key (=) value pair to the URL. For example, to pass id = 7 to the index.php page, the URL might look like http:// localhost/learningMODx/index.php?id=7. If you observe closely, you will notice that whatever resource you want to visit, MODx is actually calling the index.php page with the ID of the respective resource ID as a parameter. Almost all CMSs behave in the same way. All CMSs execute only one PHP page, which in turn parses the required resource. Friendlier URLs mean that instead of using the following URL http://localhost/learningMODx/index.php?id=7, we would want the URL to look like http://localhost/learningMODx/7. This URL appears friendlier, not just to the end users, but also to machines. If you would like to ind out more about how this appears friendly to machines, you might want to Google for 'REST' and read about it. Now that this URL appears friendlier to machines, there are greater chances that it will be ranked higher. MODx supports clean URLs. To turn on clean URLs, you must irst have mod_rewrite loaded to Apache. If you are using Apache with XAMPP, as explained in Chapter 2, Getting Started, then this feature is activated by default. Alternatively, if you are using Apache from any Debian-based distribution, you can load the module by issuing the following commands: a2enmod rewrite apache2ctl restart

      What essentially happens, when using the rewrite module, is that there is a ile in the MODx directory called .htaccess that contains rules on how to translate the URL. So although the requested URL is http://localhost/learningMODx/7, the rewrite module of Apache after reading the coniguration ile will translate this to http://localhost/learningMODx/index.php?id=7. You can also manually edit the ht.access ile to specify new mapping rules if you like. You will ind a ile with the name ht.access in the MODx root directory. Rename this ile to .htaccess. Do the same thing with the ht.access ile in the manager directory. Now, open the .htaccess ile in the MODx root directory and edit the line RewriteBase / to contain the MODxfolderpath, which, in our case, is learningMODx. Hence you will have to change the above line to RewriteBase /learningMODx. So .htaccess should now look like the following:

      [ 216 ]

      Chapter 12 # # # #

      For full documentation and other suggested options, please see including for unexpected logouts in multi-server/cloud environments and especially for the first three commented out rules

      #php_flag register_globals Off #AddDefaultCharset utf-8 #php_value date.timezone Europe/Moscow Options +FollowSymlinks RewriteEngine On RewriteBase /learningMODx # Fix Apache internal dummy connections from breaking [(site_url)] cache RewriteCond %{HTTP_USER_AGENT} ^.*internal\ dummy\ connection.*$ [NC] RewriteRule .* - [F,L] # Rewrite -> -- used with SEO Strict URLs plugin #RewriteCond %{HTTP_HOST} . #RewriteCond %{HTTP_HOST} !^www\.example\.com [NC] #RewriteRule (.*)$1 [R=301,L] # Exclude /assets and /manager directories and images from rewrite rules RewriteRule ^(manager|assets)/*$ - [L] RewriteRule \.(jpg|jpeg|png|gif|ico)$ - [L] # For Friendly URLs RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] # Reduce server overhead by enabling output compression if supported. #php_flag zlib.output_compression On #php_value zlib.output_compression_level 5

      If you are editing this ile in Windows, make sure that the editor does not save any alien characters like ^M. It is preferable not to use WordPad, Word, Dreamweaver, or anything of that sort to edit the coniguration iles to avoid this happening. Conigure the Friendly URLs page in the Manager interface to meet your requirements. MODx makes it easier for you to conigure the mapping of a URL to a friendly name pattern that you prefer.

      [ 217 ]

      SEO, Deployment, and Security

      The following is a screenshot of the coniguration page for Friendly URLs. You can get to this page by clicking on Coniguration on the Tools menu and then selecting the Friendly URLs tab.

      Change the Use friendly URLs option to Yes, and then click on Save. Now you can go to the main page, http://localhost/learningMODx, and open any page using the menu. You will notice that the links have changed and are friendlier, now being in the form http://localhost/learningMODx/pageid.html.

      [ 218 ]

      Chapter 12

      You can go ahead and change the preix and sufix. By default, the preix is blank and the sufix is .html, and that is the reason why you get pageid.html. I like to leave the .html preix blank. This means you will have http://localhost/ learningMODx/pageid. The next option on the page is the Use friendly aliases option. When this option is turned on, the page can be accessed using the alias name instead of the ID. Our Home Page has the ID 1. Let us give it an alias. In the Friendly URLs coniguration page, turn Alias to On and remove the .html sufix. Now try opening the URL http:/localhost/learningMODx/home. You will see the Home Page. With the Use alias option, it is possible to access the resources by a name instead of a number. The next option is the Use friendly alias path. This will make a resource accessible by its full path in the resource tree. Supposing the resource is a child of a container resource and both of these documents have aliases, then the document can be accessed by http://localhost/learningMODx/parentalias/childalias. Note that turning this option on would require you to turn the next option—Allow duplicate aliases—on, which is not recommended. Duplicate aliases mean that a resource can be accessed by more than one alias. This introduces an SEO problem. A site is more optimized for searching if every page has only one corresponding URL. That is, to access a particular page, there must be only one URL. This is known as Canonicalization. To make this happen, you can use the SEO Strict plugin, which will only allow the resource to be accessed by the exact alias. The next option is Automatically generate alias; turning this option on will automatically generate page aliases from the title of the page. Of course, you can still edit the generated aliases in case you want a different alias for a particular page. [ 219 ]

      SEO, Deployment, and Security

      Meta tags and keywords Meta tags are a way for you to deine what your website is about, to the outside world. These tags are generally placed within the tag. Meta tags are speciied by using the tags. These tags have two attributes—name and content. The name attribute is used to specify the name of the element, and the content attribute speciies the value for that element. For example:

      There are a set of deined elements such as author and description. Setting these elements makes your site description clearer, and hence it will have a higher chance of getting a better rating. There is also an element called keyword, which can contain a list of space-separated words. The keyword element is used to inform the search engine about what content to expect on the site. Hence, setting the meta tags and keywords should make the site more search-engine optimized. With modern search engines however the meta tags and keywords really don't matter. MODx used to come with a Manager interface that was used to add meta tags and keywords to the entire site. However, because it is easier to just add the meta tags and keyword in the templates or resources, this feature has been disabled in newer versions of MODx. However, if you want to enable this feature (which we don't recommended), you can do so from the Coniguration menu item on the Tools menu (Coniguration | Tools | Show META Keywords tab) in MODx. To access this page once enabled, carry out the following steps: 1. Click on the Elements menu. 2. Click on the Manage META tags and Keywords. You will see a screenshot like the example shown in the following screenshot:

      [ 220 ]

      Chapter 12

      Here you can add, edit, and delete tags and keywords. This is rarely used, because the process for specifying keywords for an individual resource is rather cumbersome. Most people use a Template Variable (TV) to assign the keywords, and then, in their template, have the meta tag with the TV tag in place of a list of keywords. This way, you can easily edit the TV ield for each resource.

      Site map A site map is an XML page that lets search engines know the layout of the site. Generally, you will have to create it yourself, but MODx has a snippet that does it for you automatically. To use the snippet, perform the following steps: 1. Download the snippet from package/?package=410. 2. To install the snippet, click on Create new snippet in the Elements Manager and paste the code from the downloaded ile. 3. Give the snippet the name SiteMap. More instructions on installing snippets can be found in Chapter 8, Snippets.

      [ 221 ]

      SEO, Deployment, and Security

      4. Create a resource with the following details: Field Name

      Field Value



      Uses template


      Content Type


      Resource content

      [!SiteMap? &format=`sp`!]

      Make sure that when you paste the preceding content, you are not using the rich text editor. This is a better practice when pasting code throughout the book. However, in this case, the code just won't work if you use a rich text editor. 5

      Preview the SiteLayout page and you will see something like the following example in the source code, which contains a description of the entire site.

      SiteMap Parameters Google has a feature where you can check individual pages by using the site layout. You can do this by using the service provided by Google at

      [ 222 ]

      Chapter 12

      XHTML Strict It is good practice to use XHTML Strict conventions. This does make a difference in SEO. Unlike HTML, all XHTML tags have to be closed, and it is sometimes dificult to make a page XHTML-compliant when there is a lot of code mixed with it. Since MODx allows you to keep templates as plain XHTML with only variable replacements and snippet calls, it is easier in MODx to maintain XHTML strict compliance. You can always validate any page for complete compliance at

      Other SEO tweaks In this section, we will quickly list a few other SEO tricks that aren't speciic to MODx.

      Using CSS to control the layout Always use CSS to control the layout and don't mix it with the content. This also means that you should not use inline properties in HTML.

      Content irst Always have the content as close to the tag as possible. In the case of a site with large drop-down menus, have them placed in the bottom and use CSS to move them up.

      Hidden text Search engines, such as Google, consider hidden text to be misleading and remove such pages from indexing. Always make sure that you don't have text that machines can read but humans can't. An example would be a text box with size set to 1 pixel. When search engines encounter such pages, they tend to believe that you are trying to mislead the search.

      Descriptive text Always have descriptive texts for images, lash scripts, and any other objects that you embed. This not only helps people who use a screen reader to understand the contents of the site, but also helps the search engines.

      Alternative text It is a good practice to have alternate texts for all images used. What this means is that if the user for some reason can't see the image, the user at least gets to know what the image was for. Now search engines deinitely can't see images! [ 223 ]

      SEO, Deployment, and Security

      Cross links HTML and the web evolved because of cross-linking. Make sure that you link all pages in your site in as many relevant ways as possible. Search engines like a well-connected site.

      Tracking Use a tracking mechanism to monitor the changes in your site's hit ratio. Once you are aware of what works and what doesn't for your site, you will be able to tune it better. An example of such a tracking service is Google Analytics.

      Inbound links The more people that link to your site, the more likely it is that your site will appear at the top of the search results. Get more people to refer to your site. Somehow, this trend is picking up with the blogging community so rapidly that we are left with learning from them! Tools like Feedburner can help you track such stats for feeds. See for more information on Feedburner.

      Quality content Have quality content on your site. Quality content is not just what you have, it is also how you have structured it and placed it. With appropriate headings and relevant references, you are more likely to get a higher number of hits. To know more, you may want to visit webmasters/?hl=en.

      Deployment Once you have completed the development of your website, you will want to make it available to the whole world. For this, you will have to deploy the website to a web server connected to the Internet. Any server that can run PHP and MySQL is suitable for MODx, and you can (at the time of writing) get an account starting from $3 a month. In this section, we will discuss what you need to move the website from one computer to another.

      Filesystem When migrating the website, you will have to copy the MODx installation root directory to the appropriate directory on your web server. There is not much that can go wrong in this process. Just make sure that all of the iles are copied. Also, the transferred iles may have different permissions on the new server. In such a case, the site will throw an error indicating the ile permissions. If that happens, change the permissions accordingly, as described in Chapter 2, Getting Started. [ 224 ]

      Chapter 12

      Depending on your hosting provider, you will be given one of the ways described below of transferring iles. There is an excellent full backup module that will zip up the whole ilesystem and the database into a single ZIP ile. You can then simply upload the ZIP ile and unzip it by using the site control panel's File Management feature. The extracted folder will contain a ile with the .sql extension. You can use this ile to import the database by using phpMyAdmin, or any other database management interface that the hosting service provides.

      FTP FTP is one of the most commonly-used protocols for transferring iles. To get FTP on Windows, download the program called winscp from Start the program, and specify the User name and Password that you have been given by your hosting provider. Enter the domain name and choose the Protocol as FTP.

      [ 225 ]

      SEO, Deployment, and Security

      Click on Connect. You will see two panes—the left pane shows the iles on your local machine, and the right side shows the iles on the remote machine:

      In Linux, you can use the ftp command to connect to the FTP server. Enter your username and password when prompted. (For example, ftp The put command helps you to transfer iles from the local machine to the remote machine. To transfer all of the iles and folders within a folder, you can use the -r parameter. Just like regular ilesystems, wild cards are accepted. * means all iles, and xyz* means all iles whose names start with xyz. For example, put * -r will transfer all the iles and folders, recursively. The get command is used to transfer the iles from the remote server to the local machine. It behaves in a similar way to put. Alternatively, you can use a GUI-based client such as kasablanca or kftpgrabber. There is also another program called curl, which is worth trying. Curl can work over multiple protocols and is the preferred way by those who use Linux for their day-to-day activities. [ 226 ]

      Chapter 12

      SFTP To install on Windows, follow the same steps as for FTP, but choose SFTP as the protocol, instead of FTP. In Linux, there are two easy ways to transfer the iles between the remote machine and the local machine using SFTP. You can either familiarize yourself with the scp functionality—which is very similar to cp, which is used for copying iles locally, or you can mount the remote ilesystem locally and transfer iles to and fro as you would do from a regular ilesystem by using sshfs. It would be diverging from the topic to explain both scp and sshfs, but we will give you a few pointers here that can help you learn more. scp is similar to cp. You have to specify two arguments—source and destination. If you want to copy a ile named index.php from the current directory on the local

      machine to the remote machine, you would use the following command: scp index.php [email protected]:/foldername

      Similarly, to transfer iles from a remote machine to the local machine, you would use: scp [email protected]:/foldername localpath

      sshfs is similar to mount. The only difference is that instead of mounting a local

      ilesystem, you are mounting a remote ilesystem. For this, you will need to irst install sshfs. The general syntax is:

      sshfs [email protected]:/foldername /mountfoldername

      You can alternatively use the application SecPanel, which has a GUI for scp.

      WebDAV WebDAV was originally meant for collaborative authoring, although these days it is also used for sharing iles. WebDAV operates over the HTTP protocol. It is sometimes referred to as DAV, for short. To use a DAV resource, follow these steps: In Windows: 1. Open My Network Places. 2. Click on Add Network Place. 3. Click on Choose another network location. 4. Enter the given URL from the service provider, followed by the username and password, in the Internet or network address box. 5. Now you will be able to access your iles from My Network Places. [ 227 ]

      SEO, Deployment, and Security

      In Linux, the procedure to use a DAV resource is similar to mounting a ilesystem over SFTP. You need to install an application called fusedav and then you can mount the ilesystem locally. fusedav has the following syntax: fusedav remoteurl /mountfoldername

      Database MODx stores all of the resources and templates that you create in the database. So you will have to transfer the database as well, in order for your site to be deployed. Almost all hosting providers provide phpMyAdmin for managing databases. There are two steps to migrating a database: 1. Export the database from the local machine. 2. Import the database to the remote machine.

      Exporting To export the database, you can use phpMyAdmin. We have already discussed the installation of phpMyAdmin in Chapter 2, Getting Started. 1. Log in to phpMyAdmin, using the MySQL username and password that you created for the database earlier, by opening the URL http://localhost/ phpmyadmin in a browser. 2. You will see a list of the databases available on the server. Click on the database that you want to export. 3. Click on Export. 4. Select the Save to ile checkbox, and click Go.

      [ 228 ]

      Chapter 12

      Importing When you export a database, the default option is to save it as SQL, which means that the exported ile contains the SQL instructions to reconstruct all of the tables and records in the database. Of course, you can choose a different formats and can even have them compressed before exporting. Once you have exported the database, you will want to import it to the remote server provided by your service provider. 1. Log in to phpMyAdmin by using the username mySQL and the password that was given to you by your service provider. 2. Create a new database, or select a database if you have already created one. 3. Click on Import. 4. Click Browse and select the ile that was exported before. 5.

      Click on Go to import the database.

      [ 229 ]

      SEO, Deployment, and Security

      There is typically a server limitation on the size of the ile that can be uploaded. The import screen shows the maximum size that can be uploaded. If the export ile is larger than what your service provider allows you to import, try choosing a compression format to reduce the size. The compression works really well, and reduces the size of the exported ile by a good ratio. Make sure that the compression format that you choose when exporting is also supported by the server onto which you are importing. When you click on Import, the screen shows the various compression formats that the server supports. Bzip2 is known to offer the highest compression among the various compression formats that are supported.

      Coniguration ile Sometimes you may not be able to use the same name for the database on the new server. Maybe the name is already taken. In such a case, it is alright to give a new database name, username, and password. You will have to make sure that you make the appropriate changes in the manager/includes/ ile and upload it back to the server.

      [ 230 ]

      Chapter 12


      Depending on the path of the new location, you might also want to change the following settings in the Manager, by clicking on the Tools menu and selecting Coniguration. • •

      File base path in Interface & Features File Manager path in File Manager If you had created other Managers' accounts, it may also be necessary to edit these ields for them, individually.

      Security In this section, we will discuss the permissions on ilesystems that have to be set in order to make sure that your site is safe. Also, we will discuss captcha and the mod_security module for Apache, which can cause certain issues arising from security concerns and how to solve them. When using a content management server, unless you are writing snippets yourself, there is not much to worry about. There are a few things to keep in mind though, for MODx, and they are mentioned next. [ 231 ]

      SEO, Deployment, and Security

      File permissions It is a good practice to set read-only permissions on all iles except folders that will be updated by MODx. In Linux, you can do this through chmod 0644 * -R within the MODx directory. Some folders must be made writable by using chmod 0755 folder. The following is a list of such folders: •

      • •

      assets/cache assets/files assets/media

      When you are using an external snippet that requires you to store iles in a separate folder, make sure that you make those iles writable too. For example, the gallery snippet we saw earlier requires that the folder assets/galleries be writable. For more details on what chmod does, please refer to Chapter 2, Getting Started.

      Installer The MODx installer iles are stored in the install directory. Make sure that you delete this folder after installation. Leaving it on the system poses a security risk, and someone may try to install MODx on your system again.

      Writable coniguration ile

      MODx stores the coniguration of the site in manager/includes/ php. This ile contains the database connection details and other settings. However, during installation, this ile has to be made writable, as MODx will have to store the settings that you enter in the web page. After the installation is complete, you must make it read-only, in order to have a secured site.

      Captcha Captcha is a technology to prevent spam bots. There are malicious machines on the Internet that have programs that can automatically register and post to blogs, and so on. Such programs are called bots. Captcha shows an image containing embedded text and asks the user to enter the same in a textbox. This makes sure that the person illing the form, or registering, is a human and not an automated machine. Most MODx snippets that accept input from the user have captcha ability. Make sure that you use captcha wherever necessary, in order to make your site spam free.

      [ 232 ]

      Chapter 12

      mod_security Apache has a security module that checks for code in POST requests and blocks it, which means, that if you are adding a snippet using the Manager and submit the form, then there are chances that the code may be considered unsafe. In such a case, the snippet will not get saved. In such situations, you can disable the security module for the duration of the post. On a hosted server, this may not be possible. Instead, what you can do on hosted servers is to write a few additions to the .htaccess ile that will permit the data transfer. You can try one of the following two lines in the .htaccess ile: •

      To turn off post data iltering: SecFilterScanPOST Off

      To turn off the security ilter engine: SecFilterEngine Off For any changes in .htaccess to take effect, the Apache server has to be restarted.

      Unused iles

      A recent security exploit demonstrated that unused .php iles should never be left in the ilesystem. They should either be deleted or renamed (such as the .php iles that are included with snippets, plugins, and so on that contain the code to be copied into the Manager). This experience will also most likely teach the snippet authors to name their Manager code iles with a different sufix as well, even if this does prevent an editor's syntax coloring (by default) from working properly on the ile.

      Manager conigurations In addition to the previously-mentioned security issues, there are simple conigurations in the Manager that can help you to make your site even more secure. These options can be found when clicking on Conigurations on the Tools menu.

      [ 233 ]

      SEO, Deployment, and Security

      User tab The following are the options that the User tab supports: •

      Failed Login Attempts: This option speciies how many times to allow a user to enter a wrong username or password consecutively, before the user is blocked. This can be useful to prevent a brute force attack, where a program, or even a person, is trying to guess the password of another user. Blocked Minutes: This option speciies how many minutes to block the user for before allowing them to attempt to log in again.

      File Manager tab New File Permissions: Here you can set the default permissions for the iles that are being uploaded. 0644 is safe, and it is the default permission. This makes sure that the iles are not writable, but are executable by everyone. New Folder Permissions: Here you can set the default permissions for the new folders that you create by using the File Manager. The default permission—0755— again, is a very safe option. Uploadable File Types: In this textbox, you can specify a list of comma-separated ile extensions that can be uploaded to the site. It is important that you specify non-executable extensions. It is a good idea to only allow extensions that you are anticipating; for example, if you want to allow the uploading of images, only then you can give the list of .gif, .jpeg , and .tif.

      Summary In this chapter, we discussed how to make the site optimized for search engines. We discussed clean URLs, meta tags, site maps, and other tweaks. Having developed the site on a local machine, we learned in this chapter how to deploy it to a remote server. Finally, we looked into what has to be done in order to make your MODx site secure.

      [ 234 ]

      Plugins and Modules This chapter explains plugins and modules, including those that we have used in our application. This chapter also covers events and plugin coniguration.

      Plugins and events Plugins are PHP code blocks in MODx that, unlike snippets, are not called for execution from a resource or a template. Rather, plugins are executed on the triggering of certain events, when a resource is parsed, or during other internal processing. Every action in MODx, such as rendering a resource, or deleting a user from the system, will trigger a series of lags. Each lag is viewed as an event. For example, you have events such as: •

      OnDocFormPrerender—triggered just before the resource is going to be

      rendered OnUserFormSave—triggered just before the user's details are saved

      There are many such events, and we will not describe each one of them in this chapter. Rather, we will discuss how to write plugins that are executed in response to speciic events. We will also describe how to generate events—even custom ones—when you are writing snippets. We will start by irst examining some plugins that should have been installed during the setup, and gradually move into creating a very basic plugin.

      Plugins and Modules

      Using an existing plugin You can view the entire available plugins list by clicking on Elements | Manage Elements | Plugins. An example of such a plugin list is shown below:

      You will notice that PHx—which we used earlier—is also a plugin. Click on the PHx plugin to explore it further.

      [ 236 ]

      Chapter 13

      As you can see from the next screenshot, a plugin is similar to a snippet, in that it has a plugin name and some PHP code.

      You will also see two other tabs, namely Coniguration and System Events. Let us look into each of these tabs.

      [ 237 ]

      Plugins and Modules


      The coniguration screen (as shown in the next screenshot) has category selection boxes for the plugin just like any other element in MODx. There is also an option called Import module shared properties, which we will discuss in the next section, on modules.

      Using the Plugin Coniguration text area, you can pass parameters to the plugin. There is a speciic syntax to do so. All values have to be passed as a key : value pair, with pairs separated by commas. There are ive parts to a coniguration parameter—the parameter name, its label, the data type, optional values, and a default value. Each parameter must begin with &. The parameter values are separated by a semicolon. The following example is taken from the TinyMCE plugin: &entity_encoding=Entity Encoding;list;named,numeric,raw;raw

      This deines a coniguration variable named entity_encoding. The label used when displaying the parameter editing form will be Entity Encoding. Its type is a list, with three options—named, numeric, and raw. The default value is raw.

      [ 238 ]

      Chapter 13

      System events In this screen, you will see a list of events.

      When the checkbox next to any event is selected, the plugin will be executed when that event happens. For example, we are viewing the PHx plugin and, as we can see, the checkbox next to onParseDocument is selected. This will make MODx execute the PHP code for the PHx snippet just before parsing the document. If you take a moment now to think about how PHx works, you will understand the whole concept better. MODx fetches a resource and, just before parsing, executes the PHx plugin. The code in the PHx plugin is written to search and replace the PHx notations with their corresponding result. In the subsection on creating plugins, we will discuss how to take a resource, process it, and send it back to MODx as output. All Events still refer to Resources as Documents, as in the earlier versions of MODx.

      [ 239 ]

      Plugins and Modules

      Exploring other plugins Now is a good time to go through the other plugins and notice their triggering events. It will help your understanding to think about why the Quick Manager+ plugin is triggered by the OnWebPagePrerender event, and so on with other plugins.

      Using custom plugins In this section, we will download a plugin called Codeprettify and learn how to use it. The following steps describe how to do this: 1. Download the plugin from package/?package=75, and then extract it. 2. Click on New plugin from Elements | Manage Elements | Plugins. 3. Fill in the following details: Field Name

      Field Value

      Plugin name

      Code Prettify

      Plugin code

      Copy and paste the code from plugin.codeprettify.tpl

      Coniguration ->Existing Category

      Learning Modx

      System Events

      OnLoadWebDocument: Checked

      4. Click on Save. 5. Copy the codeprettify directory that you have extracted, to the assets/plugins directory. Note that it doesn't matter what name you give the plugin, as you will not be invoking it by any call; rather it gets invoked on execution of the selected events automatically.

      As stated, for all elements, a category is just used to allow the developer to visually group the elements, and doesn't affect the functionality. If you notice the selected System Events, the trigger is OnLoadWebDocument. You may wonder why it is not OnWebPagePrerender. This is because this plugin inserts JavaScript, and it is better to do so before the resource is even generated. Now let's go ahead and test the plugin.

      [ 240 ]

      Chapter 13

      Create a resource with the following details: Field Name

      Field Value


      Testing Plugin

      Uses Template

      Learning Modx default template

      Document content

      echo "This code is pretty printed by the new plugin";

      Now, a preview of the resource will look like the example shown in the following screenshot:

      As you can see, there is no visible difference; this is because this plugin requires all of the code that has to be prettiied to be inserted within:

      So, to test pretty printing, change the contents of the resource to the following:

      echo "This code is pretty printed by the new plugin";

      [ 241 ]

      Plugins and Modules

      Now the preview will look like the example shown in the following screenshot:

      Learning about the plugin When using the previous plugin, there were a few details that we couldn't have intuitively known. For instance, we couldn't have known which tags are to be used in the resource and which events have to be enabled. Therefore, it is important that for every plugin that you want to use you read the associated document. Many plugins come with a separate document; some have the details on the download page. However, some plugins have usage details commented in the ile that contains the plugin code. In our previous example, we got the details from the plugin code. As you can see if you open the plugin.codeprettify.tpl ile, the top section contains the following code: /* * * * * * * * *

      CodePrettify * DESCRIPTION: Allows syntax highlighting of code blocks, using the google-code-prettify javascript HISTORY: version 0.5 (2007-09-08): by Daniele "MadMage" Calisi

      [ 242 ]

      Chapter 13 * NOTES: google-code-prettify can be downloaded from Google Code website ( * and is under the Apache 2.0 license ( * * INSTRUCTIONS: * - extract the content of the zip archive in assets/plugins/codeprettify * - create a new MODx plugin using the code of this file * - select "OnLoadWebDocument" as the System Event that will trigger this plugin * - all source code in the webpage enclosed in ... * or in ... will be automatically prettified. * - you can optionally put some css in assets/plugins/codeprettify/ prettify-custom.css file */

      One key skill that is very important in leveraging a community-driven platform like MODx is to be able to search and read through documentation. This may, in many cases, help you to avoid having to reinvent the wheel, and help you to ind quicker solution for something that is challenging your mental abilities. As an old friend once said—"IT Consultants get paid for reading documents".

      Creating plugins To create a plugin, you just have to remember this one concept: the plugin code requires a wrapper to determine what to execute in which event. MODx passes the event details to the plugin along with the MODx elements, which we examined in Chapter 12, PHx. $MODx->Event holds the details of the event. $MODx->Event->name gives you the name of the event. So, the plugin code will have to check the name of the triggered event and execute the appropriate code. This can easily be done with a switch statement. Hence, the structure of code speciic to the events in a plugin would look like this: $e = & $MODx->Event; switch ($e->name) { case "eventname1" : Code for eventname1 break; case "eventname2" : Code for eventname2 break; [ 243 ]

      Plugins and Modules default

      : return; break;

      Now is a good time to look into the source code of the previous plugin. By doing so you will be able to understand exactly how the plugin works the way it does. If you want to use external iles in your plugin, then the convention is to place these iles in a separate folder within the assets/plugins directory. The following is the code from the plugin that we just used: switch ($MODx->Event->name) { case "OnLoadWebDocument": $MODx->regClientCSS('assets/plugins/ codeprettify/prettify.css'); $MODx->regClientCSS('assets/plugins/codeprettify/prettifycustom.css'); $MODx->regClientStartupScript('manager/media/script/mootools/ mootools.js'); $MODx->regClientStartupScript('assets/plugins/codeprettify/ prettify.js'); $jspp = ''; $MODx->regClientStartupScript($jspp); break; default: // stop here return; break; }

      Similar to what you have just learned, the plugin uses a switch case to check for the event, along with the $MODx->Event->name API. We can see that it executes a portion of the code for only the OnLoadWebDocument event, and for any other event, it just returns without changing anything. Let us now examine what the previous code does. The code uses an API that we haven't yet discussed. The following table explains the APIs.

      [ 244 ]

      Chapter 13

      Field Name

      Field Value


      This API can be used to load a CSS at the beginning of the page. The CSS loaded by using this function will be inserted within the tag. The function takes one argument, which is the name of the CSS ile, or the CSS content itself.


      This API is similar to the previous API, but in this case, it loads a JavaScript ile within the tag, instead of the CSS.

      As you can see, the discussed plugin does the following two things: 1. Inserts the tag for CSS 2. Inserts the tag for JavaScript This plugin, as described in the comments, is using a JavaScript function from Google Code that already does the pretty printing. The functionality of this plugin is to just ensure that the JavaScript code and the CSS are loaded for every resource, irrespective of the template used. As you may realize, plugins affect the system-wide behavior for the selected events.

      Event-triggering snippets It is possible to trigger events from your snippets, in order to get a plugin to do something. The API to do this is $MODx->invokeEvent. invokeEvent takes two parameters, namely the name of the event and the parameters to be passed. For example: $MODx->invokeEvent("OnBeforeWebLogin", $parameters);

      It is recommended that you do not use this API, as it is intended to be used by the core code. If you are curious anyway, and want to try it, going through the code of WebloginPE will help.

      Modules In this section, we will learn how to use modules, and see how a module works. Modules are code that can be executed only from the Manager interface. Modules are useful for the following two purposes: [ 245 ]

      Plugins and Modules

      1. Adding functionality to the Manager interface. An example of this kind of functionality is the DOC Manager module, which is an optional component that can be installed during the MODx installation. This module allows the Manager to perform bulk actions on resources. 2. Creating tables that snippets can use. Snippets and plugins may need to store data in the database. Modules can facilitate this by creating these tables for the snippets or plugins. Moreover, Modules can be used to create an interface for the Manager to add data. This data can be stored in the database for snippets or plugins to use. In this section, we will look into a module and plugin pair, in order to demonstrate this functionality.

      Using modules In this section, we will install a module called Autolink. This module provides the Manager with an interface that can be used to create the keywords that the accompanying snippet can use. The following are the steps to use the module:

      Creating a module 1. Download the module and the plugin package from extras/package/?package=30, and then extract it. 2. Click on New Module from Modules | Manage Modules. 3. Fill in the following details: Field Name

      Field Value

      Module name


      Module code

      Code from autolink_module.txt


      Learning MODx

      4. Click on Save.

      Executing a module Once you have created a module, you will have to manually execute it from the Manager interface. The following steps show you how to do this: 1. You will see the module listed along with the other modules. 2. Next to the module, there is a small icon. Clicking on this icon opens a context menu. [ 246 ]

      Chapter 13

      3. Click on Run Module in the Context menu.

      Module's Manager interface Running the Autolink module provides us with a page that allows us to deine the keywords that will be used by the plugin. The plugin replaces the keywords with a pre-deined link. Let us, for now, just add one keyword—MODx—with the value google. This should allow the plugin to create a link that searches for "MODx" in Google. 1. Click on Add Keywords in Modules | Manage Modules | Autolink. 2. Fill in the following details: Field Name

      Field Value






      Google MODx

      [ 247 ]

      Plugins and Modules

      3. Click on Add Keywords at the bottom of the form.

      Dependent plugins Now that we have installed the module that allows the creation of keywords from the Manager interface, let us create and install the accompanying plugin that will convert the keywords to links in a resource. 1. Click on New plugin from Elements | Manage Elements | Plugins. 2. Fill in the following data: Field Name

      Field Value

      Plugin name


      Plugin code

      Code from autolink_plugin_v2.txt

      Coniguration | Category

      Learning MODx

      System Events

      OnWebPagePrerender: checked

      3. Click on Save. Let us test the combined functionality of the module and its plugin by creating a resource with the following contents: [ 248 ]

      Chapter 13

      Field Name

      Field Value


      Testing Modules

      Uses template

      Learning MODx default template

      Resource content


      Now preview the preceding document, and it will look like the one shown in the following screenshot:

      You may notice that the keyword has been changed to a link that is a Google search for "MODx". This is shown in the status bar at the bottom of the browser window, and the title is used for the tooltip. The plugin retrieved these values from what we inserted into the Modules page. Remember that this section is teaching you how to use modules and not Autolink. You must also remember that there is no need to have a relationship between the module name and the plugin name. The plugin merely reads the values from the database by using the regular MODx db API that we discussed earlier. Ex: $rs = $MODx->db->select('*', $autolinkTable);

      [ 249 ]

      Plugins and Modules

      Unlike snippets and plugins, we will not learn how to create modules, as eficient use of modules may require our understanding of certain design patterns.

      Learning to use custom modules Because the installation of modules and plugins involves multiple steps, it can be a little confusing in the beginning. It will be very easy to understand if you keep in mind a few points. Modules are used for providing some functionality in the Manager interface, and for sharing the results of such interaction, such as data collected, with plugins and snippets.

      Summary In this chapter, we have learned about plugins and modules. •

      The differences between plugins and modules are: ° °


      • • •

      Snippets are executed when they are explicitly called either in a resource, a template, or from another snippet. Plugins are executed on the trigger of the events with which they are associated. This allows the plugin code to be executed just before resource rendering, user registration, and so on, as needed. Modules are executed only from within the Manager. They are used for creating the tables that dependent plugins or snippets may want to use. Modules can also provide an interface in order to give values to the plugin and snippet parameters.

      You have learned how to use plugins and how to customize plugins. You have also learned how to create new plugins, and we analyzed the code of the prettify code plugin that we used. Finally, you have learned how to use modules by using the Autolink module and plugin, and saw an example of this.

      [ 250 ]

      MODx Revolution Congratulations! You have done very well. You are now equipped with the tools and techniques that are required to rapidly build high-quality websites with MODx. In this chapter, we will catch up with some upcoming features that will make your development experience even better. This chapter introduces the MODx Revolution, so that when it is there, you are not left behind.

      Why Evolution, why Revolution…

      You may wonder why you want to stick with Evolution when Revolution is already available for download. Evolution has been around for many years now and is very stable, with lots of plugins and snippets that work out of the box. It has been well tested, and many professional websites are already using MODx Evolution. Revolution, on the other hand, has only a release candidate this year, and the snippets and plugins available in Evolution may not work. Also, the major reason for using Evolution is this: you can migrate from Evolution to Revolution at any time. So you can wait until a stable release is available and then make the migration. Nevertheless, it is good to be prepared, and armed with the knowledge of what is ahead. In this chapter, we will discover just that.

      What is similar? The methodology remains the same, be it Evolution or Revolution. The core of everything is a resource. A resource can use a template and make snippet calls. Plugins still get executed on speciic events. What really has changed is the very core on which MODx is built, which allows for quicker development of many features, and removes certain restrictions.

      MODx Revolution

      What to expect? As explained in the preceding section, what has really changed is the core, which allows for quicker and easier development of new features. The following is a list of the many features that are already available as an effect of the core changes. This information is edited from the oficial MODx roadmap, which can be found at: • • •

      New manager: The new manager has been redesigned to be more friendly and customizable. The manager is on its way to become fully-customizable through templates. Packages: Now elements can be installed, updated, and maintained from the MODx manager interface. In the future, Revolution will also allow installation from remote repositories. Contexts: Imagine being able to reuse and share your elements in different contexts. Also, think of the contexts having a hierarchy! MODx Revolution introduces contexts, which make it easier to manage subdomains, subsites, multisites, and so on. For more information on contexts, please read: http://rtfm.modx. com/display/revolution20/Contexts.

      • • •

      Improved security: With some of the core changes, like no eval, Revolution deinitely paves the way for some serious security improvements. Improved caching: Caching has been improved in the core, database, and partial pages. This will improve the performance of your site by a large degree and is a major development in the right direction. Improved content parser: Now content parsing is possible without using many regular expressions! And you can nest [[ tags]] to any level. As Jamie Zawinski quoted: "Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems."

      [ 252 ]

      Chapter 14

      Tags For those who are in a hurry to migrate, you may ind the following information useful. MODx Revolution now uses a uniied tag format. The following table shows an oficial listing of the changes in the tag format. In a nutshell, now every tag is in the [[ ]] format. This table is taken from the oficial documentation at . Element

      Old Format

      New Format

      Template Variables [*templatevar*]














      System Settings



      A peek into Revolution The preceding sections provided you with a peek into the screens of MODx Revolution. Feel free to install MODx Revolution and try it yourself. Revolution Login Screen

      [ 253 ]

      MODx Revolution

      Manager Home

      Installing Extras from within the Manager

      [ 254 ]

      Chapter 14

      Inline Help

      [ 255 ]

      MODx Revolution


      [ 256 ]

      Chapter 14

      MVC using actions from within Manager

      Lexicon Management

      [ 257 ]

      MODx Revolution

      Core technology changes Finally, a section for PHP developers and all of those who are curious to know more about the core technology changes in MODx Revolution:

      xPDO MODx has a completely new object-oriented core, rewritten using xPDO. xPDO is an Object Relational Bridge. This is a concept where SQL tables are mapped as objects in the system. This means that they can be manipulated as objects. This is very convenient in an object-oriented environment. Although MVC frameworks have popularized ORB concepts, you don't always need an MVC to make use of xPDO. This also means that, if you are a developer extending MODx at the core or by writing new snippets, you will also beneit from the ease and simplicity of this approach. The new object-oriented approach also provides you with an improved API. This in turn makes the core extendable with content parsing, session handling, and so on.

      Sencha and Smarty MODx Revolution makes use of the Smarty framework for delivering the frontend manager. This means that it is easier to theme the manager interface. MODx revolution also uses Sencha, which makes it easier for developers to create drag-anddrop functionalities and other AJAX features. This also means less testing for crossbrowser compatibility and so on.

      Join the community If you are fascinated by all of the developments going around in MODx, join the community today at and start shaping the future of MODx.

      Summary In this chapter, we have taken a quick look into MODx Revolution, to understand when to upgrade, what to expect, and how to contribute. I hope you had fun with the Revolution from Evolution.

      [ 258 ]

      Index Symbols $MODx->db->getRecordCount about 208 example 208 parameter 208 syntax 208 $MODx->db->makeArray about 208 example 208 parameters 208 syntax 208 $MODx->db->select about 207 example 208 parameters 208 syntax 207 $modx->getAllChildren(1) 207 $modx->getDocument(1) 207 $modx->getTemplateVars 207 $modx object 207 $MODx->regClientCSS ield 245 $modx->setPlaceholder() function about 203 parameters 203 $table_preix variable 207 tag 223 &canpost parameter 141 @CHUNK keyword 64 @DIRECTORY keyword 64 @DOCUMENT keyword 64 @EVAL keyword 64 &extenders parameter 113 @FILE keyword 64 &ilter parameter 112 &irstClass parameter 122 &format parameter 109

      &formid parameter 190 &gotoid parameter 190 tag 220 &hereClass parameter 122 &hereTpl parameter 134 .htaccess ile about 216, 233 structure 217 @INHERIT keyword 64 &innerClass parameter 122 &lastClass parameter 122 &levelClass parameter 122 &level parameter 118 tag 220 #MODx 34 &outerClass parameter 122 &outertpl parameter 133 &parentClass parameter 122 &rowClass parameter 122 &rowTpl parameter 133 @SELECT keyword 64 &selfClass parameter 122 .sql extension 225 &subject parameter 190 | symbol 112 &to parameter 190 &tplForm parameter 141 &tpl parameter 190, 205 [[wayinder]] snippet 115 &webLinkClass parameter 122

      A access restricting, for resource 89 accessible resources verifying, for Friends user group 88

      ActiveParentRowTpl parameter 134 aggregation theming 103, 104 alias 39 alien character 217 Apache 19 application frameworks about 8, 12 advantages 13 disadvantages 13 need for 8, 16 Atom 108 authentication 81 author element 220 authorization 81 Autolink 246

      B blog entry 67-69 blog site creating 65 blog site, creating about 65 blog entry 67-69 NewsEditor, used 65 resource, creating 66, 67 bots 232 breadcrumbs about 132 navigating 133, 134 Bzip2 230

      C cached call 137 caching 70, 137 canonicalization 219 Captcha 232 category resources, assigning to 106 resources, tagging in 105 RSS views, creating for 110, 112 similar post, displaying from 196-199 chunk about 103 creating 143, 144, 206 creating, steps 72, 73

      processing 204, 205 used, as form template 73 used, for theming 132 chunk comments modifying 147, 148 clean URLs about 216 enabling 216 client-side script 10 CMS. See content management system Codeprettify about 240-242 downloading 240 testing 240 Collapse Site Tree icon 41 comments form 142 community-driven documentation 32 conditional statements, PHx about 171 example 171 syntax 171 conig ile 38 Coniguration page, MODx site 36 containers 40 content deining 8 managing 7 content aggregation 99 content attribute 220 content management system about 7, 14 advantages 14 disadvantages 15 functions 7, 8 need for 16 rules 8 conventional three tiers about 9 advantages 10 disadvantages 11 core technologies, MODx Revolution about 258 Sencha 258 xPDO 258 cp functionality 227 cross links 224 cross site scripting. See XSS [ 260 ]

      CSS using 223 curl 226 custom form rendering 72 using, for Post a Blog! page 71 custom plugins using 240, 241 custom XML 108

      D data aggregating, in template 101 database about 228 coniguration ile 230 creating 24-26 exporting 228 importing 229 database abstraction 13 data source binding 64 data types 63 DBAPI 207 default group joining 96 default Learning MODx template modifying 125, 126 default Manager interface page, MODx site 37 default template selecting 58 delimiters 63 dependent plugins 248, 249 description element 220 descriptive texts 223 development environment setting up 19 Ditto about 99, 196, 197 and XML formats 108, 109 multiple iltering clauses 112, 113 parameters, for resource content 100 resource, creating 99 resources, iltering 112 similar post 197-199 DittoCal snippet 154-156

      Ditto, placeholders [+author+] 103 [+id+] 103 [+link+] 103 [+summary+] 103 [+title+] 103 about 103 Doc Manager about 128 tabs 129 working 130 DocManager module 45, 46, 246 documentation, MODx about 31 combined 32 community-driven 32 oficial 32 Document Object Model. See DOM DocumentParser 207 document properties menu details 115, 116 documents about 100 editing 46 documents parameter 100 DOM 8 downloading MODx 23 PHx 160 dynamic behavior template, modifying for 59

      E eform attribute 190 eForm forms 190 eForm snippet about 187 parameters 189, 190 using 187-189 eForm snippet, parameters &formid 190 &gotoid 190 &subject 190 &to 190 &tpl 190 about 189, 190

      [ 261 ]

      entity_encoding variable 238 errors ixing 38 noticing 38 events 235 event-triggering snippets 245 existing plugin coniguring 238 system events 239 using 236 existing templates modifying 60, 61 Expand Site Tree icon 41 extenders 113

      F Family and Friends page adding, to site 159 creating 160, 161 ields 161 template code 162-169 template, creating 162 template variables, creating 161 feed 108 feedburner 224 File Manager tab 234 ile permissions 232 iles snippets, splitting into 214 ilesystem about 224 FTP 225, 226 SFTP 227 WebDAV 227 ilter rule, Ditto format 112 folder parameter 71 formats about 107, 108 atom 108 custom XML 108 JSON 108 RSS 108 forms emailing from 187-189 form template chunk, using as 73

      modifying 76, 77 formtpl parameter 71 fortunes about 209 displaying 210 table, creating 209 forums 175 friendlier URLs 216-219 Friends user group accessible resources, verifying 88 creating 88 Front Page creating for MODx site 43, 44 FTP 225, 226 ftp command 226 fusedav application 228

      G get command 226 GNU General Public License 23 Gnus mode 107 Google 215 Google analytics 224 Google news reader 107 gterm 20

      H Hide Site Tree icon 41 home page about 52 template, modifying 52 templates, using 58 HTML editor using 41, 42 Hypertext Processor. See PHP

      I if keyword 173 image gallery about 182 creating 184, 186 inbound links 224 installation, MODx about 24 database, creating 24-26 [ 262 ]

      diagnostics 28-31 starting 26-28 status 28-31 installation, PHx 160 installation, SMF 175-180 installation, SMF module 180-182 installation, snippets 151 installation, XAMPP on Linux 20 on Windows 20 install directory 232 installing MaxiGallery snippet 183-185 MODx 24 PHx 160 SMF 175-180 SMF module 180-182 snippets 151 WebLoginPE 191 XAMPP, on Linux 20 XAMPP, on Windows 20 interactive support, MODx guidelines 33 IRC 34 web forums 33 Internet Relay Chat. See IRC IRC 32, 34

      J Jot placeholders 149 Jot snippet about 138, 149 parameters 141 with minimal coniguration 139, 140 JSON 108

      K kasablanca 226 keywords 220, 221 kftpgrabber 226 konsole 20 kopete 34

      L lcase modiier 170 len modiier 170 link providing, for user proiles 194-196 Linux XAMPP, installing on 20 login form adding, on site for user login 84-86

      M makefolder parameter 71 MAMP about 21 URL, for downloading 21 manager conigurations about 233 File Manager tab 234 User tab 234 Manager interface 35, 40, 41, 220, 247 Manager user creating 93, 94 MaxiGallery snippet about 182 installing 183-185 menu index 116 menus about 115 pages, removing from 131 menu title about 116 changing 127 meta tags 220 mIRC about 34 URL, for downloading 34 modiiers about 170 lcase 170 len 170 ucase 170 ucirst 170 mod_rewrite module 216 mod_security module 233

      [ 263 ]

      modules about 245 beneits 246 creating 246 executing 246 Manager interface 247 MODx about 7, 115, 207, 243 community 258 containers 40 content aggregation 99 development environment, setting up 19 DocManager module 45, 46 documentation 31 downloading 23 existing plugin, using 236 installing 24 Manager interface 40, 41, 220 modules 245 need for 15, 16 plugins 235 prerequisites 19 snippet, creating 201-203 theming 103 URL, for downloading 23 widgets 64, 65 MODx APIs about 207 DBAPI 207 MODX_BASE_PATH 214 MODx, element resources 39 MODx Evolution about 251 and MODx Revolution, similarity 251 need for 251 MODx forum 33 MODx installer iles 232 MODx, installing about 24 database, creating 24-26 starting 26-28 MODx Manager interface new plugin, creating 160

      MODx Revolution about 253 and MODx Evolution, similarity 251 core technologies 258 feature list 252 need for 251 tags 253 MODx roadmap 252 MODx root folder 57 MODx site Coniguration page 36 coniguring 35, 36 default Manager interface page 37 deploying 224 eForm snippet 187-189 Family and Friends page, adding to 159 forums 175 front page, creating for 43, 44 functionality, adding via PHx 159 image gallery 183-186 security 231 SEO 215 SMF module 175, 180 user proiles 191 MODx site, coniguring 35, 36 MODx site, deploying about 224 conigurations 231 database 228, 229 ilesystem 224 MODx site, security about 231 Captcha 232 ile permissions 232 installer 232 manager conigurations 233 mod_security module 233 writable coniguration ile 232 MODx wiki URL 170 mo operation 172 mount functionality 227 multiple conditions, PHx 172, 173 multiple iltering clauses 112, 113 MySQL 19

      [ 264 ]

      N name changing, of site 38 name attribute 220 nested menus 121, 122 new plugin creating, MODx Manager interface used 160 New Resource icon 41 NewsEditor 65, 69, 70, 78 NewsPublisher 98 new template creating 53 new template, creating about 53 CSS code 54 HTML code 53 New Weblink icon 41 non-bundled snippets using 151 non-cached call 138

      O Object-Relational Mapping. See ORM oficial documentation 32 OnDocFormPrerender event 235 OnUserFormSave event 235 ORM 13 or operator 112 output generating, spinnets used 69

      downloading 160 Family and Friends page, creating 160, 161 functionality, adding to site 159 installing 160 modiiers 170 multiple conditions 172, 173 template variable, formatting 170 URL, for downloading 160 PHx placeholder using 171 PHx wiki documentation URL 173 pidgin 34 placeholders about 57, 99, 103, 148, 149 returning 203 Place Holders extended. See PHx plugin.codeprettify.tpl ile 242 plugins about 235 creating 243, 244 Post a Blog! page custom form, using for 71 verifying 74, 75 post moderation about 92 Manager user, creating 93, 94 role, creating 92 role, verifying 94 Purge icon 41 put command 226



      quality content 224

      pages removing, from menu 131 parameters using 205, 206 parents parameter 100 PHP 10, 19 phpMyAdmin about 209, 225 database, exporting with 228 PHx about 159, 236 conditional statements 171

      R rand() function 210 rating 61 readers 107, 108 Really Simple Syndication. See RSS Refresh Site Tree icon 41 regClientStartupScript ield 245 register_globals 38 resource group 90

      [ 265 ]

      resources about 39 access, restricting for 89 assigning, to category 106 creating 66-99 iltering 112 properties 47 tagging, in separate categories 105 template, changing of 51, 52 resource-speciic variables 61 resources, properties about 47 access permissions 48 General tab 47 settings 48 return keyword 203 rich text editor providing, for blog content area 76 role creating 92 verifying 94 RSS 108 rtcontent parameter 71, 79

      S scp functionality 227 Search Engine Optimization. See SEO select modiier 170 Sencha 258 SEO about 215 clean URLs 216 friendlier URLs 216-219 keywords 220, 221 meta tags 220 site map 221, 222 XHTML 223 SEO tricks alternative text 223 cross links 224 CSS, using 223 descriptive texts 223 inbound links 224 quality content 224 tracking mechanism 224 SFTP 227

      signup form displaying 95 linking 96 similar posts displaying, from category 196-199 simple menu creating 118-120 site name, changing of 38 site map 221, 222 Smarty 258 SMF about 175 installing 175-180 URL, for downloading 175 SMF module about 175 installing 180-182 URL, for downloading 180 snippet 99, 103 snippet.DittoCal.php ile 154 snippeting skills 157 snippets about 69, 137, 159 adding 151, 152 beneits 246 cached call 137 creating 201-203 downloading 151 extracting 151 fortunes, displaying 210 installing 151 non-cached call 138 output, generating 69 parameters 141, 142 performance, improving 212, 213 required iles, copying 153 searching 138 splitting, into multiple iles 214 testing 211, 212 using 154-156 without dependent iles 157 working 137 Sort the Site Tree icon 41 sshfs functionality 227 synchronize users 182 system events 239 [ 266 ]

      T table creating 209 tagcloud snippet 157 tags 61, 253 template about 51 changing, of resource 51, 52 creating 162 creating, steps 55, 56 data, aggregating in 101 ields 56, 57 modifying 60, 61 modifying, for dynamic behavior 59 modifying, of home page 52 using, in home page 58 template code 162-169 Template parameter 71 template variables about 51, 59 creating 61, 62, 76, 106, 161 data source binding 64 formatting, PHx used 170 values 63 Template Variable (TV) 221 templating about 12 advantages 12 disadvantages 12 testing wayinder document content, changing 122, 123 theming about 103, 117 chunks used 132 name, changing for menu title 127 nested menus 121, 122 simple menu, creating 118-120 Three-Tier Architecture 10 TinyMCE editor 42 TinyMCE plugin 238 tracking mechanism 224

      U ucase modiier 170 ucirst modiier 170 user group 90, 91

      userinfo modiier 172 user proiles about 191 editing 192, 193 link, providing for 194-196 viewing 193, 194 user properties 83, 84 user registration about 95 default group, joining 96 signup form, displaying 95 signup form, linking 96 users listing 193, 194 User tab 234

      V values for template variables 63

      W warnings 38 WayFinder about 116 discovering 116, 117 multiple calls 134 wayinder snippet 148 WebDAV 227 web development methodologies about 9 content management systems 14 conventional three tiers 9 templating 12 web forums 33 WebLoginPE about 191 installing 191 user proiles, creating 192, 193 web users about 81 creating 82 What You See Is What You Get. See WYSIWYG editor widgets 64, 65 Windows XAMPP, installing on 20 [ 267 ]

      winscp 225 writable coniguration ile 232 WYSIWYG editor 41

      X XAMPP about 19 installing, on Linux 20 installing, on Windows 20

      XAMPP, installing on Linux 20 on Windows 20 XHTML 223 XML 107 XML formats and Ditto 108, 109 xPDO 258 XSS 38

      [ 268 ]

      Thank you for buying

      MODx Web Development Second Edition

      About Packt Publishing Packt, pronounced 'packed', published its irst book "Mastering phpMyAdmin for Effective MySQL Management" in April 2004 and subsequently continued to specialize in publishing highly focused books on speciic technologies and solutions. Our books and publications share the experiences of your fellow IT professionals in adapting and customizing today's systems, applications, and frameworks. Our solution based books give you the knowledge and power to customize the software and technologies you're using to get the job done. Packt books are more speciic and less general than the IT books you have seen in the past. Our unique business model allows us to bring you more focused information, giving you more of what you need to know, and less of what you don't. Packt is a modern, yet unique publishing company, which focuses on producing quality, cutting-edge books for communities of developers, administrators, and newbies alike. For more information, please visit our website:

      About Packt Open Source In 2010, Packt launched two new brands, Packt Open Source and Packt Enterprise, in order to continue its focus on specialization. This book is part of the Packt Open Source brand, home to books published on software built around Open Source licences, and offering information to anybody from advanced developers to budding web designers. The Open Source brand also runs Packt's Open Source Royalty Scheme, by which Packt gives a royalty to each Open Source project about whose software a book is sold.

      Writing for Packt We welcome all inquiries from people who are interested in authoring. Book proposals should be sent to [email protected] If your book idea is still at an early stage and you would like to discuss it irst before writing a formal book proposal, contact us; one of our commissioning editors will get in touch with you. We're not just looking for published authors; if you have strong technical skills but no writing experience, our experienced editors can help you develop a writing career, or simply get some additional reward for your expertise.

      CMS Design Using PHP and jQuery ISBN: 978-1-84951-252-7

      Paperback: 340 pages

      Build robust and reliable persistence solutions for your enterprise Java application 1.

      Create a completely functional and a professional looking CMS


      Add a modular architecture to your CMS and create template-driven web designs


      Use jQuery plugins to enhance the "feel" of your CMS

      PHP 5 CMS Framework Development - 2nd Edition ISBN: 978-1-84951-134-6

      Paperback: 416 pages

      This book takes you through the creation of a working architecture for a PHP 5-based framework for web applications, stepping you through the design and major implementation issues, right through to explanations of working code examples 1.

      Learn about the design choices involved in the creation of advanced web oriented PHP systems


      Build an infrastructure for web applications that provides high functionality while avoiding pre-empting styling choices


      Implement solid mechanisms for common features such as menus, presentation services, user management, and more

      Please check for information on our titles

      CMS Made Simple 1.6: Beginner's Guide ISBN: 978-1-847198-20-4

      Paperback: 364 pages

      Create a fully functional and professional website using CMS Made Simple 1.

      Learn everything there is to know about setting up a professional website in CMS Made Simple


      Implement your own design into CMS Made Simple with the help of the easy-to-use template engine


      Create photo galleries with LightBox and implement many other JQuery effects like interactive navigation in your website

      Kentico CMS 5 Website Development: Beginner's Guide ISBN: 978-1-84969-058-4

      Paperback: 312 pages

      A clear, hands-on guide to build websites that get the most out of Kentico CMS 5's many powerful features 1.

      Create websites that meet real-life requirements using example sites built with easy-to-follow steps


      Learn from easy-to-use examples to build a dynamic website


      Learn best practices to make your site more discoverable

      Please check for information on our titles