1. Getting Started
      1. Video Quick-Start Series
      2. Server Requirements
        1. MySQL 5.0.51 Issues
      3. Installation
        1. Basic Installation
          1. MODx Revolution on Debian
          2. Problems with WAMPServer 2.0i
          3. Lighttpd Guide
          4. Installation on a server running ModSecurity
          5. MODX and Suhosin
          6. Nginx Server Config
        2. Successful Installation, Now What Do I Do?
        3. Successful Installation, Now What Do I Do?
        4. Advanced Installation
        5. Git Installation
        6. Command Line Installation
          1. The Setup Config Xml File
        7. Troubleshooting Installation
        8. Using MODx Revolution from SVN
      4. An Overview of MODX
        1. Glossary of Revolution Terms
          1. Explanation of Directory Structure
        2. Roadmap
        3. MODX Revolution Framework Structure Ideology
        4. What's New in 2.3
    2. FAQs & Troubleshooting
      1. CMP Development FAQs & Troubleshooting
    3. Making Sites with MODX
      1. Structuring Your Site
        1. Resources
          1. Content Types
          2. Named Anchor
          3. Static Resource
          4. Symlink
            1. Using Resource Symlinks
          5. Weblink
        2. Templates
        3. Chunks
        4. Using Snippets
      2. Tag Syntax
      3. Customizing Content
        1. Template Variables
          1. Creating a Template Variable
          2. Adding a Custom TV Type - MODX 2.2
          3. Bindings
            1. CHUNK Binding
            2. DIRECTORY Binding
            3. EVAL Binding
            4. FILE Binding
            5. INHERIT Binding
            6. RESOURCE Binding
            7. SELECT Binding
          4. Template Variable Input Types
          5. Template Variable Output Types
            1. Date TV Output Type
            2. Delimiter TV Output Type
            3. HTML Tag TV Output Type
            4. Image TV Output Type
            5. URL TV Output Type
          6. Adding a Custom TV Input Type
          7. Adding a Custom TV Output Type
          8. Creating a multi-select box for related pages in your template
          9. Accessing Template Variable Values via the API
        2. Properties and Property Sets
        3. Input and Output Filters (Output Modifiers)
          1. Custom Output Filter Examples
      4. Commonly Used Template Tags
        1. Date Formats
    4. Administering Your Site
      1. Settings
        1. System Settings
          1. access_category_enabled
          2. date_timezone
          3. access_context_enabled
          4. access_resource_group_enabled
          5. allow_duplicate_alias
          6. allow_forward_across_contexts
          7. allow_multiple_emails
          8. allow_tags_in_post
          9. archive_with
          10. automatic_alias
          11. auto_check_pkg_updates
          12. auto_check_pkg_updates_cache_expire
          13. auto_menuindex
          14. base_help_url
          15. blocked_minutes
          16. cache_action_map
          17. cache_context_settings
          18. cache_db
          19. cache_db_expires
          20. cache_db_session
          21. cache_default
          22. cache_disabled
          23. cache_format
          24. cache_handler
          25. cache_json
          26. cache_json_expires
          27. cache_lang_js
          28. cache_lexicon_topics
          29. cache_noncore_lexicon_topics
          30. cache_resource
          31. cache_resource_expires
          32. cache_scripts
          33. cache_system_settings
          34. clear_cache_refresh_trees
          35. compress_css
          36. compress_js
          37. concat_js
          38. container_suffix
          39. cultureKey
          40. custom_resource_classes
          41. default_per_page
          42. default_template
          43. editor_css_path
          44. editor_css_selectors
          45. emailsender
          46. emailsubject
          47. enable_dragdrop
          48. error_page
          49. extension_packages
          50. failed_login_attempts
          51. feed_modx_news
          52. feed_modx_news_enabled
          53. feed_modx_security
          54. feed_modx_security_enabled
          55. fe_editor_lang
          56. filemanager_path
          57. filemanager_path_relative
          58. filemanager_url
          59. filemanager_url_relative
          60. forgot_login_email
          61. friendly_alias_lowercase_only
          62. forward_merge_excludes
          63. friendly_alias_max_length
          64. friendly_alias_restrict_chars
          65. friendly_alias_restrict_chars_pattern
          66. friendly_alias_strip_element_tags
          67. friendly_alias_translit
          68. friendly_alias_translit_class
          69. friendly_alias_translit_class_path
          70. friendly_alias_trim_chars
          71. friendly_alias_urls
          72. friendly_alias_word_delimiter
          73. friendly_alias_word_delimiters
          74. friendly_urls
          75. friendly_url_prefix
          76. friendly_url_suffix
          77. global_duplicate_uri_check
          78. hidemenu_default
          79. link_tag_scheme
          80. mail_charset
          81. mail_encoding
          82. mail_smtp_auth
          83. mail_smtp_helo
          84. mail_smtp_hosts
          85. mail_smtp_keepalive
          86. mail_smtp_pass
          87. mail_smtp_port
          88. mail_smtp_prefix
          89. mail_smtp_single_to
          90. mail_smtp_timeout
          91. mail_smtp_user
          92. mail_use_smtp
          93. manager_date_format
          94. manager_direction
          95. manager_favicon_url
          96. manager_language
          97. manager_lang_attribute
          98. manager_theme
          99. manager_time_format
          100. context_tree_sort
          101. context_tree_sortby
          102. context_tree_sortdir
          103. session_enabled
          104. upload_files
          105. modx_charset
          106. new_file_permissions
          107. new_folder_permissions
          108. password_generated_length
          109. password_min_length
          110. phpthumb_allow_src_above_docroot
          111. phpthumb_cache_maxage
          112. phpthumb_cache_maxfiles
          113. phpthumb_cache_maxsize
          114. phpthumb_cache_source_enabled
          115. phpthumb_document_root
          116. phpthumb_error_bgcolor
          117. phpthumb_error_fontsize
          118. phpthumb_error_textcolor
          119. phpthumb_far
          120. phpthumb_imagemagick_path
          121. phpthumb_nohotlink_enabled
          122. phpthumb_nohotlink_erase_image
          123. phpthumb_nohotlink_text_message
          124. phpthumb_nohotlink_valid_domains
          125. phpthumb_nooffsitelink_enabled
          126. phpthumb_nooffsitelink_erase_image
          127. phpthumb_nooffsitelink_require_refer
          128. phpthumb_nooffsitelink_text_message
          129. phpthumb_nooffsitelink_valid_domains
          130. phpthumb_nooffsitelink_watermark_src
          131. phpthumb_zoomcrop
          132. principal_targets
          133. proxy_auth_type
          134. proxy_host
          135. proxy_password
          136. proxy_port
          137. proxy_username
          138. publish_default
          139. rb_base_dir
          140. rb_base_url
          141. request_controller
          142. request_param_alias
          143. request_param_id
          144. resource_tree_node_name
          145. resource_tree_node_tooltip
          146. richtext_default
          147. search_default
          148. server_offset_time
          149. server_protocol
          150. session_cookie_domain
          151. session_cookie_lifetime
          152. session_cookie_path
          153. session_cookie_secure
          154. session_handler_class
          155. session_name
          156. settings_version
          157. signupemail_message
          158. site_name
          159. site_start
          160. site_status
          161. site_unavailable_message
          162. site_unavailable_page
          163. strip_image_paths
          164. symlink_merge_fields
          165. tree_default_sort
          166. tree_root_id
          167. tvs_below_content
          168. udperms_allowroot
          169. ui_debug_mode
          170. unauthorized_page
          171. upload_maxsize
          172. use_alias_path
          173. use_browser
          174. use_editor
          175. use_multibyte
          176. welcome_screen
          177. which_editor
          178. which_element_editor
          179. xhtml_urls
      2. Using Friendly URLs
      3. Contexts
        1. Creating a Subdomain from a Folder using Virtual Hosts
        2. Using One Gateway Plugin to Manage Multiple Domains
      4. Customizing the Manager
        1. Customizing the Manager via Plugins
        2. Form Customization Profiles
        3. Form Customization Sets
          1. Customizing Tabs via Form Customization
          2. MODX GitHub Contributor's Guide
        4. Manager Templates and Themes
      5. MODX GitHub Integrator's Guide
      6. Security
        1. Hardening MODX Revolution
        2. Policies
          1. ACLs
          2. Permissions
            1. Permissions - Administrator Policy
            2. Permissions - Resource Policy
          3. PolicyTemplates
        3. Resource Groups
        4. Roles
        5. Security Standards
        6. Security Tutorials
          1. More on the Anonymous User Group
          2. Creating a Second Super Admin User
          3. Giving a User Manager Access
          4. Making Member-Only Pages
          5. Restricting an Element from Users
        7. Troubleshooting Security
          1. Resetting a User Password Manually
        8. User Groups
        9. Users
      7. Installing a Package
        1. Troubleshooting Package Management
      8. Upgrading MODX
        1. Upgrading to Revolution 2.0.5
        2. Upgrading from 2.0.x to 2.1.x
        3. Upgrading from Versions Earlier than 2.0.5
        4. Upgrading to 2.2.x
        5. Upgrading to Revolution 2.0.0-rc-2
        6. Troubleshooting Upgrades
        7. Upgrading from MODx Evolution
          1. Functional Changes from Evolution
      9. Moving Your Site to a New Server, or to Root from Subfolder
      10. Media Sources
        1. Adding a Media Source
        2. Assigning Media Sources to TVs
        3. Media Source Types
          1. Media Source Type - File System
          2. Media Source Type - S3
        4. Securing a Media Source
          1. Creating a Media Source for Clients Tutorial
      11. Dashboards
        1. Assigning a Dashboard to a User Group
        2. Creating a Dashboard Widget
        3. Dashboard Widget Types
          1. Dashboard Widget Type - File
          2. Dashboard Widget Type - HTML
          3. Dashboard Widget Type - Inline PHP
          4. Dashboard Widget Type - Snippet
        4. Managing Your Dashboard
    5. Developing in MODX
      1. Code Standards
      2. Overview of MODX Development
        1. Developer Introduction
          1. Getting Started Developing
        2. Extras Directories
        3. Setting up a Development Environment
      3. Basic Development
        1. Static Elements
        2. Plugins
          1. System Events
            1. OnMODXInit
            2. OnFileManagerBeforeUpload
            3. OnFileManagerDirCreate
            4. OnFileManagerDirRemove
            5. OnFileManagerDirRename
            6. OnFileManagerFileCreate
            7. OnFileManagerFileRemove
            8. OnFileManagerFileRename
            9. OnFileManagerFileUpdate
            10. OnPackageInstall
            11. OnPackageUninstall
            12. OnPackageRemove
            13. OnBeforeCacheUpdate
            14. OnBeforeChunkFormDelete
            15. OnBeforeChunkFormSave
            16. OnBeforeDocFormDelete
            17. OnBeforeDocFormSave
            18. OnBeforeEmptyTrash
            19. OnBeforeManagerLogin
            20. OnBeforeManagerLogout
            21. OnBeforeManagerPageInit
            22. OnBeforePluginFormDelete
            23. OnBeforePluginFormSave
            24. OnBeforeSaveWebPageCache
            25. OnBeforeSnipFormDelete
            26. OnBeforeSnipFormSave
            27. OnBeforeTempFormDelete
            28. OnBeforeTempFormSave
            29. OnBeforeTVFormDelete
            30. OnBeforeTVFormSave
            31. OnBeforeUserActivate
            32. OnBeforeUserFormDelete
            33. OnBeforeUserFormSave
            34. OnBeforeWebLogin
            35. OnBeforeWebLogout
            36. OnCacheUpdate
            37. OnCategoryBeforeRemove
            38. OnCategoryBeforeSave
            39. OnCategoryRemove
            40. OnCategorySave
            41. OnChunkBeforeRemove
            42. OnChunkBeforeSave
            43. OnChunkFormDelete
            44. OnChunkFormPrerender
            45. OnChunkFormRender
            46. OnChunkFormSave
            47. OnChunkRemove
            48. OnChunkSave
            49. OnContextBeforeRemove
            50. OnContextBeforeSave
            51. OnContextFormPrerender
            52. OnContextFormRender
            53. OnContextRemove
            54. OnContextSave
            55. OnDocFormDelete
            56. OnDocFormPrerender
            57. OnDocFormRender
            58. OnDocFormSave
            59. OnDocPublished
            60. OnDocUnPublished
            61. OnEmptyTrash
            62. OnFileManagerUpload
            63. OnHandleRequest
            64. OnInitCulture
            65. OnLoadWebDocument
            66. OnLoadWebPageCache
            67. OnManagerAuthentication
            68. OnManagerLogin
            69. OnManagerLoginFormPrerender
            70. OnManagerLoginFormRender
            71. OnManagerLogout
            72. OnManagerPageAfterRender
            73. OnManagerPageBeforeRender
            74. OnManagerPageInit
            75. OnPageNotFound
            76. OnPageUnauthorized
            77. OnParseDocument
            78. OnPluginBeforeRemove
            79. OnPluginBeforeSave
            80. OnPluginEventRemove
            81. OnPluginFormDelete
            82. OnPluginFormPrerender
            83. OnPluginFormRender
            84. OnPluginFormSave
            85. OnPluginRemove
            86. OnPluginSave
            87. OnPropertySetBeforeRemove
            88. OnPropertySetBeforeSave
            89. OnPropertySetRemove
            90. OnPropertySetSave
            91. OnResourceGroupBeforeRemove
            92. OnResourceGroupBeforeSave
            93. OnResourceGroupRemove
            94. OnResourceGroupSave
            95. OnRichTextBrowserInit
            96. OnRichTextEditorInit
            97. OnRichTextEditorRegister
            98. OnSiteRefresh
            99. OnSiteSettingsRender
            100. OnTemplateVarBeforeRemove
            101. OnTemplateVarBeforeSave
            102. OnTemplateVarRemove
            103. OnTemplateVarSave
            104. OnUserActivate
            105. OnUserBeforeRemove
            106. OnUserBeforeSave
            107. OnUserChangePassword
            108. OnUserFormDelete
            109. OnUserFormSave
            110. OnUserNotFound
            111. OnUserRemove
            112. OnUserSave
            113. OnWebAuthentication
            114. OnWebLogin
            115. OnWebLogout
            116. OnWebPageComplete
            117. OnWebPageInit
            118. OnWebPagePrerender
        3. Snippets
          1. Adding CSS and JS to Your Pages Through Snippets
          2. How to Write a Good Chunk
          3. How to Write a Good Snippet
          4. Templating Your Snippets
        4. xPDO
      4. Advanced Development
        1. Caching
          1. Setting up Memcache in MODX
        2. Custom Manager Pages
          1. Custom Manager Pages in 2.3
          2. Actions and Menus
            1. Action List
          3. Custom Manager Pages Tutorial
          4. MODExt
            1. MODx.combo.ComboBox
            2. MODx.Console
            3. MODx.FormPanel
            4. MODx.grid.Grid
            5. MODx.grid.LocalGrid
            6. MODx.msg
            7. MODx.tree.Tree
            8. MODx.Window
            9. MODExt Tutorials
              1. 1. Ext JS Tutorial - Message Boxes
              2. 2. Ext JS Tutorial - Ajax Include
              3. 3. Ext JS Tutorial - Animation
              4. 4. Ext JS Tutorial - Manipulating Nodes
              5. 5. Ext JS Tutorial - Panels
              6. 7. Ext JS Tutoral - Advanced Grid
              7. 8. Ext JS Tutorial - Inside a CMP
            10. MODExt MODx Object
        3. Custom Resource Classes
          1. Creating a Resource Class
            1. Creating a Resource Class - Step 2
            2. Creating a Resource Class - Step 3
            3. Creating a Resource Class - Step 4
        4. Extending modUser
        5. From the Command Line (CLI)
        6. Internationalization
          1. Adding a Translation
        7. MODX Services
          1. modFileHandler
          2. modMail
          3. modRegistry
        8. Namespaces
        9. Package Management
          1. Package Dependencies
          2. Creating a 3rd Party Component Build Script
          3. Providers
          4. Transport Packages
        10. Using runProcessor
        11. Validating Requests: Tokens and Nonces
        12. Developing RESTful APIs
      5. Other Development Resources
        1. Summary of Legacy Code Removed in 2.1
        2. API Reference
        3. Class Reference
          1. modResource
            1. modResource.isMember
          2. modChunk
            1. modChunk.getContent
            2. modChunk.setContent
          3. modUser
            1. modUser.addSessionContext
            2. modUser.changePassword
            3. modUser.endSession
            4. modUser.getSessionContexts
            5. modUser.getSettings
            6. modUser.hasSessionContext
            7. modUser.isAuthenticated
            8. modUser.isMember
            9. modUser.loadAttributes
            10. modUser.removeSessionContext
            11. modUser.removeSessionContextVars
            12. modUser.removeSessionCookie
          4. modX
            1. modX.addEventListener
            2. modX.checkForLocks
            3. modX.checkSession
            4. modX.executeProcessor
            5. modX.getAuthenticatedUser
            6. modX.getCacheManager
            7. modX.getChildIds
            8. modX.getChunk
            9. modX.getConfig
            10. modX.getContext
            11. modX.getEventMap
            12. modX.getLoginUserID
            13. modX.getLoginUserName
            14. modX.getParentIds
            15. modX.getParser
            16. modX.getPlaceholder
            17. modX.getRegisteredClientScripts
            18. modX.getRegisteredClientStartupScripts
            19. modX.getRequest
            20. modX.getResponse
            21. modX.getService
            22. modX.getSessionState
            23. modX.getTree
            24. modX.getUser
            25. modX.getVersionData
            26. modX.handleRequest
            27. modX.hasPermission
            28. modX.initialize
            29. modX.invokeEvent
            30. modX.lexicon
            31. modX.makeUrl
            32. modX.parseChunk
            33. modX.regClientCSS
            34. modX.regClientHTMLBlock
            35. modX.regClientScript
            36. modX.regClientStartupHTMLBlock
            37. modX.regClientStartupScript
            38. modX.reloadConfig
            39. modX.removeAllEventListener
            40. modX.removeEventListener
            41. modX.runProcessor
            42. modX.runSnippet
            43. modX.sendError
            44. modX.sendErrorPage
            45. modX.sendForward
            46. modX.sendRedirect
            47. modX.sendUnauthorizedPage
            48. modX.setDebug
            49. modX.setPlaceholder
            50. modX.setPlaceholders
            51. modX.switchContext
            52. modX.toPlaceholder
            53. modX.toPlaceholders
            54. modX.unsetPlaceholder
            55. modX.unsetPlaceholders
        4. Loading MODX Externally
        5. Reserved Parameters
    6. Case Studies and Tutorials
      1. Developing an Extra in MODX Revolution
        1. Developing an Extra in MODX Revolution, Part II
        2. Developing an Extra in MODX Revolution, Part III
      2. Developing an Extra in MODX Revolution - MODX 2.1 and Earlier
        1. Developing an Extra in MODX Revolution, Part II - MODX 2.1 and Earlier
        2. Developing an Extra in MODX Revolution, Part III - MODX 2.1 and Earlier
      3. PHP Coding in MODx Revolution, Pt. I
        1. PHP Coding in MODx Revolution, Pt. II
        2. PHP Coding in MODx Revolution, Pt. III
      4. Using Custom Database Tables in your 3rd Party Components
      5. Creating a Blog in MODx Revolution
      6. Loading Pages in the Front-End via AJAX and jQuery Tabs
      7. Reverse Engineer xPDO Classes from Existing Database Table
      8. Integrating a Template into MODX Tutorial
      9. Quick and Easy MODX Tutorials
        1. Automated Server-Side Image Editing
      10. Adding Custom Fields to Manager Forms
      11. Create a Multilingual Website with migxMultiLang
      12. Managing Resources and Elements via SVN
    7. MODX Community Information
      1. Becoming a Core Contributor
      2. Filing Bug Reports
      3. Getting a MODx Account
      4. Using GitHub

Code Standards

Last edited by Susan Ottwell on Feb 6, 2015.

Code Standards

This page describes the MODX coding standards for any MODX Component, Extension or core code. These are not de-facto rules, but guidelines for easier development and collaboration between developers.

This page was heavily borrowed from Fellowship One's Design Standards. Thanks!

General Practices

Indentation and Line Breaks

All indentation must be done with 4 spaces, not tabs. Make sure to change your editor settings to reflect this. Line breaks must be in UNIX format.

Trailing Spaces

MODX recommends removing any trailing spaces in a line in code, unless that spacing is for design purposes.

Compression

MODX suggests packaging both compressed and uncompressed JS/CSS. MODX recommends using the compressed JS/CSS in production environments, but allowing users the option to toggle between compressed and uncompressed JS/CSS. This allows for easier debugging.

MODX does not advocate PHP compression.

HTML

HTML5 is a new version of HTML and XHTML. The HTML5 draft specification defines a single language that can be written in HTML and XML. It attempts to solve issues found in previous iterations of HTML and addresses the needs of Web Applications, an area previously not adequately covered by HTML. ( from html5.org)

MODX recommends following the HTML5 specs: http://whatwg.org/specs/web-apps/current-work/

Validation

All HTML must be HTML5-validated. MODX recommends using the W3C Validator.

Inline HTML in Snippets

MODX requires that no html be echo'ed or inline in a Snippet. MODX also recommends externalizing any HTML in PHP code into Chunks.

All HTML pages should be verified against the W3C validator, to ensure that the markup is well formed. This in and of itself is not directly indicative of good code, but it helps to weed out problems that are able to be tested via automation. It is no substitute for manual code review.

Note: In TextMate, Control + Shift + V will check the validity of the currently open HTML document.

Self-closing Elements

Though we are using HTML5, which allows for either HTML or XHTML style syntax, we prefer the strictness of XHTML. Therefore, all tags must be properly closed. For tags that can wrap nodes such as text or other elements, termination is a trivial enough task. For tags that are self-closing, the forward slash should have exactly one space preceding it
vs. the compact but incorrect
. The W3C specifies that a single space should precede the self-closing slash (source).

Terseness

Doctype

A nice aspect of HTML5 is that it streamlines the amount of code that is required. Meaningless attributes have been dropped, and the DOCTYPE declaration has been simplified significantly. Additionally, there is no need to use CDATA to escape inline JavaScript, formerly a requirement to meet XML strictness in XHTML.

"HTML5 Doctype"
<!DOCTYPE html>
"XHTML 1.0 Transitional Doctype"
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Tags and Attributes

All tags and attributes must be written in lowercase. Additionally, we prefer that any attribute values also be lowercase, when the purpose of the text therein is only to be interpreted by machines. For instances in which the data needs to be human readable, proper title capitalization should be followed, such as:

"For machines"
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
"For humans"
<a href="http://example.com/" title="Description Goes Here">Example.com</a>

Quotes

In keeping with the strictness of XHTML code conventions, according to the W3C, all attributes must have a value, and must use double-quotes (source). The following are examples of proper and improper usage of quotes and attribute/value pairs.

"Correct"
<input type="text" name="email" disabled="disabled" />
"Incorrect"
<input type=text name=email disabled>

CSS

Inline Styles

We strive to maintain proper separation of content and design, and therefore highly discourage the use of inline style="..." attributes. This not only makes maintenance a nightmare, but inextricably ties the presentation to the data it represents. All of our CSS will be stored in external files, with one master.css file called per page. That single file will incorporate other files as necessary with the @import syntax.

Note: An exception to this rule is style="display:none" for revealing hidden elements via JavaScript.

CSS Validation

All cascading stylesheets should be verified against the W3C validator, to ensure correct syntax and to check for possible accessibility issues with text and background colors. This in and of itself is not directly indicative of good code, but it helps to weed out problems that are able to be tested via automation. It is no substitute for manual code review.

Note: In TextMate, Control + Shift + V will check the validity of the currently open CSS document.

CSS Formatting

To ease potential headaches for maintenance, we require that all CSS be written in a consistent manner. For one, all CSS selectors must be listed on their own line. As a general rule of thumb, if there is a comma in CSS, it should immediately be followed by a line break. This way, we know that all text on a single line is part of the same selector. Likewise, all property/value pairs must be on their own line, with one tab of indentation. The closing brace must be on the same level of indentation as the selector that began it - flush left.

"Correct"
#selector_1 span,
#selector_2 span,
#selector_3 span {
    background: #fff;
    color: #000;
}
"Incorrect"
#selector_1 span, #selector_2 span, #selector_3 span {
    background: #fff; color: #000;
}
"Also incorrect"
#selector { background: #fff; color: #000; }

Pixels vs. Ems

We use the px unit of measurement to define font size, because it offers absolute control over text. We realize that using the em unit for font sizing used to be popular, to accommodate for Internet Explorer 6 not resizing pixel based text. However, all major browsers (including IE7 and IE8) now support text resizing of pixel units and/or full-page zooming. Since IE6 is largely considered deprecated, pixels sizing is preferred. Additionally, unit-less line-height is preferred because it does not inherit a percentage value of its parent element, but instead is based on a multiplier of the font-size.

"Correct"
/*
13 * 1.5 = 19.5 ~ Rounds to 20px.
*/
#selector {
    font-size: 13px;
    line-height: 1.5;
}
"Incorrect"
/*
Equivalent to 13px font-size and 20px line-height,
but only if the browser default text size is 16px.
*/
#selector {
    font-size: 0.813em;
    line-height: 1.25em;
}

Internet Explorer Bugs

Inevitably, when all other browsers appear to be working correctly, any and all versions of Internet Explorer will introduce a few nonsensical bugs, delaying time to deployment. While we encourage troubleshooting and building code that will work in all browsers without special modifications, sometimes it is necessary to use conditional if IE comments to serve up specific fixes, which are ignored by other browsers.

"Fixing IE"
<!--[if IE 7]>
<link type="text/css" rel="stylesheet" href="/assets/styleshseets/ie7.css" />
<![endif]-->
<!--[if IE 8]>
<link type="text/css" rel="stylesheet" href="/assets/styleshseets/ie8.css" />
<![endif]-->

Shorthand

In general, CSS shorthand is preferred because of its terseness, and the ability to later go back and add in values that are already present, such as the case with margin and padding. Developers should be aware of the TRBL acronym, denoting the order in which the sides of an element are defined, in a clock-wise manner: Top, Right, Bottom, Left. If bottom is undefined, it inherits its value from top. Likewise, if left is undefined, it inherits its value from right. If only the top value is defined, all sides inherit from that one declaration.

For more on reducing stylesheet code redundancy, and using CSS shorthand in general:

Margin & Padding

"Correct"
#selector {
    margin: 0 0 10px;
    padding: 0 0 10px;
}
"Incorrect - left attribute unnecessary"
#selector {
    margin: 0 0 10px 0;
    padding: 0 0 10px 0;
}

Hex Colors

We prefer hex values for all colors, written in lower-case. No upper-case or RGB, please! Additionally, all colors should be written as tersely as possible. This means that colors such as full blue, which can be written lengthily as #0000FF, should be simply written as #00f. Obviously, for colors that require more precision, all six characters should be used. For example, a light shade of grayish beige: #f9f9f0.

Background

"Correct - shorthand"
#selector {
    background: #fff url(../images/file.png) repeat-x fixed left bottom;
}
"Incorrect - longhand unnecessary"
#selector {
    background-color: #fff;
    background-image: url(../images/file.png);
    background-repeat: repeat-x;
    background-attachment: fixed;
    background-position: left bottom;
}

Border

In general, border should be a single line declaration, assuming that the values of the border are the same on all sides of the element. The order in which values are declared are: width, style, and color.

"Shorthand - method 1"
#selector {
    border: 1px solid #000;
}

If the values of each side differ, then there are two possible ways of using shorthand, and it is up to the discretion of the developer to decide which to use. Note that method 2 follows the TRBL pattern.

"Shorthand - method 2"
#selector {
    border-color: #fff #999 #666 #ccc;
    border-style: solid dashed dotted double;
    border-width: 1px 2px 3px 4px;
}
"Shorthand - method 3"
#selector {
    border-top: 1px solid #fff;
    border-right: 2px dashed #999;
    border-bottom: 3px dotted #666;
    border-left: 4px double #ccc;
}

By contrast, the same style declaration is extremely verbose using longhand. This should be avoided, except in instances where only one particular value needs to be overridden, allowing the rest to flow through.

"Longhand"
#selector {
    border-top-color: #fff;
    border-right-color: #999;
    border-bottom-color: #666;
    border-left-color: #ccc;
    border-top-style: solid;
    border-right-style: dashed;
    border-bottom-style: dotted;
    border-left-style: double;
    border-top-width: 1px;
    border-right-width: 2px;
    border-bottom-width: 3px;
    border-left-width: 4px;
}

Font

Not to be confused with the inadvisable tag, the CSS font property can be written in a few different ways. The shorthand property puts all the aspects of the font into a single declaration, whereas the longhand splits it out over several lines. While the contrast between methods is not as stark as with that of the border property, there is still space to be saved by using shorthand. While line-height can be defined within the scope of the font declaration, but when written in longhand it has its own unique property.

Note: Times New Roman is encapsulated in quotes, because the font name itself contains spaces.

"Shorthand"
<font>#selector {
    font: italic small-caps bold 15px/1.5 Cambria, 'Times New Roman', sans-serif;
}
</font>
"Longhand"
<font>#selector {
    font-style: italic;
    font-variant: small-caps;
    font-weight: bold;
    font-size: 15px;
    line-height: 1.5;
    font-family: Cambria, 'Times New Roman', sans-serif;
}
</font>

Longhand

When overriding only parts of a style, longhand declaration is preferred. This way, by sticking to shorthand for initial style declarations, anytime we see a longhand declaration used, we know that we are specifically overriding only a very precise part of an overall style, thereby leaving other aspects unaffected.

"Longhand override"
<font>#selector {
    border: 1px solid #ccc;
    font: 11px Verdana, sans-serif;
}
#selector.modifier {
    border-bottom-color: #333;
    border-bottom-width: 2px;
    font-family: Georgia, serif;
}
</font>

Javascript

Type Coercion

Unlike strongly typed languages such as Java or C#, JavaScript will perform type coercion when evaluating conditional statements. This sometimes creates awkward scenarios in which numerical values are seen as false or the existence of a string is mistaken for true. This is typically disadvantageous.

To ensure a strict level of comparison, as might be seen in a strongly typed or compiled language, JavaScript (like PHP) has a triple-equals operator ===. In similar fashion, it also has a strict negation operator !==. Consider the following examples of potential pitfalls when it comes to evaluating comparisons.

<font>var test_1 = 'true';
var test_2 = 0;
if (test_1 == true) {
    // Code here will run.
    // But it shouldn't.
}
if (test_1 === true) {
    // Code here won't run.
    // Correct behavior.
}
if (test_2 != false) {
    // Code here won't run.
    // But it should.
}
if (test_2 !== false) {
    // Code here will run.
    // Correct behavior.
}
</font>

As you can see in the example above, simply using == and != is insufficient because it makes for potentially unpredictable results. Therefore, the stricter comparison operators should always be used. There is never a good reason to use the lesser form of comparison operators. To simply for the existence of elements in the DOM, there is an even more abbreviated way, that leaves no room for ambiguity. If you are unsure if certain elements will be present in an HTML page, use one of the following techniques.

<font>function first_func() {
    if (!document.getElementById('id_name')) {
        return;
    }
    // If code gets here, element exists.
}
function second_func() {
    if (!document.getElementsByTagName('div').length) {
        return;
    }
    // If code gets here, one or more exist.
}
</font>

White-space

In general, the use of whitespace should follow longstanding English reading conventions. Such that, there will be one space after each comma and colon (and semi-colon where applicable), but no spaces immediately inside the right and left sides of parenthesis. In short, we advocate readability within reason. Additionally, braces should always appear on the same line as their preceding argument.

Consider the following examples of a JavaScript for-loop...

"Correct"
<font>for (var i=0, j=arr.length; i<j; i++) {
    // Do something.
}
</font>
"Incorrect"
<font>for ( var i = 0, j = arr.length; i < j; i++ )
{
// Do something.
}
</font>

Variables, ID & Class

All JavaScript variables shall be written in completely lowercase letters, with underscores to separate words if need be. Likewise, all id and class declarations in CSS shall be written in the same manner. Neither dashes nor camelCase shall be used, except for words that contain dashes when written in plain English.

Quotes

The preferred method of delineating strings is to use single quotes for everything. Since JavaScript exists to manipulate markup, and because HTML is generally written with double quotes in W3C specifications, using single quoted strings will better facilitate handling HTML fragments, and keep code more readable.

"Correct"
<font>var my_html = '<img class="photo" src="/path/file.jpg" alt="Text" />';
</font>
"Incorrect"
<font>var my_html = "<img class=\"photo\" src=\"/path/file.jpg\" alt=\"Text\" />";
</font>

Event Listeners

Rather than using attributes such as onload, onfocus, onsubmit, or onclick directly in markup, we will instead attach event listeners to these elements via unobtrusive techniques. The reasoning for this is the same philosophy that is behind not using inline style="..." declarations. So doing inextricably ties the behavior of a web page to its data, and makes maintenance more difficult.

Event Delegation

When assigning unobtrusive event listeners, it is typically acceptable to assign the event listener directly to the element(s) which will trigger some resulting action. However, occasionally there may be multiple elements which match the criteria for which you are checking, and attaching event listeners to each one might negatively impact performance. In such cases you should use event delegation instead.

Closures & Scope

To maintain proper scope for variables, it is highly recommended that self-executing anonymous function be used as a closure. For the most part, variables defined correctly using the var syntax, within the scope of a function will not add to global scope pollution. However, from time to time, you may need to access variables via two or more functions. In such cases, multiple functions can be grouped together inside a closure.

"Closure"
<font>(function() {
    var first_variable = 'value 1';
    var second_variable = 'value 2';
    function first_func() {
        // Do something.
    }
    function second_func() {
        // Do something.
    }
})();
</font>

Objects & Arrays

Objects can be thought of as tiered variables that contain multiple attributes. Similarly, an array could be described as a list of data that all share common characteristics. The following code snippets show examples of objects and arrays, and the different ways in which they can be defined. Note that values such as John Doe's age and marital status do not have quotation marks around them. This is because age is truely numerical, and true is a Boolean value.

Note also that the commas are before the variable or method declaration. This prevents errors with trailing commas in IE and other browsers.

Objects (and arrays) are an important part of JSON - JavaScript Object Notation, which is a platform and language independent way of transmitting data, used as an alternative to XML.

"Object literal - preferred"
<font>var john_doe = {
    first_name: 'John'
    ,last_name: 'Doe'
    ,job: 'Everyman Respresentative'
    ,email: 'john.doe@example.com'
    ,married: true
    ,age: 30
};
</font>
"Object dot notation"
<font>/*
Could also be written:
var john_doe = new Object();
*/
var john_doe = {};
john_doe.first_name = 'John';
john_doe.last_name = 'Doe';
john_doe.job = 'Everyman Representative';
john_doe.email = 'john.doe@example.com';
john_doe.married = true;
john_doe.age = 30;
</font>
"Array literal - preferred"
<font>var doe_family = [
    'John'
    ,'James'
    ,'Jane'
    ,'Jenny'
    ,'Jared'
    ,'Jerome'
];
</font>
"Array bracket notation"
<font>/*
Could also be written:
var doe_family = new Array();
*/
var doe_family = [];
doe_family[0] = 'John';
doe_family[1] = 'James';
doe_family[2] = 'Jane';
doe_family[3] = 'Jenny';
doe_family[4] = 'Jared';
doe_family[5] = 'Jerome';
</font>

PHP

General

  • Beginning brackets do NOT linebreak. They start one space after the end parenthesis, as according to traditional Unix policy.
  • Do not do any real logic in object constructors. Create class methods to do so.
  • null, true and false should always be lowercase.
  • Avoid embedded assignments (ex: $d = ($a = $b + $c) is bad).
  • Never use extract().
  • Avoid using global variables if at all possible.
  • Document EVERYTHING.

Parenthesis

  • Do not put parenthesis next to keywords. Put a space between.
  • Do put parenthesis next to function names.
  • Do not use parenthesis in return statements when it's not necessary. Example:
    if ($test) {
    }
    while ($test == $other) {
    }
    array_push($one,$two);
    return $test;
    	

  • Do not use parenthesis when using include, require, include_once, and require_once.

Classes

  • All ''core'' classnames, unless stated otherwise for special conditions, will be prefixed with the "mod" prefix: ie, modChunk, modTemplate, etc.
  • All method names will be camelCase and will start with a lowercase letter.
  • All private methods and variables must be prefixed with the underscore _ character.
    class modFactor {
        public $publicVar;
        private $_privateVar;
        private function _privateFunc() { }
        public function publicFunc() { }
    }
    	

Variables

Note these are not function arguments.

  • Use all lowercase letters.
  • Separate words with the underscore.

Function Arguments and Class Variables

  • The first letter is lowercase, rest are camelCase. Example:
    class modFactor {
        public function testFunc($testVar, array &$anotherTest = array()) {
            $this->_privateVar = $testVar;
            $local_variable =& $anotherTest;
        }
    }
    	

Arrays

  • Array index names use the underscore _, not the dash as their separator. This prevents errors with magic_quotes.
  • Array index names are always lowercase. Spaces are represented by an underscore.
  • Array index names are always encapsulated with single quotes.
    Example:
    $_lang['chunk_create_text'] = 'Test';
    	

Constants

  • Constants must be in all UPPERCASE letters.
  • Use only if absolutely necessary.

File Structure

  • Always name PHP class files in name.class.php format.

Prefixing

  • Lexicon strings for Components need to be prefixed:
<font>$_lang['mycomponent.welcome_message'] = 'Welcome!';
</font>
  • Always prefix class names; eg: 'finBank', 'finTransaction', etc.
  • Always prefix Chunk names; eg: 'finStatement', 'finDeposit'

SQL

All inline SQL must be capitalized, and table and column names must be enclosed with backticks.

"Correct"
<font>UPDATE `mydatabase`.`mytable`
SET `name` = "Johnny"
WHERE `id` = 123;
</font>
"Incorrect"
<font>update mydatabase.mytable set name='Johnny' where id=12
</font>

Comment Policy

These comments are not for usage questions or support. See below for support options.

Comments intended add specific value for other users with this document are welcome! Have a suggestion to improve this document? Suggest an edit (requires GitHub account). Have suggestions for code changes or feature requests? Submit to the Revolution project at GitHub..

Support Options

If you need assistance, you can get it via the MODX Forums or the MODX Community Slack.

Suggest an edit to this page on GitHub (Requires GitHub account. Opens a new window/tab) or become an editor of the MODX Documentation.