-
- What is DG3
- The different components
- Requirements for running DG3
- Installation of DG3
- Additional installation steps
- Select which web server to use
- Hello World application
- Intro to CMS
- Setting up DG3 as a CMS
- Editing pages
- More about pages and urls
- Structuring a page using the grid
- Adding menu to pages
- Add images to the application
- More formating
- Sending email from contact us
- Adding menu to template
- Deploy the web site
- Storing the pages in database
- Create record
- Auto fill field
- Field validation
- Enable save button validator
- Add new button to template
- View document
- List documents
- Fix selection in menus in template
- CRUD Create Read Update Delete
- Intro to blogs
- Add user authentication
- Bootstrap authentication
- Let user change their passords
- Add reset password
- Login dialog box
- Extending the CMS to a blog
- Extend table for blogging
- Edit blog entry
- View blog entry
- User registration
- User password validation
- User field validation
- User auto login
- User extra registration fields
Login dialog box
You do not always want a separate page for login in to your solution. In this example we will create a popup login form that will be shown as a dialog when you click on the login link. The link will show login when you not are authenticated and an action menu with all your action and logout when you are authenticated. To achieve this we will introduce a couple of new techniques, the if template tag and hidden elements that can be shown on a click on a link.
The if template tag
DG3 has a vast template language. You can use this to manipulate what gets loaded at run time based on livetext. We have already used it when we fixed the menus in the CMS, but here is a bit more about what you can do and how it works.
{% if user.is_authenticated %} <p>Show this if I am authenticated</p> {% else %} <p>Show this if I am not authenticated</p> {% endif %}
This works by running the check done in the if part of the tag and render the part between the if and the else it is true. If not it will render the part from else tag to endif. In the example you use the livetext user element as found in the authentication document earlier in this chapter. You can use all template tags in both pages and direct template, but then you will have to make sure to use the right form [% tag %] in pages and {% tag %} in direct templates. Since the DG3 is using the Django template engine internally, all tags described in the Django template documentation can be used in DG3 as well. We also add extra tags in DG3 as we see the need for them. These can then be loaded into the documents with the load tag followed by the name of the extention.
Code for checking if you are authenticated or not
In the menu we want to show the action menu if we are logged om an the login link if not. Since we are doing this in a direct template tag, the template tags use the syntax {% for start tag and %} for end tag.
Code for creating the login box
#loginbox { position:absolute; top: 1px; left: 1000px; background-color: darkgray; height: 150px; width: 200px; border: 1px solid; } .hidden { display: none; }
The added code to base.css. The position is not need, just to remind our self of approx position it will get from the javascript code.
<!DOCTYPE html> <html> <head> <script type="text/javascript"> $(document).ready(function(){ // Show and position the dialog when you click on the login link $('#loginlink').on('click', function(e) { var mypos=$(this).offset(); mypos.left -= 120; var lb = $('#loginbox'); lb.css(mypos); lb.removeClass('hidden'); }); // Remove the dialog when clicking cancel instead of login $('#logincancel').on('click', function(e) { var lb = $('#loginbox'); lb.addClass('hidden'); }); }); </script> </head> <body> <nav class="navbar navbar-default" role="navigation"> <div class="container"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="/">DG3 by Example</a> </div> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> ... </ul> <ul class="nav navbar-nav navbar-right"> {% if user.is_authenticated %} ... {% else %} <li> <a id="loginlink" href="javascript:void(0)">Login</a> </li> {% endif %} </ul> </div> </div> </nav> {% if user.is_authenticated == False %} <div id="loginbox" class="hidden"> <form method="post" action="/authentication/login/?next=.">{% csrf_token %} <h4 class="text-center">Please login</h4> <div class="form-group"> <div class="col-sm-12"> <input id="id_username" type="text" name="username" class="form-control" maxlength="254" placeholder="user name"> </div> </div> <div class="form-group"> <div class="col-sm-12"> <input id="id_password" type="password" name="password" class="form-control" placeholder="password"> </div> </div> <div class="form-group"> <div class="col-sm-6"> <a id="logincancel" class="btn btn-default" href="javascript:void(0)">Cancel</a> </div> <div class="col-sm-6"> <input id="loginsubmit" class="btn btn-success pull-right" type="submit" value="login" /> <input type="hidden" name="next" value="[{ next }]" /> </div> </div> </form> </div> {% endif %} </body>
The code for the login popup is devided into 3 section.
CSS
First we must add the needed css to our base.css file. This consist of one generic element for making hidden elements by setting a class. This is simpler than manipulating the display attribute directly and gives cleaner code. By adding in to base.css, we can use it for any other element we need to hide.
Login form
The next part is the for dialog code. We can find this to the end out our html code in this example. We have added a if tag, so we only loads this code when not logged in. This form will be loaded and hidden on all pages as long as the user not have logged in. A possible better solution is to load the login when we click the link, but this we will come back to in our all ajax forms in a later chapter. If you look at the content of the for, it is exactly the same as we created when we updated the login form, except that we have got rid of the labels and use placeholders instead. All is contained inside the loginbox div that is hidden and styled with absolute position, darkgray background, fixed height and width and a solid border. What happens when you subimit the form is excactly the same as when using the login page except that we told the page to reload current page as the next page. This is done by using the '.' as next page. The '.' means my current url. If you get a login error, this will send you to the standard login page with an error message. This is a good reason to fix the looks as well as that is the page that will be used if you try to enter a page that requires authentication when not logged in.
Javascript (jQuery)
As the final part we have the javascript that makes all work. What is does is to trigger on click for the login element in the menu. The login link is set up with a the same id as selected in the javascript and a href="javascript:void(0)" to not trigger any link when clicked. Next we get the position of the login link and calculates where we want our loginbox to be placed based on this and then set the position of the loginbox and show it by removing the hidden class. We do not bother to remove the loginbox as it will trigger a page reload when ok is clicked.
The end result
Login link only
When you have clicked on the link.