Jump to content

dynamic layout included


bwakad
 Share

Recommended Posts

It's maybe offtopic, but anyway... I was looking for a way to have 2 buttons. Idea is to dynamically include layouts based on those buttons clicked. - one for GRID layout - one for LIST layout - I need a php variable for this... Jquery and ajax allow to change DOM elements as in HTML. But PHP get parsed as HTML so no dynamic php variable would be changed since the page is already processed.

Developers at google are very strict on different views (layout) and url segments, because it lead to same content...

For now I think there are 3 ways to do this:

1 - a href links - problem: url is attached to end, and on every page load, or field selector, the $layout variable is reset.

2 - url segments - problem: url is attached to end, and on every page load, or field selector, the $layout variable is reset.

3 - form with post - problem: on page refresh, the form get's re-send which I do not want.

Then again, maybe this would suit better in a cookie... but I really have no idea as how to do that.

code what I have now:

// menu
<form action='./' method='post' id='layout' novalidate>
      <div class='small-2 columns'>
      <button type='submit' name='submit_list' value='list' id='list' class='button tiny right'>List</button>
      </div>
      <div class='small-2 columns'>
      <button type='submit' name='submit_grid' value='grid' id='grid' class='button tiny right'>Grid</button>
      </div>
</form>

// before header is included
$layout = "./inc/grid.inc";

if($input->post->submit_list) {
$layout = "./inc/list.inc";
}
if($input->post->submit_grid) {
$layout = "./inc/grid.inc";
}
Link to comment
Share on other sites

I would store the selection in a $session variable and switch content with ajax.

Schema:

first view:

- no session present

- render standard view (grid)

Click on list view button:

- get list part per ajax

- replace content with that

- store selection in $session

Next page:

- selection is present in $session

- render list view

until $session ends or grid is selected again.

Depending on layout you also could render the same html and change the view per switching a html class (body or so) and remember that class in $session for next render.

Link to comment
Share on other sites

I can't really find info on how to work with sessions in PW...

http://processwire.com/api/variables/session/

Another simpler option is to use a tabbed interface approach where both views are loaded, but one is hidden, like this: http://jqueryui.com/tabs/

If you are using a css framework, they usually have something built in for this. Keep in mind that this might not be a good idea depending on the size/complexity of the content being rendered in the grid.

Here is an example of how to load tabs using ajax, which would avoid the above mentioned issue: http://stackoverflow.com/questions/14361211/jquery-tabs-use-url-to-load-ajax-content

Link to comment
Share on other sites

This I read. But what I mean is: how to attach a session to my variable using a button / link.

And then this:

Using a link I do not need a a form, but my url get's assigned either a # or #something or /page/ ...

Using a form I don't have this in the url, BUT after the submit, when refresh the page, the form get submitted again (message poppup)...

- edit - I could of course make a link go to the same page !!! - end edit -

The only thing I found (almost the same as what I had) was this  :

// before anything is outputted
if($input->post->layout) {
  // set the layout
  $session->layout = $sanitizer->pageName($input->post->layout);
}

// where the buttons/links are
if($session->layout == 'grid') {
  $layout = './inc/grid.inc';
} else if($session->layout == 'list') {
  $layout = '.inc/list.inc';
} else {
   // should there not be a session here as well?
  $layout = './inc/grid.inc';
}

Link to comment
Share on other sites

No need for a form.

<div class='myViews'>
    <a class='button switchLayout' href='#' data-view='list'>List view</a>
    <a class='button switchLayout' href='#' data-view='grid'>Grid view</a>
</div>

jQuery:

$('myViews').on('click','.switchLayout',function(e){
   e.preventDefault();
   var whichView = $(this).attr('data-view');
   $.get( document.URL, { layout: whichView }).done(function( data ) {
       $( ".myView" ).html( $(data).filter('.myView').html());
   });
})

in your template:

...
$layout = $sanitizer->text($input->layout); // is there a get variable from ajax?
if($layout){
    $session->layout = $layout;
} else     // or something in session?
{
   if($session->layout){
        $layout = $session->layout;
   } 
   else {   // standard view
   $layout = "grid";
   }
}
include("./inc/{$layout}.inc");  // returns $layoutView
...
html goes here
...
<div class="myView">
<?= $layoutview ?>
</div>
.....

So basically: Fetch the click, identify the button, load the current page via Ajax and with a GET variable which tells the template which view to render. The response is filtered, so only the myView part is the replacement for the current .myView.

Written in the browser, totally untested.

  • Like 3
Link to comment
Share on other sites

@MadeMyDay -

I think your code is okay, did not work for some reason ...

placed the script in footer,

the session BEFORE any output,

after that the buttons in the header

and the include() in my template for content

This next part I do not understand, it supposed to be the css layout (do not need), because should be already set in $layout which will be included. Or am I going with this the wrong way?

<div class="myView">
<?= $layoutview ?>
</div>

But I actually need to pass variable ( "grid" or "list" ) to $layout;

Set session for this value;

And then include the file with my php/layout.

Judging from the session code this: include("./inc/{$layout}.inc"); is working once, buttons does nothing...

Link to comment
Share on other sites

Judging from the session code this: include("./inc/{$layout}.inc"); is working once, buttons does nothing...

Try include("./inc/".$layout.".inc");

And your includes should return $layoutview;

For example:

foreach($products as $)}
  $layoutview. = "<div>{$p->title}</div>";
}

As I said, totally untestet. If the button does nothing please provide console output.

Link to comment
Share on other sites

Maybe I am on a different track...

I have two files: grid.inc + list.inc , Both have their own php and css

As it stands now (default) the include("./inc/".$layout.".inc"); is reading include("./inc/grid.inc");

This should also be when the button "grid" gets clicked. Is not working...

When the button "list" get clicked, I need it to include "list"... and should read include("./inc/list.inc"); Is not working...

- edit -Provide console output ?? were can I find that ?? using FF found it, but did not display ANY errors...

Link to comment
Share on other sites

1, 2, 3, 4, and back to 1 ... The only way I could make this work is using this following code, which on a refresh/reload does not give popus asking to re-send info again. I guess it is only doing that on post method...

it will output url like this: "path/?view=list" which are urlsegments.  

// menu buttons in header
<form action='./'>
         <input type='submit' class='button' name='view' value='list' />
         <input type='submit' class='button' name='view' value='grid' />
</form>

// and in the top of content(ps. using GET bevause I did not set POST in form)...
if (isset($_GET['view'])) {
    switch ($_GET['view']) {
        case 'grid': $layout = 'grid'; echo $layout; break;
        case 'list': $layout = 'list'; echo $layout; break;
    }
} else{
    $layout = 'grid';
}

So, I have:

$selector = "template=member-profile";

     // here I need to build a switch 
     // based on fields (example if someone clicks on 'bodytype')

// a little further ...
$selects = $pages->find($selector);

// at the end ...
include ("./inc/{$layout}.inc");

// and inside the layout file ... etc
foreach ($selects as $member) { ?>

But everytime this runs with something new in the selector, the urlsegment get lost...

I was thinking to use whitelist to 'remember' the value, and have:

$this->input->whitelist("view", $this->input->get->view);

but don't know how to continue...

Link to comment
Share on other sites

You should really think about keeping the markup constant and only changing the CSS. Preferably you would toggle a single class on your container (a <ul> probably) via JS and save the preference to $session through AJAX. Of course, I don’t know your requirements, but all this seems really complex. Even if you really do need to change all the markup (do you want to display different data or do you want to display the same data differently?), you might want to build it entirely in JQuery using AJAJ data or something.

Link to comment
Share on other sites

The Jquery / javascript / ajax was not working as I already expected in my first post.

In both files, the layout is different and some of the data. So changing only CSS does not help.

Basically I just need to store this value in a session upon clicking something, then something like: if this is page xxx or yyy, layout is session value.

But do not know how. Been browing the internet the whole day.

Making it static I end up with 2 url's fetching (almost the same data) and if someone could say if that's good SEO speaking then okay :

/path/to/page/list/page=2

/path/to/page/grid/page=2

If using other methods I guess I end up with a # in url, as long as session is in place i would not mind.

Link to comment
Share on other sites

Been following this discussion with interest, but...

In a case like this I simply had a template with both layouts in it, in your case the grid and the list in separate divs, and just showed and hide the divs with jquery. Worked perfect.

But, maybe I am missing something and I am still too much of a noob for this :P....Just curious....why don't you choose for a situation like this not just two pages?

1. the gridpage with a gridtemplate and in the admin all the data

2. a second empty listpage with a listtemplate.

At the backend you leave the listpage empty. And in the listtemplate you just load the data of the gridpage. 

Then a simple pagelink to the other page in both templates.

What am I missing here? :)

Link to comment
Share on other sites

Well here are my thoughts...

A: 2 pages

would mean I have them either in the beginning or end of the url... buth their title would not mean so much - if thinking about content.

would also mean I probably somewere end up with same data on 2 pages. SEO problem here.

B: 1 page

would mean I have twice data and markup on 1 page, had to use CSS to hide a part (but cannot use media query for that)

so I would have to load YET another jquery of something else

it will also mean I have to load the whole bunch of data to only show half.

Also this presents yet another SEO problem. Hiding in css does not prevent reading from a crawler.

C: urlsegments

I could use the url segments to work with, it does require GET which is less secure then POST.

In the end, when you have langues, AND pagination AND segments for this part,

it would look like  /?lang=en&page=3&view=grid or something similar.

Moving through pages, I would need to make a adjustment to keep it in the segmentnr they are in. 1=a&2=b&3=c...

I prefer to use native PW segments when they are needed especially for the pagination and language. Unless you change htaccess or something.

D: Jquery, Ajax etc

There are solutions, but they require a reload of the page (in my case) to get the value in the php variable...

and I would need to use CSS - show and hide parts.

They are overload in my opinion... I now have 5 lines of code - with only an if statement - and could even be simplified to 2 lines. Far less then using any of the other solutions.

E: framework

I use foundation, but on any framework, I simply use native parts which work everywere.

And of course I could use native visibility classes to show or hide...

but php requests had to be made anyway, for nothing, get processed, and is double load for nothing.

I set up my pages with what I want to show, not what I want to hide - if that makes sence.

Of course, any case is different I guess - but in the end PW get the job done. That's why I will never return to Joomla, WP, Drupal or any other :)

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...