Jump to content
doolin

Try to create a Custom Login site

Recommended Posts

Hi guys

I try to create a custom login page. So i read a lot in the forum about this, but i don't understand how i have to implement it. The login page was no problem, i use the code from ryan here:


And customize my login page. At the moment is this site my default admin page: 

/admin. 

So my first idea was..I create a new site called "login" and add my custom Login site as template to this site. This worked fine, but now i have two more problems:

First, when the user logout via the custom logout links, he gets back to the old default login site "/admin". I've tried to change this in the admin template, without success. I use the Default admin theme.

Second: The created page "login" is visible in the site tree, but it should be hidden for non admin user, so i move the "login" site below the admin site, but now the non admin user cannot access the site anymore. I also tied to customize the template access, but the site are still visible.

Can anyone explaine me a better solution for this?

Greats

Share this post


Link to post
Share on other sites

Hi doolin, I would suggest checking this post from Soma, which "corrects" ryan's original code for the custom login.

Concerning the redirection after logging out, I am assuming that you are using the link in the admin area, right? Since the admin doesn't know about your custom login page, it can't redirect to it. You need to hook into the Session::logout function to force redirection to the right login page, for example with a module:

class CustomLogout extends WireData implements Module {
  public static function getModuleInfo() {
    return array(
      'title' => 'Custom Logout',
      'summary' => 'Redirects to a custom login page after logout',
      'singular' => true,
      'autoload' => true
    );
  }

  public function init() {
    $this->addHookAfter('Session::logout', function($event) {
      $this->session->redirect($this->pages->get('/login/')->url);
    });
  }
}

Concerning the login page itself, it should remain accessible for non-admin users, since they need to access it to login. What you could simply do is make it non-editable by non-admin users by configuring the permissions for the login template (in the Access tab). Removing it from the page tree is somewhat of a hassle...

  • Like 3

Share this post


Link to post
Share on other sites
Hi ESRCH

Thanks for the right code.

Yes i user the link in the admin area.

Where i have to put this code? I read in the Docs i can place hooks anywhere i want with the autoload method. I add the code into the default.php in the Default admin theme, but it doesn't work?

yes i see, i can set the site as non editable, but the site are still display, but i have to hide it. Is there no easy way?

greats

Share this post


Link to post
Share on other sites

While you can put hooks anywhere, the cleanest approach is usually to create a separate module for it. In this case, the code I gave you is the code for a complete module, so here's what you should do:

  • Create a CustomLogout.module file in the /site/modules directory (you can rename the file if you want, but it must have the same name as the class that it defines).
  • Paste the code from my previous post.
  • Go to Modules > Refresh. The new module should appear, and you can click on install, to install it just like any Core module.

After doing this, the redirection should work.

To hide the login page, I would suggest using CSS to hide a specific item in the PageList. You will notice when examining the HTML generated by the PageList that each page is actually a div with (among other things) a class of "PageListID1234", where 1234 is the id of the page. So if your login page's id is 1025 for example, you could create a custom.css file (in /site/templates/styles) with the rule

.PageListID1025 { display: none !important; }

You now have to include this CSS file when showing the PageList page, but only when the user is not the superuser (or any another rule based on permissions or roles). You can try using the Admin Custom Files module and checking the different options there. I must admit that I have never used it, so I can't help you much. Otherwise, you can make a module (or include it in the above module in the init function) with this hook:

$this->addHookBefore("ProcessPageList::execute", function($event) {
  if (!$this->user->isSuperUser()) // You can change the rule here
    $this->config-styles->add($this->config->urls->templates . "styles/custom.css"); // Adapt the link to the file
})

As a final note, you can indeed add hooks (the $this->addHookAfter(...) call) more or less anywhere, but the syntax will change:

  • Within a class (such as a module as defined in the code in my previous post), the hook is called on $this, e.g., $this->addHookBefore("Page::render")
  • Outside of a class (such as in a template, or the admin.php file), the hook is called on wire(), so wire()->addHookBefore("Page::render").
  • You can also call addHook on an instance of a class, like $page->addHookBefore("render").

What you tried to do by including my entire module code in the default.php file wouldn't have worked, because the autoload looks for classes in files that have the same name as the class (so the CustomLogout class must be in the CustomLogout.module or CustomLogout.php file).

Learning about hooks requires a little effort, but once you get it, it is very logical and it really opens the door to doing whatever you want with Processwire. The hook system is really well built, and most aspects of the application can be hooked into. I would suggest the following to learn about hooks (that's what I did):

  • Like 1

Share this post


Link to post
Share on other sites
ESRCH, thank you very much for your effort and the great explanation! No, Now i understood how hooks are working and for what they are.
 
Yes, CSS, thank you. I dont know why i did not think about this. Good solution.  :)
 
Ok, i created an module according to your instructions. The module are installed now. If I Logout now, it redirects me to 
 
/admin/login/logout
 
and i get a 
 

"Internal Server Error

 
The server encountered an internal error or misconfiguration and was unable to complete your request.
 
Error has been logged."
 
There are already an site called "Login" by default from processwire. So i create a new site in "/" called "logins", and customize your code. But i still get the error?
 
I created a new module for the css hook:
 
<?php
class SiteHider extends WireData implements Module {
  public static function getModuleInfo() {
    return array(
      'title' => 'SiteHider',
      'summary' => 'Hide Sites in CSS per User Roles',
      'singular' => true,
      'autoload' => true
    );
  }

  public function init() {
    $this->addHookBefore("ProcessPageList::execute", function($event) {
  if (!$this->user->isSelina())
    $this->config-styles->add($this->config->urls->templates . "css/sitehide.css");
})
  }
}

 
And get this error:
 

"Parse Error: syntax error, unexpected T_OBJECT_OPERATOR (line 15..."

I also get the same error if i combine both hooks like you sayed

 
What im doing wrong? 
I have to say i've added in the first line of both modules "<?php".

Share this post


Link to post
Share on other sites

The problem is most probably the $this->user->isSelena() function. I understand the confusion, since $this->user->isSuperuser() gives the impression that you can use any user name, but it's not the case. isSuperuser() is a built-in method of the User class (you can find it on the cheatsheet under $user / User methods). If you want to allow only a specific user with the username "selina", you would do

if (!$this->user->name === 'selina')

This should hopefully do the trick.

You should also add a semi-colon after the }) on the third line from the bottom, or you'll get another error :)

  • Like 1

Share this post


Link to post
Share on other sites

I didn't realize that your post had two parts with two different questions, sorry :rolleyes:

For the logout problem, I would need to know more about the error. There normally isn't a /login page in ProcessWire from the start, so I'm surprised that this would be an issue. At the end of th error message, you can see the message that the "Error has been logged". This means that you can find this error in /site/assets/logs/errors.txt. So try doing it again, and look at the last error in the file, it should give you some indication on how to solve the issue. If not, just post the error here, as well as the exact code from the module if you adapted it.

Share this post


Link to post
Share on other sites
It's a module:
 
/**
 * ProcessWire Login Process
 *
 * Provides Login capability for ProcessWire Admin 
 * 
 * For more details about how Process modules work, please see: 
 * /wire/core/Process.php 
 * 
 * ProcessWire 2.x 
 * Copyright (C) 2014 by Ryan Cramer 
 * Licensed under GNU/GPL v2, see LICENSE.TXT
 * 
 * http://www.processwire.com
 * http://www.ryancramer.com
 *
 */

class ProcessLogin extends Process {

protected $nameField;
protected $passField; 
protected $submitField; 
protected $form; 
protected $id; 

public static function getModuleInfo() {
return array(
'title' => 'Login',          
'summary' => 'Login to ProcessWire', 
'version' => 101, 
'permanent' => true, 
'permission' => 'page-view',
);
}
.............
 
the error Log:
 

2015-03-13 09:35:54 admin http://SITE.ch/admins/module/ Parse Error:  syntax error, unexpected T_OBJECT_OPERATOR (line 15 of /is/htdocs/wp12205379_U47G28VDDD/www/SITE/site/modules/SiteHider/SiteHider.module)

2015-03-13 09:38:36 guest http://SITE.ch/admins/login/ Error:  Using $this when not in object context (line 14 of /is/htdocs/wp12205379_U47G28VDDD/www/SITE/site/modules/CustomLogout/CustomLogout.module)

Share this post


Link to post
Share on other sites

For ProcessLogin: Did you put your custom login page under the Admin page? You should avoid doing that if you want people who have not logged in to access it so that they are able to login.

I am a bit stumped with your errors. Could you please paste the exact code from the SiteHider.module and the CustomLogout.module files? Also, which version of PHP are you using?

Share this post


Link to post
Share on other sites
No. There are already an "Login" page under /admin that i never created. My created site is here /login. I tried to move the /admin/Login site to / and get an error.

CustomLogout.module



<?php
class CustomLogout extends WireData implements Module {
public static function getModuleInfo() {
return array(
'title' => 'Custom Logout',
'summary' => 'Redirects to a custom login page after logout',
'singular' => true,
'autoload' => true
);
}

public function init() {
$this->addHookAfter('Session::logout', function($event) {
$this->session->redirect($this->pages->get('/login/')->url);
});
}
}


SiteHider.module 



<?php
class SiteHider extends WireData implements Module {
public static function getModuleInfo() {
return array(
'title' => 'SiteHider',
'summary' => 'Hide Sites in CSS per User Roles',
'singular' => true,
'autoload' => true
);
}

public function init() {
$this->addHookBefore("ProcessPageList::execute", function($event) {
if (!$this->user->name === 'selina');
$this->config-styles->add($this->config->urls->templates . "css/sitehide.css")
})
}
}

I use PHP Version 5.3.29

Share this post


Link to post
Share on other sites

Hmmm... I wonder if it's the inline function. Try this code instead for each module:

<?php
class CustomLogout extends WireData implements Module {
  public static function getModuleInfo() {
    return array(
      'title' => 'Custom Logout',
      'summary' => 'Redirects to a custom login page after logout',
      'singular' => true,
      'autoload' => true
    );
  }

  public function init() {
    $this->addHookAfter('Session::logout', $this, 'hookAfterLogout');
  }

  public function hookAfterLogout($event) {
    $this->session->redirect($this->pages->get('/login/')->url);
  }
}
<?php
class SiteHider extends WireData implements Module {
  public static function getModuleInfo() {
    return array(
      'title' => 'SiteHider',
      'summary' => 'Hide Sites in CSS per User Roles',
      'singular' => true,
      'autoload' => true
    );
  }

  public function init() {
    $this->addHookBefore("ProcessPageList::execute", $this, 'hookBeforePageListExecute');
  }

  public function hookBeforePageListExecute($event) {
    if (!$this->user->name === 'selina')
      $this->config-styles->add($this->config->urls->templates . "css/sitehide.css");
  }
}

Also, be careful with where you put the semi-colons (;). In SiteHider, you had put it just after the if, which is a problem.

  • Like 3

Share this post


Link to post
Share on other sites
Hmmm... I wonder if it's the inline function

Yep, If I remember correctly, you can't refer to "$this" in a closure. But you could use wire('session') to get the session object there.

  • Like 1

Share this post


Link to post
Share on other sites

Indeed, though after some research, they added support for $this in PHP 5.4, which is why it works on my local server (I have PHP 5.4.7).

  • Like 1

Share this post


Link to post
Share on other sites
Ok, the CustomLogout Module works fine now :)
I try to understand. The problem was, you have to define a separate function and call it. Before we try it with an event right? why that didn't work?
 
For the SiteHider i still get this error:
 
2015-03-13 21:23:02 admin http://SITE.ch/admins/module/ Parse Error: syntax error, unexpected T_OBJECT_OPERATOR (line 18 of /is/htdocs/wp12205379_U47G28VDDD/www/SITE/site/modules/SiteHider/SiteHider.module)

I'm not even can install the module, I get the error as soon i transfer the files in the /modules folder

Share this post


Link to post
Share on other sites

The problem with the CustomLogout module was that we were using an anonymous function in the hook (the function($event) {...} is an anonymous function), and according to the PHP manual (here, under Changelog), PHP version 5.3 didn't allow using $this within such anonymous functions. So we had to use the "traditional" syntax for hooks, which uses a method of the module.

The reason why the SiteHider module is called without needing to install it is probably because it wasn't uninstalled correctly the previously, so it is still in the database (if you look in the modules table in your database, you can probably find the SiteHider module). Before deleting a module from the /site/modules folder, you should always uninstall it first by clicking on its name in the modules list, selecting Uninstall and clicking Save. This will remove the module from the database.

I see that I did a typo in my code, there is a > missing: it should be $this->config->styles->add(...); Also, the line above should be

if ($this->user->name !== 'selina')

because the ! operator has a higher precedence as the === operator.

I hope that this solves the problem :)

Share this post


Link to post
Share on other sites
this is embarrassing, because i checked the code for errors but i cant see this! My "Syntax View" is not so good right now, but it gets better. Now,  I've removed the "!" from:



if (!$this->user->name === 'selina')


and now, processwire takes the selected css file! It does what it should do  :)

Very nice, thank you :)

  • Like 1

Share this post


Link to post
Share on other sites

Hey, just noticed right now that this is a swiss powered discussion :)

Have a nice weekend!

Cheers

  • Like 3

Share this post


Link to post
Share on other sites

Glad it solved your problem.

Indeed, it's a pretty Swiss thread :) Though Swiss German would be a little difficult, I'm from Geneva... German would be fine ;)

  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Anton
      Hi there,
      I'm working with Processwire 3. Before summer I had issues to load to my backend. I finally managed to connect thanks to this : 
      $admin = wire('users')->get('admin');
      $admin->setOutputFormatting(false);
      $admin->set('pass', 'yo12345ZZ')
      $admin->save('pass');
      But later, the problem evolved: when I logged in to the site, the login page redirected me to the home. I didn't find any information about it on the web.
      But recently, the redirection has changed, now it is the login page that reloads when you connect. 
      I don't know where to start to fix this. It looks like sorcery.
      Thank you for all the help you can give me.
       
    • By sambadave
      Hi everyone, here's the problem I'm trying to solve.
      I have a config area in my PW admin that is locked down for admin use. I use pages to store a bunch of settings that I'll use for my clients website. It's mostly used for visual things like colours and theming. This list could be tiny or large, depending on the sites requirements, but its great because I can store any information I want to. So the page tree could look something like this:
      ADMIN SETUP
      Home Config Aesthetics Colours Red Field: Custom Label - "Red" Field: Class name - "theme--red' Green Field: Custom Label - "Green" Field: Class name - "theme--green' Blue Field: Custom Label - "Blue" Field: Class name - "theme--blue' etc... Sizes Small Field: Custom Label - "Small" Field: Class name - "sm' Medium Field: Custom Label - "Medium" Field: Class name - "md Large Field: Custom Label - "Medium" Field: Class name - "lg" etc... Icons Target Field: Custom Label - "Hands shaking Icon" Field: Icon SVG - "[svg code]' Target Field: Custom Label - "Target icon" Field: Icon SVG - "[svg code]' Success Field: Custom Label - "Happy face icon" Field: Icon SVG - "[svg code]' etc... HOW I USE THIS
      I'm then able to set up page reference fields for colour, size and icons. I'll use these fields on particular pages so that my clients can select a particular colour, size or icon, or anything really. Currently, with the page reference field I can create a custom label for the options. So for something like colour I can label the field "Theme" and present a list of colours like "Red, "Green" and "Blue" using the custom page label label format of the colours page.
      This of course means that I can use this to do some lovely presentation on the front end of the site. With a colour selected I'll then be able to use the page reference to get the class name for that colour theme so that I can update the page's look and feel. So in my markup I'd end up with "theme--red" or "theme--green" etc.
      THE PROBLEM
      I have this all working which is great and it's really flexible for the client which they love. However, I'd love to be able to make things more visual for the client.
      Is there a way to be able to output more than just text in the page reference field? I might have a bunch of different blue colours, so instead of a list like so:
      Navy Blue Deep Blue Bright Blue Sea Blue ... it would be great to be able to output actual colour swatches, which is a lot mor visual for the client.
      Taking the icon selector, I would ideally like to show the actual svg that I've stored against that icon as a selectable image instead of seeing text options like:
      Hands shaking icon Target icon Happy face icon Just a couple of scenarios here, but as you can see there could be any number of reasons to display a more visual method of selection.
      ANY SOLUTIONS?
      I've looked at modules like FieldtypeColorPicker which could help in solving the colour issue, but it doesn't allow me to select a colour and then use a particular class name assigned to it the way I describe above.
      Considering the other use cases I mention above, does anyone know if anything exists already that would help me to create custom presentaion for page reference lists, or if there's anything planned?
      Thank you in advance for anyone who's read this far and has any words of wisdom!
      Dave
       
    • By angelo, italy
      Hi guys,
      I've always used WP but I want to swtich to PW. I'm not sure ....
      I'd like to know if it's possible to create a website for an online photo contest.
      The participants of the competition could create their own account, in which they upload their photos. The photos uploaded remain visible only to themselves and the judges.
      From their account they can make the "entrance fee" payment.
      The judges of the competition can create their own account... entering they see the photos of the participants and vote photos
      At the main page I imagine the title of the competition, a button to read the regulation, and a button to register.
      The website should be in Italian and English.
      Thank you!!
       
       
    • By Peter Knight
      I have a demo site which I moved to a new VPS for client testing
      We noticed that leaving a page open and then revisiting the site can result in a 25 second(ish) to load time and will then throw a 500 Error.
      The hosting guys had a look and confirmed that the server is fine but the issue could be related to authentication or sessions.
      We are running Page Protector and ProCache so I wondered if there were any known bugs here and any recommended actions.
      My actual PW log doesn't show anything but the server log has plenty of these
       
      2018-12-06 08:14:00 Error xxx.141.1x.101 500 POST /who-we-are/ HTTP/1.0     1.58 K Apache access 2018-12-06 08:14:45 Warning xxx.141.1x.131   mod_fcgid: read data timeout in 45 seconds, referer: http://demo.abc.not/who-we-are/       Apache error 2018-12-06 08:14:45 Error xxx.141.1x.131   End of script output before headers: index.php, referer: http://demo.abc.not/who-we-are/       Apache error 2018-12-06 09:03:18 Error xxx.141.1x.131   2614#0: *667 recv() failed (104: Connection reset by peer) while reading response header from upstream       nginx error Thanks
      P
    • By Marcel
      Hey all,
      I want to customize the mywebsite/processwire/profile page. It's almost all good but I want to get rid of the sections 'Admin Theme' and 'Language' so that the user can just set a new password. (see image)
      Do I have to modify the admin template or how can I do that? Because when I go tree>Admin>Profile there are no fields to add or remove.
      Or where can I find the php file?
      I would appreciate your help.

×
×
  • Create New...