• How to make a horizontal menu in modx. Multi-level MODX menu using Bootstrap. What is Wayfinder

    Let's start lesson 8 of MODx Revolution for beginners. Let me remind you that we are making a website for studying MODx Revolution. In the last lesson, we looked at the concept of snippets, which are pieces of PHP code that allow us to add functionality to our website. In this lesson we will look at a special snippet - Wayfinder, and we will use it to create a dynamic menu for our website.

    What is Wayfinder?

    Wayfinder is a snippet that displays an unsorted list of links to resources in your site tree; the type of list output depends on the snippet call and the parameters of this call. In general terms, this means that when you place a Wayfinder call in your template, it starts looking for resources that meet the parameters specified in it and returns a list of links to those resources in an unsorted list format or in a format you define.

    Why use Wayfinder?

    I usually use Wayfinder to create dynamic website navigation, that is, menus. Since most HTML templates use unordered lists to create menus, Wayfinder is the ideal tool for this purpose. When creating a site, you can painstakingly insert your URLs into the navigation menu, just as you did before in a static HTML site. At the same time, every time you need to delete or create a page, you need to make the appropriate changes to your menu, change the URLs. Using the Wayfinder snippet to dynamically generate your menus avoids this headache because it automatically detects changes and changes your menu accordingly.

    Wayfinder is quite a flexible tool and allows you to determine what resources to include or exclude from the menu, what the menu template is, how deep the menu of your site is. The limit of your capabilities is determined by your HTML/CSS code.

    How to use Wayfinder?

    As we already mentioned in the previous lesson, the syntax for calling snippets looks like this: [[!somesnippet]]

    This is just a basic call and it is not enough, besides this we must define some properties of this call. In the case of Wayfinder, the very minimum that needs to be defined in the properties is where in the resource tree Wayfinder should start building a list of resources. Thus, in calling the Wayfinder snippet, you must specify at least one parameter - the initial ID. The basic call to the Wayfinder snippet in this case will look like this:

    This call tells the Wayfinder to start at the root of the tree ( ID 0 means the root of the site) and shows all resources that are published and that do not have a checkmark in the checkbox Hide from Menus.

    If we take a look at the template we're using, we can see a top menu with several options and drop-down lists.

    Let's take a look at the template and code that displays this menu:

    As you can see, this is a nested unordered list. Let's replace this code with a basic Wayfinder call and see what we get. Delete the code above and paste in its place:

    [[!Wayfinder? &startId=`0` ]]

    If you're using the same template as me, your code will look something like this:

    Save the template and look at the home page, it should look like this:

    Fantastic! You can see that our previous menu, which had several options, has now been replaced with a simple menu with only one item - Home. This tells us that Wayfinder is working as expected and is taking one page from our site and displaying its title as a menu item.

    Let's create a couple more resources. I'm going to add an About page with 3 child pages (MODx, Tutorials, Contact and FAQ pages). You can create any resources or pages for your site. The goal of this exercise is to create several resources so that Wayfinder has something to display.

    I'm done creating pages and my site resource tree looks like this:

    Now we have several pages, let's see how calling Wayfinder will generate a menu for our site:

    The good news is that all our pages have appeared in the menu and by clicking on each menu item we are taken to the corresponding page. (To test this element, add some text to each page, for example on the About page you could add “This is an About page” and this message will appear when the page is opened. Remember that we need to define a template for each page, but at the moment I don’t I'm going to worry about it).

    The bad news is that the menu formatting is broken, but we can fix it. Right click on the web page and look at the source code (or use firebug for this), you will see that now Wayfinder generates HTML like this:

    • Home
    • About
      • MODx CMS
      • The Coding Pad
        • The Blog
        • The Services
    • Contact Us
    • Tutorials
    • FAQ

    As you can see this looks very similar to our initial static code with a few exceptions. First, Wayfinder generated

      item without class sf-menu which was used in our static code. The template needs this class to work with CSS. It is also clear that
    • items have a parameter span, which refers to the link text elements in the original static code and is not present in the generated Wayfinder code. In addition, our static HTML code has a class current-page-item, which is not represented in our Wayfinder snippet code. All these missing pieces make our menu look unsightly.

      How to customize the output style of a Wayfinder snippet

      Looking at how Wayfinder generates the code, a very natural question arises: “How can we add the missing pieces of code so that we want to display the menu in the form we need?” The answer is very easy, we use template chunks to format the output of the Wayfinder snippet.

      Wayfinder is a flexible tool and you can use parameters to define the appearance of the output. Some general parameters allow you to determine at what level to start building a menu, which items not to include in the menu, etc. Other parameters are template parameters, which allow you to set the HTML template code for your menu, etc. Descriptions of the latter can be found in the official documentation - http://rtfm.modx.com/display/ADDON/Wayfinder.

      Take note: Some Wayfinder parameters have default values.

      This explains, for example, why in the Wayfinder-generated menu, the Home page item has the class name “ first active" This is the default class, but we can override it by defining our own classes in template chunks.

      We'll be using several Wayfinder options in this tutorial, but I encourage you to explore them all and practice using them as much as possible to understand all of their capabilities. Since Wayfinder's default settings are clearly documented on the official website, it would be foolish to talk about them here. We'll be using more and more of these as we work through different menus.

      To start working on the menu template, let's create several mini-templates and save them in chunks. You will see that in these chunks we are using HTML code, but replacing dynamic elements fillers(or placeholders as they are also called) the syntax of which looks like this: [[+placeholder]]. The placeholders we use are specific to the Wayfinder snippet and their definition is obvious from the name, but you can always refer to the MODx documentation for more complete help.

      Here are the chunks I'll use to create our template:

      7in1menuOuter– will contain the HTML code for our external ul container.

        [[+wf.wrapper]]

      You can see that I have added a class for the outer ul. An alternative way to do this is to use the wf.classes placeholder and then append the class name to the current wayfinder call using the parameter outerClass. But for simplicity, let's use the first method, but both of them will work fine...

      7in1menuRow– will contain the HTML code of the first level menu items

    • [[+wf.linktext]][[+wf.wrapper]]
    • The main idea here is that I added the tag to the menu link text as in the original static HTML code. I also included the wf.classes placeholder and this will allow me to define a class for the current page that will override the default “active” class.

      7in1menuInner– will contain the HTML code of the internal ul containers

        [[+wf.wrapper]]

      7in1menuInnerRow– will contain HTML code for lines of internal level items

    • [[+wf.linktext]][[+wf.wrapper]]
    • That's it, now our template chunks are in place, as you can see (for the sake of order, I placed them in a separate category):

      Now we can change the Wayfinder call so we can use these mini templates to output the Wayfinder. If you look at the list of templating parameters (it would be useful to have http://rtfm.modx.com/display/ADDON/Wayfinder open in front of you, or print it out and keep it near the screen), you will see that I called my chunks similar to the corresponding ones snippet call parameters. I did this for convenience, it helps me keep track of what's what when I start constructing my call. Let's add parameters and call our chunks. The Wayfinder call will now look like:

      [[!Wayfinder? &startId=`0` &outerTpl=`7in1menuOuter` &rowTpl=`7in1menuRow` &innerTpl=`7in1menuInner` &innerRowTpl=`7in1InnerRow` &hereClass=`current_page_item` &firstClass=`` &lastClass =`` ]]

      Parameter values ​​are placed in apostrophes (`) rather than single quotes (').

      Great, let's take a look at this challenge. You can see that we use templating options to call our chunks so that Wayfinder outputs the HTML we need with the correct classes. I have defined the callee hereClass parameter and gave it a value current_page_item so that it matches the static HTML template. You may notice that I left the parameters firstClass And lastClass empty. The reason for this is that my HTML template does not set a class for the first and last menu item, so to avoid overlap I overwrote empty strings in them.

      It can be seen that our menu looks exactly the way we wanted. The correct styles are used in the dropdown menu. If you look at the source code you will see that the generated Wayfinder‘om HTML code has changed beyond recognition:

      • Home
      • About
        • MODx CMS
        • The Coding Pad
          • The Blog
          • The Services
      • Contact Us
      • Tutorials
      • FAQ

      This code matches the original static code of our template, but it was generated by calling Wayfinder.

      There are many other options that you can use along with Wayfinder for building your menus. In the following lessons we will look at complex menus and how to integrate them into Wayfinder. To summarize: our website has now taken some form and we have a functional and dynamic menu.

      In previous lessons we have already created a MODX menu: 1st - and 2nd - Output of a standard MODX drop-down menu using Bootstrap. Today we will learn how to display multi-level Bootstrap menus with an unlimited degree of nesting (3-level menu, 4-level, 5-level, etc.).

      For example, I will display a 5-level Bootstrap menu, but you can make it 3-level or 7-level, even 10, by changing the value level to what you need!

      Displaying a multi-level Bootstrap menu (with unlimited nesting) in MODX using PdoMenu.

      The output of the multi-level menu will be like this:

      []>[[+wrapper]]

    ` &tplInner=`@INLINE ` &tplParentRow=`@INLINE
  • [[+menutitle]] [[+wrapper]]
  • ` ]]

    It won't work out of the box. since Bootstrap 3 by default only supports 2 nesting levels, and in order to expand the nesting level of the bootstrap 3 menu, you need to include a js file with the following content.

    (function($)( $(document).ready(function())( $("ul.dropdown-menu ").on("click", function(event) ( event.preventDefault(); event.stopPropagation() ; $(this).parent().removeClass("open"); $(this).parent().toggleClass("open" ));

    After that, the 3rd, 4th, etc. will begin to open. nesting levels. In principle, everything, but there is one thing, this menu will open down all levels, and in my opinion this is not particularly correct or beautiful, but this can be fixed using CSS.

    In my case, it took 2 lines of CSS code to make the levels fall sideways.

    Ul.dropdown-menu (left: 100%;top: -8px;) li.submenu1.dropdown.open>ul.dropdown-menu (left: 0%; top: 100%;)

    You may receive a slightly different (but identical) code and the number of its lines may be greater if you have several menu branches with submenus. Well, there are still some little things that you will have to adjust the CSS to suit your taste, my goal is to show the basics. How to find the necessary CSS classes in the code to which you need to apply styles is shown in the video, but to be more precise, the entire process of creating a multi-level menu is shown there.

    This is the menu in my video:

    If you needed to rotate the triangles in a dropdown menu (they point downwards when items drop out to the left), it would look like this.

    Then add the following css code:

    Li.submenu2.dropdown>a>span.caret ( -moz-transform: rotate(-95deg); -ms-transform: rotate(-95deg); -webkit-transform: rotate(-95deg); -o-transform: rotate(-95deg); transform: rotate(-95deg); li.submenu3.dropdown>a>span.caret ( -moz-transform: rotate(-95deg); -ms-transform: rotate(-95deg); - webkit-transform: rotate(-95deg); -o-transform: rotate(-95deg); transform: rotate(-95deg); 95deg); -ms-transform: rotate(-95deg); -webkit-transform: rotate(-95deg);

    Greetings, dear readers. In the last lesson we filled the site with some content (), now it’s time display everything in the menu so that users can navigate to them.

    Create dynamic menu in MODX we will use a snippet PdoMenu from the package pdoTools. Before you begin, please read the main documentation.

    pdoMenu Documentation

    Options

    Template Options

    CSS Class Options

    Official examples


    You can read the official documentation here. Now let’s look at the most typical menu calls.

    Call PdoMenu

    Option 1. In place of this static menu call the snippet pdoMenu, for this in the resource tree, on the “ tab Elements” in the snippets section, expand the thread pdoTools, then click on pdoMenu left mouse button (do not release the button) and drag this snippet to the place where you want to open the menu, then in the window that opens, fill in the necessary parameters and click “ Save«.

    Option 2. We just write the call manually.

    Typical examples

    Regular one-level menu

    For example, we have the most common menu, with the following html markup.

    The result is the following code for calling the menu:

    • &parents=`0` - list of parents (in my case I do not limit the selection, since I will only display certain pages anyway);
    • &level=`1` — nesting level (in this case there is none);
    • &resources=`2,3,4,5` — list of resources that need to be displayed in the menu;
    • &firstClass=`0` — class for the first menu item (not which one);
    • &lastClass=`0` — class of the last menu item (not which one);
    • &outerClass=`top-menu` — menu wrapper class (substituted in ul);
    • &hereClass=`current-menu-item` — class for the active menu item (substituted in li);
    • &rowClass=`menu-item` - class of one menu line (substituted in li).

    Two-level custom bootstrap menu

    Static html code looks like this:

    Its output code will be like this:

    Also in the next lesson I will give a couple more outputs of drop-down menus based on bootstrap (and, this is for those who did not catch the essence. Well, then we’ll do it.

    At first glance, everything looks complicated, but it’s not so, read the documentation in more detail, ask questions in the comments, I’ll definitely help.

    Date of publication: 02/07/2011

    In this simple tutorial I will show you how to customize the menu.

    I was once asked to fix a bug with a menu on one website - some items stubbornly did not want to line up, but instead appeared in unexpected places on the page when hovering the cursor. The bug was not in crooked css, as I first assumed, but in a crooked Wayfinder call.

    What is Wayfinder- this is a snippet that is used when you need to display a list of documents in a section/s. As a result of the snippet, an unnumbered list is generated. Using various parameters, you can do anything with this list :) You can read more in the documentation, or by typing in Google - “wayfinder modx wiki”.

    Important Notes:

    1. About what MODx is, how to install MODx, how to organize the structure of documents, how to make a template from html, what a chunk is, etc. I do not consider questions from beginners in this lesson.

    2. The placeholders that I will use in the lesson are indicated in the format that the Evo version “understands”. What is the difference, see example:

    So, let's look at creating a menu step by step.

    Step 1

    For the lesson I sketched out this menu:

    Here, for clarity, I have applied different styles to different menu levels. On the site where I fixed the bug with the menu, it was approximately the same - each menu level has its own style.

    Layout - the details of the layout are not included in the scope of this lesson, this is the code I got:

    After admiring the code, we determine for ourselves which class in our menu is responsible for what (if you are poking around in someone else’s code, it should be clear in your own):

    ul class="menu" - class of the entire menu
    li class="top" - class of top-level menu items
    a class="top_link" - class for links in top-level items
    ul class="sub" - class for the submenu
    well, span class="down" for designing top-level items

    Step 2. Create three documents

    Products
    - Delivery
    - Suppliers
    We create child documents for the “Products” document: “Truth Serum”, “Makropoulos Remedy”, “Universal Remedies”.

    Step 3. Place the menu in a separate chunk

    In the template, in the place where you should have a menu, we remove all the extra code (the html code of the menu itself), and write instead

    (( menu))

    Thus, we put the menu in a separate chunk. Then we create a new chunk and call it menu. For now, you can copy the menu code that you created into the contents of the chunk. For clarity.

    Go to the admin panel in “Site” -> “View” - to check that everything is fine with the paths to the style file and images.

    Did it work? Ok, but this is not a menu yet. Let's breathe life into it with the help of Wayfinder.

    Step 4

    Remove all contents of the menu chunk and call the Wayfinder snippet instead.
    For now let's write it like this:

    [[ Wayfinder? &startId=`0`]]

    startId parameter- indicates which document to start forming the list from. We have 0 specified - this means that the list is formed from the root of the document tree.

    Let's see what happened:

    This is a working and live menu. Rename documents, delete, add - the menu will be formed in accordance with the document tree.

    Step 5

    5.1. Now we bring the appearance of the menu back to normal

    Wayfinder by default generates a simple code () , all classes of lists and elements are specified by special parameters when called.

    At the beginning of the lesson, we determined which CSS classes in our menu are responsible for what. Wayfinder has the parameters we need: outerClass- class for the menu container. Comparing with our layout, we get the following Wayfinder call:

    [[ Wayfinder? &startId=`0` &level=`2` &outerClass=`menu`]]

    in addition to parameters with classes, we indicate nesting level - &level=`2`.

    We note the shortcomings - there are no classes for top-level menu items, no tags and a class for the submenu.
    All these shortcomings are corrected by adding the appropriate parameters to the Wayfinder call.

    5.2. Adding classes to top-level items and tags

    There is a variable for this rowTpl, which describes a template for a menu item, we make such a template, for this we create a chunk called parent:

  • [+wf.linktext+][+wf.wrapper+]
  • In the Wayfinder call we add &rowTpl=`parent` .
    Don't forget to check the source code - almost everything is fine, only a submenu remains.

    To configure the submenu, use the innerRowTpl variable.

    Creating a chunk inner:

  • [ +wf.linktext+][ +wf.wrapper+]
  • Add a variable to the Wayfinder call innerRowTpl=`inner` and a variable that specifies the class for the submenu container &innerClass=`sub` .

    The final Wayfinder call looks like this:

    [ ]

    That's it, our menu is ready. Good luck!



    Wayfinder serves to organize lists of links for MODX. Thanks to the support of templates, it allows you to display lists in any desired form:
    • Menu in the form of a list, table, images, with icons, etc.
    • Static menus
    • Menu with various effects (drop-down, drop-down, etc.)
    • Site map
    Example call:


    &rowTpl=`rowTpl`
    &outerTpl=`outerTpl`
    &hereClass=`active`
    &rowClass=`eNav_li`]]

    Snipet parameters:

    &startId- id of the parent page, if you specify 0 it will be from the root of the site. The default value is the id of the active page

    &displayStart - show document with startId in menu title, default false

    &level- nesting depth, default 0 - all levels

    &limit- limit the number of pages in the output (default 0 - no restrictions)

    &ignoreHidden- ignore the checkbox of the "Show in menu" page, i.e. if you specify 1, it will display all pages. Default is 0. Only those pages that have the “Show in menu” checkbox checked are displayed.

    &ph - the name of the substitute that replaces the directly printed results. Default is 0.

    &debug- debug mode (default 0)

    &hideSubMenus - expand only the active submenu (default 0)

    &removeNewLines- removes the line break character during output (default 0)

    &textOfLinks- for the name of the menu link. Possible options:menutitle, id, pagetitle, description, parent, alias, longtitle, introtext . Default menutitle

    &titleOfLinks- for the title of the menu link. Options:menutitle, id, pagetitle, description, parent, alias, longtitle, introtext. Default pagetitle

    &rowIdPrefix- sets id (rowIdPrefix + docId) for each element. Default 0

    &includeDocs- id of documents separated by commas that will be included in the menu (not specified by default)

    &excludeDocs - id of documents separated by commas that will be excluded from the menu (default 0)

    &contexts- context for menu generation. Default is current.

    &startIdContext - ID of the context from which documents are taken to generate the result.

    &config - External PHP file to store Wayfinder configuration (example: core/components/wayfinder/configs).

    &scheme - Format for generating URLs. Possible values ​​(based on the makeURL API call):

    1: (default) URL relative to site_url;

    0: see http;

    1: see https;

    full: absolute URL starting with site_url;

    abs: absolute URL starting with base_url;

    http: absolute URL, forced in the http scheme;


    https: absolute URL, forced in the https scheme.

    &sortBy - The field by which the sorting occurs. (default menuindex)

    Options:

    id, menutitle, pagetitle, introtext, menuindex, published, hidemenu, parent, isfolder, description, alias, longtitle, type, template

    &sortOrder- Sorting order."ASC" or "DESC". Default ASC

    &where - JSON style of filtering parameters (Corresponds to where in MySQL). For example, when you need to hide a blog or news from the Articles add-on: &where=`[("class_key:!=": "Article")]`
    Examples:
    output folders only: & where = `isfolder = 1

    &hereId - Determine the current ID to use in the snippet. Use the [[*id]] value if the template is specified using the hereTpl parameter and activeRowParentTpl is not applied correctly in the menu item. The default is the current ID.
    It only needs to be specified if the script itself incorrectly defines it, for example, when displaying a menu from a chunk of another snippet.

    &hereTpl - The hereTpl template is used when the current item is displayed in the menu.
    Possible placeholders:
    [[+wf.classes]] - place to specify the CSS class to use (includes class=" ")
    [[+wf.classnames]] - contains only the name of the CSS class (does not include class=" ")
    [[+wf.link]] - address (href) for the link
    [[+wf.title]] - text for the title of the link
    [[+wf.linktext]] - link title text
    [[+wf.wrapper]] - place to display submenu
    [[+wf.id]] - output of a unique identifier (id)
    [[+wf.attributes]] - display additional link attributes
    [[+wf.docid]] - document identifier for the current element
    [[+wf.subitemcount]] - number of items in the folder
    [[+wf.description]] - displays the values ​​of the description field
    [[+wf.introtext]] - displays the values ​​of the introtext field

    Example template: [[+wf.linktext]][[+wf.wrapper]]

    Template Options

    These parameters specify the chunks that contain the patterns that will generate Wayfinder output.

    In the current version of Wayfinder for MODX Revolution, you can access your custom TVs using wf prefix placeholders. , for example [[+my_TV]]

    At the time of writing, only the original TV values ​​will be returned - they will not be formatted. For example, if your TV is an image - the normal usage is that a TV inside your template will return the full full image tag, but inside a Wayfinder template - only the path to the image will be returned.

    If you want to handle TV, you can do so by calling a snippet within the Wayfinder row template (&rowTpl . For example, your TV image is called icon and usually the template uses code like this for output:

    ... ...

    But since this will not allow you to process TV, you need to replace it with:

    ... ...

    And now inside the processTV snippet we place the following PHP code:

    getObject("modResource", $myId); return $doc->getTVValue($myTV);

    As a result, a fully processed TV image is returned.

    &outerTpl

    The name of the chunk containing the external container template.

    Available placeholders:

    • wf.classes - displays classes taken from the Wayfinder parameter set (including the class="") attribute
    • wf.classnames - display class names (without class="")
    • wf.wrapper - output of internal content (row).
      [[+wf.wrapper]]

    The &innerTpl parameter contains the same set of placeholders as &outerTpl .

    &rowTpl

    The name of the chunk containing the template for the menu row elements.

    Available placeholders:

    • wf.classes - class output (including the class="") attribute
    • wf.classnames - output of the corresponding classes (without class="")
    • wf.link - href="" attribute value for the menu link
    • wf.title - name of the title text for the link from the field specified in the &titleOfLinks parameter
    • wf.linktext - text for the active link specified in the field passed in the &textOfLinks parameter
    • wf.wrapper - display internal content, such as submenu
    • wf.id - displays the unique ID of the attribute. You need to specify the &rowIdPrefix parameter in order for this placeholder to receive a value. The value is the prefix + docId.
    • wf.attributes - displays the attributes link for the current element
    • wf.docid - document identifier of the current element
    • wf.description - description for the current element
    • wf.level - current nesting level

    Usage example:

    [[+wf.linktext]][[+wf.wrapper]]

    Another option:

  • [[+wf.linktext]] - [[+wf.description]] [[+wf.wrapper]]

  • Examples

    First level


    [[!Wayfinder? &startId=`0` &level=`1`
    &rowTpl=`rowTpl`
    &outerTpl=`outerTpl`
    &hereClass=`active`
    &rowClass=`eNav_li`]]

    Chunk code outerTpl



      [[+wf.wrapper]]

    RowTpl chunk code



      [[+wf.wrapper]]

    Second level (in this example, the menu and submenu items were visually at the same level

    [[!Wayfinder? &startId=`0` &level=`2`
    &rowTpl=`rowTplFooterMenu`
    &outerTpl=`outerTplFooterMenu`
    &innerTpl=`innerTplFooterMenu`
    &innerRowTpl=`innerRowTplFooterMenu`
    &hereClass=`active`]]

    Chunk code outerTplFooterMenu



    [[+wf.wrapper]]

    chunk code rowTplFooterMenu




    • [[+wf.title]]


    • [[+wf.wrapper]]

    innerTplFooterMenu chunk code

    [[+wf.wrapper]]

    chunk code innerRowTplFooterMenu



  • [[+wf.title]]