Site Navigation

MODx login link

How to Have a Login Link on Every Page

(Tested with MODx revision 0.9.5.)

Goal: To have a 'Login' link on every page of a web site hosted using MODx. The user may click on this link and get a login screen. Once the web user has logged in (e.g., as 'joe'), he will subsequently see a 'Logout joe' link. (MODx currently allows this for manager logins but not for web users.)

The dynamic 'Login' or 'Logout joe' link will likely defeat caching. If caching is essential, the dynamic link can be replaced by a static 'Login/Logout' link. See below.

One example of a nice Login link implementation is in MediaWiki. It presents an unobtrusive 'Sign in / create account' link. Following this link lets you log in, and then you are given the option ot returning to the page from where you followed the link. This is simple and convenient. The user can be randomly browsing the web site, can log in at any point, and continue browsing from the same place.

Our solution, given below, forces the user to a specific hard-coded web page after completing the login. Fortunately he can use his back button a couple of times to get back to where he was.

1. Note Down Web Page Numbers

MODx assigns a number to each web page. In the procedure below, you will need the number of (a) your web site's home page, and (b) your web site's login page. The home page should already exist. The login page you will create in step 2 below.

In this description we will assume that the home page is number 1 and the login page is number 50. The document tree on the left-hand side of the manager screen shows the web pages and the number assigned to each. Use the numbers appropriate for your own web site's pages.

2. Create Login Page

Go to the menu item: Site -> New Document.

Here we will create a small web page and into it insert the contents shown below. This page will serve as the login page.

On the Page Settings tab:

Uncheck the 'Rich Text' box if not already so.

Uncheck the 'Cacheable' box if not already so.

Change 'Editor to use:' to 'None' if not already so.

Into the Document content box, enter the text shown below between the '-- cut here --' lines. Don't insert the '-- cut here --' lines.

In place of 1 in the text, use the number of the web page to which the user should be sent after he completes the login. Usually this will be the top (home) page of your web site.

On the 'General' tab, insert the string 'Login' into the boxes entitled: title, long title, description, summary, and menu title. Make sure 'Show in menu' is unchecked.

Save.

(Note: Optionally you could leave 'Show in menu' checked, causing your Login link to automatically appear in Wayfinder-generated menus. Then following these instructions exactly may cause duplicate Login links and resulting confusion.)

-- cut here --
<div>
 [!WebLogin? &tpl=`formlogin-whoami` &loginhomeid=`1`!] 
</div>
-- cut here --

Save it. Now you have finished creating the login page. MODx will have assigned it a number. We will use this number in the next step below. For these instructions, let's assume this number is 50. Use the actual number that you see. On the left-hand-side of the manager screen, the document tree will show you the number of each document.

3. Include Login/Logout Fragment in Web Site Template

You should already have a template for your web site. If not, create one at Site -> Home -> Resources -> Templates.

Somewhere in the template, insert the following within a div block. (Don't insert the '-- cut here--' lines.)

-- cut here --
[!whoami!]
-- cut here --

This will be replaced by the Login or Logout link at run time.

This dynamic code defeats caching. It must be evaluated on every page access.

To allow caching, instead of the code above, use the following, which creates a simple html Login/Logout link:

-- cut here --
<a href="[~50~]">Login/Logout</a>
-- cut here --

In place of the '50' use the number of the login page created in step 2 above.

EITHER use the [!whoami!] fragment (nicer, not cached), OR use the Login/Logout link (less nice, but cached). Don't do both.

4. Create a Snippet

Go to the menu item: Site -> Home -> Resources -> Snippets.

Create a snippet called 'whoami' whose contents are as shown below. In place of the number '50', use the number of the login page created in step 2 above. Paste the snippet text into the 'Snippet code (php)' box. Also, on the Properties tab, put the snippet in some category. Save.

-- cut here --
<?php
# do the work
$user = $modx->getLoginUserName();
if ($user) {
  return '<a href="[~50~]?webloginmode=lo">Logout ' . $user . '</a>';
} else {
   return '<a href="[~50~]">Login</a>';
}
?>
-- cut here --

5. Create a Chunk

Go to the menu item: Site -> Home -> Resources -> Chunks.

Create a new chunk called 'formlogin-whoami'. Into the Chunk code (html) box insert the html text shown below between the -- cut here -- lines. I have copied most of it from the existing 'FormLogin' form, and slightly modified it by adding some formatting.

(Note: Due to the way these web pages are designed, some of the code below may be hidden under the side panel. But you should have no trouble selecting it with your web browser so you can do a copy and paste.)

Save.

-- cut here --
<!-- #declare:separator <hr> --> 
<!-- login form section-->
<h3>Not Logged In</h3>
<form method="post" name="loginfrm" action="[+action+]"> 
    <input type="hidden" value="[+rememberme+]" name="rememberme" /> 
    <fieldset>
        &nbsp; <br />
        <label for="username"><tt>Username: </tt><input type="text" name="username" id="username" tabindex="1" onkeypress="return webLoginEnter(document.loginfrm.password);" value="[+username+]" /></label><br />
        <label for="password"><tt>Password: </tt><input type="password" name="password" id="password" tabindex="2" onkeypress="return webLoginEnter(document.loginfrm.cmdweblogin);" value="" /></label><br />
        <input type="checkbox" id="checkbox_1" name="checkbox_1" tabindex="3" size="1" value="" [+checkbox+] onclick="webLoginCheckRemember()" /><label for="checkbox_1" class="checkbox">Remember me on this computer</label> <br />
        <input type="submit" value="[+logintext+]" name="cmdweblogin" class="button" /> <br />&nbsp;<br />
    <a href="#" onclick="webLoginShowForm(2);return false;" id="forgotpsswd">Forget Your Password?</a>
    </fieldset>
</form>
<hr>
<!-- log out hyperlink section -->
<h4>You're logged in</h4>
Do you wish to <a href="[+action+]" class="button">[+logouttext+]</a>?
<hr>
<!-- Password reminder form section -->
<form name="loginreminder" method="post" action="[+action+]">
    <fieldset>
        <h3>It happens to everyone...</h3>
        <input type="hidden" name="txtpwdrem" value="0" />
        <label for="txtwebemail">Enter the email address of your account to reset your password: <input type="text" name="txtwebemail" id="txtwebemail" size="24" /></label>
        <label>To return to the login form, press the cancel button.</label>
        <input type="submit" value="Submit" name="cmdweblogin" class="button" /> <input type="reset" value="Cancel" name="cmdcancel" onclick="webLoginShowForm(1);" class="button" style="clear:none;display:inline" />
    </fieldset>
</form>
-- cut here --

6. Summary

Here is what we did above. On the template for our web site, we included a little [!whoami!] fragment where we want the Login or Logout link to appear (or we inserted a real Login/Logout link). We created a snippet called 'whoami' that checks the user's login status and generates either a 'Login' link or a 'Logout joe' link. We created a Login web page (driven by a template 'formlogin-whoami' that we also created) to which that link points. On this login web page we either log out a logged-in user, or we let a user log in.

All of this is ultimately driven by the Webuserlogin snippet, except that that snippet is called only when a login or logout is needed, and not on every page.

You may need to go to Tools -> Configuration -> Site and specify your template as the 'Default template'.

Now every page that is based on your template should show a Login or Logout link at the place where you inserted the code into the template in step 3.


Rahul Dhesi
Revised: 2007-04-30

•••