Jump to content
iipa

Using $session to save UI changes on site

Recommended Posts

Hello forum!

I have a site, where I want to remember two settings defined by user:

1) Theme (light or dark)
2) Language (Finnish or English)

Because user makes changes to these settings on client side, I am a bit lost with how can I save them in ProcessWire $session variable? I would like to use $session for more reliable saving, and since it is only two variables I will use, I doubt it will become too resource-needy.

I have tried using jQuery's post() -method referring to a file in Templates folder (theme.php), but I get 403 Forbidden Error. I don't like the idea of trying to post to same file user currently is in, which is why I thought having a separate file would be good in this.

Contents of theme.php:

<?php
	namespace ProcessWire;
	header('Access-Control-Allow-Origin: https://domain.com');
	$theme = $input->post['theme'];
	if(!empty($theme)) $session->theme = $theme;
?>

Long story short: Does anybody have any pro tips I could use with setting and getting $session variables?

Share this post


Link to post
Share on other sites

I build and use one template that is bound to a single page in PW where both are simply named "ajax". I can access it per URL "/ajax/" and use it for everything that needs to send or retrieve data in the background. Here is an example from a project where different forms send data that need to be validated first and then send to final (external) destinations. The client browser optionally gets back HTML like "success messages" or error descriptions.

<?php namespace ProcessWire;
/*==============================================================================
    XXXXXXXXXX :: site/templates/ajax.php
    2019-07-04
==============================================================================*/


/*******************************************************************************
*
*   This template file handles form submissions that are raised via AJAX!
*
*   Sanitize, validate, log and submit to final destinations.
*
*
    // how the used JS looks like
        $.ajax({
            url      : gAjaxUrl,                // /ajax/
            type     : 'POST',
            async    : true,
            dataType : 'html',                  // returned data has to be HTML
            data     : submitData,              // submitted data object
            success  : function(markup) {
                if('' != selector) {            // a selector string to match the
                    $(selector).html(markup);   // markup container
                }
            }
        });
        
    ...
*
*******************************************************************************/

// only process AJAX calls
if(!$config->ajax) return 'WRONG ACCESS METHOD';

// only process POST requests with valid required id
if(!$input->post->hidden_id) return 'WRONG ACCESS METHOD';

// ... followed by all project specific validations etc.

 

So, with your example I would check if there is a post value named theme, and if the value is one out of a whitelist of valid theme values:

// does this belong to theme selection
if($input->post->theme) {
	$validThemeValues = ['dark', 'light'];
	if(!in_array($input->post->text('theme'), $validThemeValues)) {
		header('HTTP/1.1 403 Forbidden');
		return;
	}
	$session->set('selectedTheme', $input->post->text('theme'));
	return;
}

// does this belong to another thing?
if($input->post->anotherThing) {

	// first validate, then process data
	// ...
	return;
}

 

  • Like 8

Share this post


Link to post
Share on other sites
2 hours ago, iipa said:

two settings defined by user:

1) Theme (light or dark)
2) Language (Finnish or English)

I would prefer cookies instead of sessions for such user-choices. Sessions expire when you close your browser, but cookies will still be remembered after x days (= the lifespan you define). You can set cookies with JS alone, so you don't even need a server / PHP for that. 

  • Like 8
  • Thanks 1

Share this post


Link to post
Share on other sites
17 hours ago, dragan said:

I would prefer cookies instead of sessions for such user-choices. Sessions expire when you close your browser, but cookies will still be remembered after x days (= the lifespan you define). You can set cookies with JS alone, so you don't even need a server / PHP for that. 

Somehow I didn't consider this option at all! Thanks @dragan, I decided to implement this with cookies 🙂

18 hours ago, horst said:

I build and use one template that is bound to a single page in PW where both are simply named "ajax". I can access it per URL "/ajax/" and use it for everything that needs to send or retrieve data in the background. Here is an example from a project where different forms send data that need to be validated first and then send to final (external) destinations. The client browser optionally gets back HTML like "success messages" or error descriptions.

And thanks to you too @horst, I'm sure this will come handy at some point!

  • Like 2

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 dimitrios
      Hello,
      this module can publish content of a Processwire page on a Facebook page, triggered by saving the Processwire page.
      To set it up, configure the module with a Facebook app ID, secret and a Page ID. Following is additional configuration on Facebook for developers:
      Minimum Required Facebook App configuration:
      on Settings -> Basics, provide the App Domains, provide the Site URL, on Settings -> Advanced, set the API version (has been tested up to v3.3), add Product: Facebook Login, on Facebook Login -> Settings, set Client OAuth Login: Yes, set Web OAuth Login: Yes, set Enforce HTTPS: Yes, add "http://www.example.com/processwire/page/" to field Valid OAuth Redirect URIs. This module is configurable as follows:
      Templates: posts can take place only for pages with the defined templates. On/Off switch: specify a checkbox field that will not allow the post if checked. Specify a message and/or an image for the post.
      Usage
      edit the desired PW page and save; it will post right after the initial Facebook log in and permission granting. After that, an access token is kept.
       
      Download
      PW module directory: http://modules.processwire.com/modules/auto-fb-post/ Github: https://github.com/kastrind/AutoFbPost   Note: Facebook SDK for PHP is utilized.


    • By pwFoo
      With JS fetch() it is a bit tricky to get for example $_POST populated (params need to be FormData / forms), but would it possible to get PW $input (get, post, urlSegments, queryString) working for fetch requests?
      Is there a fix / hook / workaround to solve it PW side?
    • By hansv
      Hi everybody
      I want to catch a variable from outside processwire into _main.php
      if(isset($_GET['u']) && $_GET['u'] !== ''){ $gebruikersnaam = $_GET['u']; ... ... This is working fine in a php file in a non processwire environment. 
      In a processwire environment, I get the variable when I refer to /site/templates/_main.php but a great part of my template-code is not shown. 
      From outside processwire I refer to    mydomain/index.php.  If I place   $gebruikersnaam = $_GET['u'];  in index.php, how can I pass through my variable to _main.php?   Or is there an other solution?
      thx
      hansv
    • By rareyush
      I am using this function to get blogpost but I don't see what's wrong in it and why it is now showing anything in frontend.
       
      function ukBlogPost(Page $page, $options = array()) { $defaults = array( 'summarize' => null, // Display blog post summary rather than full post? (null=auto-detect) 'metaIcon' => 'info', 'moreIcon' => 'arrow-right', 'moreText' => __('Read more'), 'categoryIcon' => 'hashtag', 'bylineText' => __('Posted by %1$s on %2$s'), ); $options = _ukMergeOptions($defaults, $options); $title = $page->title; $img = $page->images->first(); $date = $page->date ? $page->date : $page->createdStr; $name = $page->createdUser->name; $body = summarizeText($page->get('body'), 100); $metaIcon = ukIcon($options['metaIcon']); $moreIcon = ukIcon($options['moreIcon']); $categoryIcon = ukIcon($options['categoryIcon']); $n = $page->comments->count(); $numComments = $n ? "<a href='$page->url#comments'>" . ukIcon('comments') . " $n</a>" : ""; $itn = $page->get('itineraries'); $ito = $itn->each( "<h4> {itineraries_title}</h4> <p>{itineraries_details} </p> "); if($options['summarize'] === null) { // auto-detect: summarize if current page is not the same as the blog post $options['summarize'] = page()->id != $page->id; } /* $categories = $page->categories->each($categoryIcon . "<a class='uk-button uk-button-text' href='{url}'>{title}</a> " );*/ if($options['summarize']) { // link to post in title, and use just the first paragraph in teaser mode $title = "<a href='$page->url'>$title</a>"; $body = explode('</p>', $body); $body = reset($body) . ' '; $body .= "<a href='$page->url'>$options[moreText] $moreIcon</a></p>"; $class = 'blog-post-summary'; } else { $class = 'blog-post-full'; } if($options['summarize']) { $heading = "<h4 class='uk-margin-remove tour-heading'>$title</h4>"; } else { $heading = "<h3 class='uk-article-title uk-margin-remove tour-heading'>$title</h3>"; } $byline = sprintf($options['bylineText'], $name, $date); if($img) { $img = $img->size(375,380); } // return the blog post article markup return " <div> <div class='uk-card'> <div class='uk-inline-clip uk-transition-toggle'> <img src='$img->url' alt='$img->description' class='uk-border-rounded uk-transition-scale-up uk-transition-opaque' > <div class='uk-overlay uk-light uk-position-bottom'> <p class='uk-text-light'>$heading</p> </div> </div> $ito </div> </div> "; }  
       
      I tried running $title, $img etc. - or are they all blank? simultaneously but nothing returns anything.
       
      I do not know why it is not working 
    • By albertax
      Hi All, I am wondering if you could provide input on the best way an item as a user favorite.
      I am setting up a price comaprison website, and have most of the logic done for the site. Search results, listing page, login/logout, search, etc. It's all looking pretty good. However someone has suggested to me that users might like to save an item as a favorite.
      So my idea behind that was to have a button on each of the grid items in the search results page. 
      This is my search results page code with the button within the item.
      <form id="add_fav" name="add_fav" autocomplete="off" accept-charset="utf-8" action="./" method="post"> <button class="wish_btn" name="add_fav">Add Fav</button> </form> Where the business logic is on the page, this is what I have so far - I just don't know how to align an item to a user.
      $log->save ('pageview', 'testing'); function clense_input($data){             $data = trim($data);             $data = stripslashes($data);             $data = htmlspecialchars($data);             return $data;         }                 $sort = "title";         // Logic for favorites         if ($_SERVER["REQUEST_METHOD"] == "POST") {           if (isset($_POST['add_fav'])) {             $favs = $sanitizer->text($_POST['add_fav']);             if(!empty($favs)){               $ticket = $pages->get($favs); // Set page name               if($favs != null){                 $favs->of(false);                 $favs->fav_title = $page->user->name; // Save username                 $favs->fav_title = $page->title->id; // Save page id to favs list                 $favs->save();                 echo "Fav saved.";               }             }           }       }  
×
×
  • Create New...