Jump to:

5514 Posts in 1733 Topics by 1219 members

Customising the CMS

SilverStripe Forums » Customising the CMS » Customization of the login page

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Page: 1
Go to End
Author Topic: 894 Views
  • vodoomoth
    Avatar
    Community Member
    22 Posts

    Customization of the login page Link to this post

    Hello,

    I have a website that has two locales, fr_FR and en_US and on every page of my website, the header contains a "Login" (en_US) or "Connexion" (fr_FR) link. The link allows users to login and turns into a link for editing the user's profile.

    Question 1:
    I have realized that the login form is displayed in French no matter the language of the page where the link is clicked. I would like to have the login form localized according to the language of the page where the login form link was clicked. How can I do that? Is there some information that I can use to determine the previous page? What programmatic is usually used to know the current session locale?

    Question 2:
    The access to some of my pages (from the blog module) is restricted to some groups. However, those pages appear in the list of articles without being filtered with respect to the user's access rights to individual articles (the lack of filtering isn't a problem for me on the website that I'm currently working on). When a user who isn't connected (or who doesn't have the access rights) clicks to view one of those pages, he is presented with the login page. I would like to make the login page "group-aware" so as to display the names of the groups that can access the "target" page.
    1- Is it possible to find information about the target page (which may be related to question 1) and if yes, how?
    2- Is there a way to list the groups that have access to a page? I'm asking this question because I am not familiar with the architecture of the code, specifically when it comes to the class of objects that have access restrictions attached to them (is it Page? or SiteTree? or some other class?).

    Thank you.

  • vodoomoth
    Avatar
    Community Member
    22 Posts

    Re: Customization of the login page Link to this post

    Question 2, item 2 – way to list the groups that have access to a page, done. Use $this->ViewerGroups() when in a subclass of Page, or $this->owner->ViewerGroups when in a DataObjectDecorator. I used a decorator on BlogEntry and I've been able to insert the list of groups that can view an article right above the article summary, without touching the content of the article.

    Question 1 - determining the previous page, done. Use the BackURL argument: $_REQUEST['BackURL']. It happens that this argument is automatically added when a non-connected user tries to view an access-protected page. This answers Question 2, item 1.

    Question 1 - determining the locale, done. I haven't found a "session locale" per se but I have found that each blog article (and probably any translatable page) has its locale information reachable via… "Locale"! In a decorator, "$locale = $this->owner->Locale;" yields the page's locale in the variable.

    Question 1 - localizing the login form depending on the previous page, WIP. I think I just have to retrieve the object that matches the URL fragment in BackURL. Working on it.

    [EDIT: removed an unwelcome line break]

  • martimiz
    Avatar
    Forum Moderator
    1067 Posts

    Re: Customization of the login page Link to this post

    At question 1 localization of the login form:

    Maybe this post can be of some help: http://www.silverstripe.org/general-questions/show/19556

  • vodoomoth
    Avatar
    Community Member
    22 Posts

    Re: Customization of the login page Link to this post

    @martimiz: thanks for the link; it helped but it didn't solve the problem. I've added the code indicated in Page_Controller.init but thanks to the debugger in Eclipse, I've seen this:
    * non-connected en_US user clicks a link to an access-restricted article
    * Page_Controller.init is called with an ID > 0, requested URL pointing to an en_US page (/pages/articles-en/roadmap), no BackURL, and the locale is then en_US
    * a permission control takes place at some unknown point then there's a redirect to the login page
    * Page_Controller.init is called with an ID < 0, for Security/login, with BackURL = /pages/articles-en/roadmap and the locale is fr_FR.

    At that point, I can no longer know that the real intended target's locale is en_US. Unless I'm able to map the URLSegment in BackURL to a Page object and retrieve that object's locale, which will allow me to change the locale of the login page.

    So to solve this once and for all: how can I map a URLSegment to a Page/SiteTree/whatever is pertinent object? Thank you all.

  • vodoomoth
    Avatar
    Community Member
    22 Posts

    Re: Customization of the login page Link to this post

    OK. I've succeeded in the initial intention which was to have the Login page displayed in the language of an "access-restricted" (don't even know if that's valid English) page.

    It is indeed in Page_Controller.init (in mysite/Page.php) that all the cooking takes place. The whole function is below.

    Please, note that this code is very far from being clean. Too much defensive programming, redundancy, etc. The code will probably not work if the last segment happens to be used for different locales. Put more clearly: if you have mywebsite.com/pages/faq and mywebsite/pages-en/faq, it won't work.

    You've been warned.

       public function init() {
          // Note: you should use SS template require tags inside your templates
          // instead of putting Requirements calls here. However these are
          // included so that our older themes still work
          Requirements::themedCSS('layout');

          //RSSFeed::linkToFeed($this->Link() . "rss", "Flux RSS");

          if($this->dataRecord->hasExtension('Translatable')) {
             i18n::set_locale($this->dataRecord->Locale);
          }
          if ($this->ID < 0) { // we're dealing with a Security virtual page
             $URLSegment = $_REQUEST['BackURL'];
             if (!empty($URLSegment)) {
                $lastSegment = '';
                $lastPos = strrpos($URLSegment, "/");
                $len = strlen($URLSegment);
                if ($lastPos == $len - 1) {
                   $shortenedURL = substr($URLSegment, 0, $len - 1);
                   $lastSegment = substr($shortenedURL, strrpos($shortenedURL, "/") + 1);
                } else {
                   $lastSegment = substr($URLSegment, strrpos($URLSegment, "/") + 1);
                }
                // find the Page that matches the urlfrag
                Translatable::disable_locale_filter();
                $sitetree = DataObject::get_one(
                      'SiteTree',
                      sprintf(
                            '"URLSegment" = \'%s\'',
                            Convert::raw2sql($lastSegment)
                      )
                );
                Translatable::enable_locale_filter();
                // get its locale
                if ($sitetree) {
                   $forcedLocale = $sitetree->Locale;
                   // set the current locale to the page's locale
                   $this->dataRecord->Locale = $forcedLocale;
                   i18n::set_locale($forcedLocale);
                }
             }
          }
          parent::init();
       }

    The finding of the page that matches $lastSegment was taken from ModelAsController.php. To be sure that you've selected the appropriate page, a recursive function is needed so as to ensure that the path matches the selected object. I'm too lazy now to do it. Left as an exercise to you

  • vodoomoth
    Avatar
    Community Member
    22 Posts

    Re: Customization of the login page Link to this post

    Just to share my success (and, unabashedly, to flaunt… just a little).
    The results of the customized login page can be seen in the attached screen captures.

    Last instruction on the how: I've added a decorator to Security. This decorator class has functions that give me the title of the target page and a pretty print listing of its groups (if you've read the previous posts, you'll notice that the pretty print function has been –almost– duplicated in two decorators). To sum up, here are the lines that I've added in mysite/_config.php :

    // for listing the article's ViewerGroups in BlogSummary.ss
    Object::add_extension('BlogEntry','CustomBlogEntry');

    // for forcing the locale of the login page to the locale of the target page
    Object::add_extension('Page_Controller','CustomLoginUtils');
    // for the title and ViewerGroups of the target page (the URL of which is in BackURL)
    Object::add_extension('Security','CustomLoginUtils');

    Last thing, it's quite obvious but stating it won't hurt: there were also some changes done in themes/MyTheme/templates/Security_login.ss

    Hope all that helps someone. Cheers!

    894 Views
Page: 1
Go to Top

Want to know more about the company that brought you SilverStripe? Then check out SilverStripe.com

Comments on this website? Please give feedback.