Jump to content

FrontendUser: login, logout and register users / members

Recommended Posts

In documentation I used $redirectDestination, which isn't optional ;)

I'll add it to the wiki page.

Thank you a lot. I think it would be enough to mention this in your documentation. I was really confused about the endless loop redirects.

And is there any ability to send mails? Because I have the problem that any redirect is looses the data from posting the form. It would be helpful to send the admin an email that a new user is registered.

Just write a small extension (a PW hook) to send an email? Could be done inside the template file or a small PW module.

Share this post

Link to post
Share on other sites

Hint about redirect loops is added to the wiki documentation.

@Florian Grüttner

FrontendUser is build with flexibility and PW core features in mind. So you can add an hook to send an email after successfully registered a new user.

Use addHookAfter FrontendUser save() method. User registration was successful if you return value is "true" (exactly "true" checked with "==="). You can use WireMail to send an email with the form data.

Edited by pwFoo

Share this post

Link to post
Share on other sites


I'm trying to override the "Send email validation code" value of the UserRegistration submit button, I need it to be translatable.

Since I don't want to hack the module (line 157 of  FrontendUserRegisterEmailValidation.module) by putting a _('Send email validation code'), I tried to set the custom value with a

        $form = wire('fu')->form;
        if (!wire('session')->get('registerStep')) {
            $form->fhSubmitBtn->value = __('My custom text',$langfile);

but to no avail -- it seems that the module's hook function ( hookRegisterFormBeforeRender ), which also will hook into before render, always trumps "my" value.

What am I missing?



  • Like 1

Share this post

Link to post
Share on other sites

ok, found it (with the support of @inspeCTor) :-)

        if (!wire('session')->get('registerStep')) {
            $event->object->fhSubmitBtn->value = __('Send validation code',$langfile);

Share this post

Link to post
Share on other sites

Hi again,

I think we found a bug regarding the emailValidation E-mail: The email contains some markup residue which is pulled from the _main.php file (for example some google analytics script code), even if sent as text email. If the vars for the render() func contain

$vars['prependFile'] = null;
$vars['appendFile'] = null;
$vars['allowCache'] = false;

this is gone.

Is there a way to insert this via hook, or only in FrontendUserRegisterEmailValidation.module, line 97ff…?

// Set email template variables
            $vars = array(
                'username'  => wire('session')->get('registerUsername'),
                'email'     => wire('session')->get('registerEmail'),
                'token'     => wire('session')->get('registerToken'),
                'url'       => wire('page')->httpUrl . '?registerToken=' . wire('session')->get('registerToken'),
                'content'   => $this->content,  // config variable  // ToDo: Tests with php 5.3
                // no markup from page template:
                'prependFile' => null,
                'appendFile' => null
                // ---- //
            // Load the plain / html email templates
            $emailContentHtml = wire('page')->render(wire('fu')->getFile('validationEmail.php', 'templates'), $vars);
            // Send verification email with the generated token
            $mail = wireMail();
            if ((int)$this->emailType == 1) {
            else {
                $emailContentPlain = preg_replace('/^\h+|\h+$/m', '', strip_tags($emailContentHtml));
  • Like 1

Share this post

Link to post
Share on other sites


  • \h+ matches any horizontal whitespace character (equal to [[:blank:]])
    • Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]

You can test it at https://regex101.com/

  • Like 1

Share this post

Link to post
Share on other sites


Thanks for reporting. I'll release an updated version soon...

  • Like 1

Share this post

Link to post
Share on other sites


Thank you, didn't know about that special char, and my google skills need some improvement, it seems :)


Cool, thanks. Perhaps this could be triggered via a settings option? I guess 'our' problem is caused because we have all the 'surrounding' markup in the _main.php, other structural designs may not be bothered by this. On the other hand, in your demo mail template the complete 'surrounding' markup is contained, so no need for inheritance from the page/main template. hm. on the other hand, what if you need to access some vars or funcs from _init.php or _func.php … guess what i'm trying to say: as so often with processwire: it depends ;)



Share this post

Link to post
Share on other sites

Share this post

Link to post
Share on other sites

Hi pwFoo,

sorry for the late reply; it seems to work as intended in our install, thank you :-)

(one minor thing, tho, the FrontendUserRegisterEmailValidation module is not updatable from the backend, it still claims to be 6 months old, even with the fresh 13.11.15 version on the server…)



Share this post

Link to post
Share on other sites

Thanks for Testing :)

FrontendUserRegisterEmailValidation isn't an independent module and packaged with the main module (same git repo and PW module).

Share this post

Link to post
Share on other sites

I am just getting started on this - building a forum site where users can register an account, have a profile page and then expand from there...

Could someone give a summary of this thread. How far along is this module?

FrontendUser is listed as alpha/not stable, but does the basic process work? Is it good enough to get started?

Is a stable version 1.0 coming any day now or is this an abandoned experiment?

Would I be better off trying to develop something very rudimentary from scratch?

Share this post

Link to post
Share on other sites

Hi, the module is listed as unstable because I don't use it with a production site at the moment and there isn't that much feedback about production usage yet, but I think some members here are using it. Reported issues should be fixed.

The module IS designed as a starting point and easy to extend by writing plugins (based on PW hooks) without hacking the module itself. ;)


You plan to build a PW based forum?


  • Like 1

Share this post

Link to post
Share on other sites

I'm using it in a low-traffic site since summer 2015 and no reports of problems so far from users.

  • Like 2

Share this post

Link to post
Share on other sites

Thank you for your quick response pwFoo. And Beluga.

I have forum websites based on heavily customized Wordpress Multisite now, but it is a structural mess - http://geowebforum.com etc.

In Wordpress Multisite each new site is completely independent/disconnected from the others. Buddypress works around that by adding a second users database table. I tried a different approach to minimize the number of plugins and keep everyhing as standard as possible, but Wordpress still makes it hard to manage as one platform.

I don't want a classic old skool forum/BB, like this support forum. It should be more like a social network; users have their own profile pages where they can post content in their own channel/newsfeed and then can comment on eachothers content.

Whatever the features are going to be, I need a solid, straightforward users/members management system to get started. I'll try your module and will report back here.

Thanks again!

Share this post

Link to post
Share on other sites

Maybe EsoTalk and particularly its successor Flarum could be inspiration.

I started such a basic discuss module (just some code for testing, nothing which could be used yet) but stopped it because of lack of time. 

  • Like 1

Share this post

Link to post
Share on other sites

EsoTalk and Flarum look like old-fashioned bulletin boards to me. I want something much more content focused; member profile pages as content channels and then collect some platform activity on a general homepage.

I like the straightforward way PW handles content. If PW can handle users/members  in a similar straightforward way, that would be a great starting point. I don't want to use yet another php script that only does one thing.

Share this post

Link to post
Share on other sites

I tested FrontendUser module with PW 3.0 dev and it seems to works fine, but minimal changes to FormHelper are needed because of namespace compatibility...

The FrontendUserRegisterEmailValidation plugin send an empty mail body and a update is needed to make it work with PW 3.0!

Maybe I'll optimize my modules for the PW3.0dev usage soon.

FormHelper PW 3.0 dev compatibility:


Share this post

Link to post
Share on other sites


I have have added an extra field for registration as per your instructions in Code snippets, however the field data is missing after registration is completed.

I have updated the relevant template in admin so that "firstname" is now a user field, and this is working fine.

My code is all working ok but the "firstname" field remains empty upon registration. I can only manually update it through admin.

ProcessWire 2.7.1

FrontendUser 0.8.9

My code is posted below.

$fu = $modules->get('FrontendUser');
$FirstName = $modules->get('InputfieldText');
$FirstName->label = $this->_('First Name');
$FirstName->attr('id+name', 'firstname');
//$FirstName->required = 1;
$FirstName->fhSanitizer = 'text';

// Call hook after field is processed by PW form api
$FirstName->addHookAfter('processInput', function($event) {
   $field = $event->object;

   // Value will be sanitized as text with "$sanitizer->text()"
   $mySanitizedCustomInput = wire('fu')->form->fhValue($field->name);

   // Do ...

   // Example: Add value to user during registration
   wire('fu')->userObj->myField = $mySanitizedCustomInput;

   // Need to set an field error?
   // $field->error('Custom field has an error...');

// Define the field before you call FU and add it as additional field...
$fu->register(array('username', 'email', 'password', $FirstName));

echo $fu->render();

Share this post

Link to post
Share on other sites

Hello everyone,

there is an option in the frontend of the site to create a new user and then to login for downloading the content.

I have the following problem:

In the PW-backend I can create a new user with access restrictions. When this user has admin rights, he can login in the PW-backend, and when he is loginned in the PW-backend I can see in the frontend the files to download and can logout. But when this user is not logined in the PW-backend he can’t login directly from the frontend. I can’t also create a new user from the frontend. When I'm trying to login or to create a new user in the frontend, I'm redirected to the homepage.

What can cause this problem? I took the code from the same project I made earlier.

<?php // process register / form submit ?>
		<?php $downloads = $pages->get(1062)->url; ?>
		<?php $erfolg = $pages->get(1224)->url; ?>
		<?php echo $erfolg; ?>
		<?php $my_downloads = $pages->find("template=download-detail, include=all"); ?>
		<?php $logout = $pages->get(1363)->url; ?>

		<div class="register">
			<div class="col col-xs-10 col-xs-offset-1 col-sm-10 col-sm-offset-1 download">

				<?php if($user->isLoggedin()): ?>
					<div class="col col-xs-12 col-sm-10">
						<?php echo "<h3 class='primary headline3 download-text'>Sie sind eingeloggt als '".$user->name."'.</h3>"; ?>
					</div><!-- col -->
				<?php else: ?>
                <div class="col col-xs-12 col-sm-6">
					<div class="col col-xs-12 col-sm-10">
						<h3 class="primary headline3 register-text">Registrierung</h3>
					<!-- col -->
					<?php $fu_r = $modules->get('FrontendUser'); ?>
					<?php $fu_r->register(); ?>
					<?php $fu_r->process($erfolg); ?>

					<?php echo $fu_r->render(); ?>
                <div class="col col-xs-12 col-sm-6">
                    <div class="col col-xs-12 col-sm-10">
                    <h3 class="primary headline3 register-text">Login</h3>
						<?php $fu_l = $modules->get('FrontendUser'); ?>
						<?php $fu_l->login(); ?>
						<?php $fu_l->login(array('username', 'password')); ?>
						<?php //// Additional LoginPersist and ProcessForgotPassword module integration (built-in) ?>
						<?php //$fu->login(array('username', 'password', 'persist', 'forgot')); ?>
						<?php //// process login / form submit ?>
						<?php  ?>
						<?php $fu_l->process($downloads); ?>
						<?php //// output form ?>
						<?php echo $fu_l->render();?>

				<?php endif; ?>
			</div><!-- col -->

			<?php if($user->isLoggedin()): ?>
			<div class="download-list">
				<div class="col col-xs-10 col-xs-offset-1 col-sm-10 col-sm-offset-1">
					<div class="col col-xs-12 col-sm-5 col-sm-offset-0 main-text">
							<?php $user_pages = $user->download_selector; ?>
							<?php if($user_pages[0]): ?>
								<p class="secondary copy">Ihre verfügbaren Downloads:</p>
							<?php else: ?>
								<p class="secondary copy">Für Sie sind derzeit keine Downloads verfügbar.</p>
							<?php endif; ?>
								<ul class="download-text">
									<?php foreach($user_pages as $user_page): ?>
										<li><a class="secondary copy" download="download" target="_blank" href="<?php echo $user_page->download_file->url; ?>" title="<?php echo $user_page->title; ?>"><?php echo $user_page->title; ?></a></li>
							<?php endforeach; ?>
							<?php if($user->isLoggedin()): ?>
								<div class="col col-xs-12">
									<a class="primary headline3 cta icon-open icon-close download-text" href="<?php echo $logout; ?>">Logout</a>
								</div><!-- col -->
							<?php endif; ?>

					<!-- col -->
			</div><!-- download list -->
			<?php endif; ?>

Maybe its a simple task but I am not sure where to look for the problem.

Thanks for your help - I really appreciate all that kind support here in the forum!



Share this post

Link to post
Share on other sites

I have found where the problem is and realized my mistake.

we had the base-tag with the URL where the site is situated.

without this tag has the module the full functionality on the site. 

Everything is working now. 

Share this post

Link to post
Share on other sites


i have some problems with the Forgot password function ? 

I have both calls for login and register on one page 


now i if try to restore the password i see the url   two times the reset field 


so if i use one of them i get the mail but on click on the link



nothinh happens ? I see also this two fields and jump also to


how to not render the register for the page if user try to reset password  ? 


Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By d'Hinnisdaël
      Happy new year, everybody 🥬
      I've been sitting on this Dashboard module I made for a client and finally came around to cleaning it up and releasing it to the wider public. This is how it looks.
      ProcessWire Dashboard

      If anyone is interested in trying this out, please go ahead! I'd love to get some feedback on it. If this proves useful and survives some real-world testing, I'll add this to the module directory.
      You can find the latest release on Github.
      Check out the documentation to get started. This is where you'll find information about included panel types and configuration options.
      Custom Panels
      My goal was to make it really simple to create custom panels. The easiest way to do that is to use the panel type template and have it render a file in your templates folder. This might be enough for 80% of all use cases. For anything more complex (FormBuilder submissions? Comments? Live chat?), you can add new panel types by creating modules that extend the DashboardPanel base class. Check out the documentation on custom panels or take a look at the HelloWorld panel to get started. I'm happy to merge any user-created modules into the main repo if they might be useful to more than a few people.
      This is a pre-release version. Please treat it as such — don't install it on production sites. Just making sure 🍇
      These are the things I'm looking to implement myself at some point. The wishlist is a lot longer, but those are the 80/20 items that I probably won't regret spending time on.
      Improve documentation & add examples ⚙️ Panel types Google Analytics ⚙️ Add new page  🔥 Drafts 🔥 At a glance / Page counter 404s  Layout options Render multiple tabs per panel panel groups with heading and spacing between ✅ panel wrappers as grid item (e.g. stacked notices) ✅ Admin themes support AdminThemeReno and AdminThemeDefault ✅ Shortcuts panel add a table layout with icon, title & summary ✅ Chart panel add default styles for common chart types ✅ load chart data from JS file (currently passed as PHP array) Collection panel support image columns ✅ add buttons: view all & add new ✅
    • By Pip
      Hi everyone!
      I'm trying out the Login/Register module for my site. Noted that the module assigns the newly registered user to login-register role. 
      Once you modify the login-register role's permissions, particularly adding page-edit, the new member role will be set to guest. 
      Thing is I'd like to grant my new users the power to create their own pages. Any advice? 
    • By Gadgetto
      SnipWire - Snipcart integration for ProcessWire
      Snipcart is a powerful 3rd party, developer-first HTML/JavaScript shopping cart platform. SnipWire is the missing link between Snipcart and the content management framework ProcessWire.
      With SnipWire, you can quickly turn any ProcessWire site into a Snipcart online shop. The SnipWire plugin helps you to get your store up and running in no time. Detailed knowledge of the Snipcart system is not required.
      SnipWire is free and open source licensed under Mozilla Public License 2.0! A lot of work and effort has gone into development. It would be nice if you could donate an amount to support further development:

      Status update links (inside this thread) for SnipWire development
      2020-07-03 -- SnipWire 0.8.7 (beta) released! Fixes some small bugs and adds an indicator for TEST mode 2020-04-06 -- SnipWire 0.8.6 (beta) released! Adds support for Snipcart subscriptions and also fixes some problems 2020-03-21 -- SnipWire 0.8.5 (beta) released! Improves SnipWires webhooks interface and provides some other fixes and additions 2020-03-03 -- SnipWire 0.8.4 (beta) released! Improves compatibility for Windows based Systems. 2020-03-01 -- SnipWire 0.8.3 (beta) released! The installation and uninstallation process has been heavily revised. 2020-02-08 -- SnipWire 0.8.2 (beta) released! Added a feature to change the cart and catalogue currency by GET, POST or SESSION param 2020-02-03 -- SnipWire 0.8.1 (beta) released! All custom classes moved into their own namespaces. 2020-02-01 -- SnipWire is now available via ProcessWire's module directory! 2020-01-30 -- SnipWire 0.8.0 (beta) first public release! (module just submitted to the PW modules directory) 2020-01-28 -- added Custom Order Fields feature (first SnipWire release version is near!) 2020-01-21 -- Snipcart v3 - when will the new cart system be implemented? 2020-01-19 -- integrated taxes provider finished (+ very flexible shipping taxes handling) 2020-01-14 -- new date range picker, discount editor, order notifiactions, order statuses, and more ... 2019-11-15 -- orders filter, order details, download + resend invoices, refunds 2019-10-18 -- list filters, REST API improvements, new docs platform, and more ... 2019-08-08 -- dashboard interface, currency selector, managing Orders, Customers and Products, Added a WireTabs, refinded caching behavior 2019-06-15 -- taxes provider, shop templates update, multiCURL implementation, and more ... 2019-06-02 -- FieldtypeSnipWireTaxSelector 2019-05-25 -- SnipWire will be free and open source Plugin Key Features
      Fast and simple store setup Full integration of the Snipcart dashboard into the ProcessWire backend (no need to leave the ProcessWire admin area) Browse and manage orders, customers, discounts, abandoned carts, and more Multi currency support Custom order and cart fields Process refunds and send customer notifications from within the ProcessWire backend Process Abandoned Carts + sending messages to customers from within the ProcessWire backend Complete Snipcart webhooks integration (all events are hookable via ProcessWire hooks) Integrated taxes provider (which is more flexible then Snipcart own provider) Useful Links
      SnipWire in PW modules directory SnipWire Docs (please note that the documentation is a work in progress) SnipWire @GitHub (feature requests and suggestions for improvement are welcome - I also accept pull requests) Snipcart Website  

      ---- INITIAL POST FROM 2019-05-25 ----
    • By Sten
      Till now I hacked something with the twig template but it works no more with new PW versions so I look forward to create a module. I am working on a site in multiple languages : French, English, Italian, German, Spanish, Portuguese, Hebrew, Russian. The new posts are entered in any language with a field for language. Till now, I got twig files to get the translations with constants defined for each part of the pages.
      So I'd like to create a module to include theses files added according to the url /fr/en/...
      Have you some observations to do before I begin about the direction to take ?
      Thank you
    • By ukyo
      Mystique Module for ProcessWire CMS/CMF
      Github repo : https://github.com/trk/Mystique
      Mystique module allow you to create dynamic fields and store dynamic fields data on database by using a config file.
      ProcessWire 3.0 or newer PHP 7.0 or newer FieldtypeMystique InputfieldMystique Installation
      Install the module from the modules directory:
      Via Composer:
      composer require trk/mystique Via git clone:
      cd your-processwire-project-folder/ cd site/modules/ git clone https://github.com/trk/Mystique.git Module in live reaction with your Mystique config file
      This mean if you remove a field from your config file, field will be removed from edit screen. As you see on youtube video.
      Using Mystique with your module or use different configs path, autoload need to be true for modules
      Default configs path is site/templates/configs/, and your config file name need to start with Mystique. and need to end with .php extension.
      Adding custom path not supporting anymore !
      // Add your custom path inside your module class`init` function, didn't tested outside public function init() { $path = __DIR__ . DIRECTORY_SEPARATOR . 'configs' . DIRECTORY_SEPARATOR; Mystique::add($path); } Mystique module will search site/modules/**/configs/Mystique.*.php and site/templates/Mystique.*.php paths for Mystique config files.
      All config files need to return a PHP ARRAY like examples.
      Usage almost same with ProcessWire Inputfield Api, only difference is set and showIf usage like on example.
      <?php namespace ProcessWire; /** * Resource : testing-mystique */ return [ 'title' => __('Testing Mystique'), 'fields' => [ 'text_field' => [ 'label' => __('You can use short named types'), 'description' => __('In file showIf working like example'), 'notes' => __('Also you can use $input->set() method'), 'type' => 'text', 'showIf' => [ 'another_text' => "=''" ], 'set' => [ 'showCount' => InputfieldText::showCountChars, 'maxlength' => 255 ], 'attr' => [ 'attr-foo' => 'bar', 'attr-bar' => 'foo' ] ], 'another_text' => [ 'label' => __('Another text field (default type is text)') ] ] ]; Example:
      site/templates/configs/Mystique.seo-fields.php <?php namespace ProcessWire; /** * Resource : seo-fields */ return [ 'title' => __('Seo fields'), 'fields' => [ 'window_title' => [ 'label' => __('Window title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'attr' => [ 'placeholder' => __('Enter a window title') ] ], 'navigation_title' => [ 'label' => __('Navigation title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'showIf' => [ 'window_title' => "!=''" ], 'attr' => [ 'placeholder' => __('Enter a navigation title') ] ], 'description' => [ 'label' => __('Description for search engines'), 'type' => Mystique::TEXTAREA, 'useLanguages' => true ], 'page_tpye' => [ 'label' => __('Type'), 'type' => Mystique::SELECT, 'options' => [ 'basic' => __('Basic page'), 'gallery' => __('Gallery'), 'blog' => __('Blog') ] ], 'show_on_nav' => [ 'label' => __('Display this page on navigation'), 'type' => Mystique::CHECKBOX ] ] ]; Searching data on Mystique field is limited. Because, Mystique saving data to database in json format. When you make search for Mystique field, operator not important. Operator will be changed with %= operator.
      Search example
      $navigationPages = pages()->find('my_mystique_field.show_on_nav=1'); $navigationPages = pages()->find('my_mystique_field.page_tpye=gallery');
  • Create New...