Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

WordPress

Boris Kamp
Boris Kamp
16,660 Points

Wordpress archive page options

Hi!

How can I get different layout options to work in an archive page? Im planning on working to two options, list-style and tiles and want the user to be able to select either one on the archive page as an "view option" or something.

Im familiar with building the layouts, just don't know how to get Wordpress to recognize them both and let the user be able to choose with a button or something.

Thanks!

4 Answers

Boris Kamp
Boris Kamp
16,660 Points

Guys, I worked out my own version! it works perfect and I think it's a great solution. I made two loops in my archive.php, one for the tile view, and one for the list view:

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>

          <div class="col-xs-6 col-sm-4 col-md-3 gridPost">
            <a href="<?php the_permalink(); ?>">
              <div class="grid-item">
                <img class="grid-img" src="<?php the_field('postGridImage'); ?>" alt="<?php the_title();?>">
                <h5><?php the_field('kitName'); ?></h5>
                <div>
                  <img class="country-flag" src="<?php bloginfo('stylesheet_directory'); ?>/images/country_flags/<?php $terms = get_the_terms( $post->ID , 'countries' ); foreach ( $terms as $term ) { echo $term->name; } ?> Flag.png" alt="><?php $term = get_field('country_of_origin');?><?php echo $term->name; ?> Flag">
                  <span class="label label-info scale">
                    <?php $terms = get_the_terms( $post->ID , 'scales' ); foreach ( $terms as $term ) { echo $term->name; } ?>
                  </span>
                  <span class="label label-info manufacturer">
                    <?php $terms = get_the_terms( $post->ID , 'manufacturers' ); foreach ( $terms as $term ) { echo $term->name; } ?>
                  </span>
                </div>
              </div>
            </a>
          </div>

        <?php endwhile; else: ?>

          <div class="page-header">
            <h1>Oh no!</h1>
          </div>

          <p>No content is appearing for this page!</p>

        <?php endif; ?>

      </div>

      <?php rewind_posts(); ?>

      <div id="infinitescrollContainer" class="row container list-container">
        <table class="table table-striped">
          <thead>
            <tr>
              <th><h5>Kitname</h5></th>
              <th><h5>Scale</h5></th>
              <th><h5>Manufacturer</h5></th>
              <th class="hidden-xs"><h5>Country</h5></th>
              <th class="hidden-xs"><h5>Date</h5></th>
              <?php if ( is_post_type_archive( 'reviews' ) ) { ?> 
                <th><h5>Score</h5></th> 
              <?php } ?>

            </tr>
          </thead>
            <tbody>
              <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
                <div class="listPost">
                    <tr>
                      <td><a href="<?php the_permalink(); ?>"> <h5><?php the_field('kitName'); ?></h5></a></td>
                      <td><h5><?php $terms = get_the_terms( $post->ID , 'scales' ); foreach ( $terms as $term ) { echo $term->name; } ?></h5></td>
                      <td><h5><?php $terms = get_the_terms( $post->ID , 'manufacturers' ); foreach ( $terms as $term ) { echo $term->name; } ?></h5></td>
                      <td class="hidden-xs"> <h5><?php $terms = get_the_terms( $post->ID , 'countries' ); foreach ( $terms as $term ) { echo $term->name; } ?></h5></td>
                      <td class="hidden-xs"><h5><?php echo the_time('F j, Y');?></h5></td>
                      <?php if ( is_post_type_archive( 'reviews' ) ) { ?>
                        <td>
                          <div class="progress archive">
                            <div class="progress-bar progress-bar-success archive" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: <?php the_field('reviewRating'); ?>%;">
                              <p><strong><?php the_field('reviewRating'); ?>%</strong></p>
                            </div>
                          </div>
                        </td>
                      <?php } ?>
                    </tr>
                </div>
              <?php endwhile; else: ?>
                <div class="page-header">
                  <h1>Oh no!</h1>
                </div>
                <p>No content is appearing for this page!</p>
              <?php endif; ?>
            </tbody>
          </table>

please note the html markup for the table above the second loop, and don't forget the <?php rewind_posts(); ?> between the loops!

Now the trick is done with the main div, created above each loop, the first div (for the tile view) has a class called 'grid-container' and the second main div (for the list view) has a class 'list-container'

Now I added two buttons, and all that was left was to use this javascript code:

//Create display options in archive pages
    //Toggle grid view
    $(".glyphicon-th").click(function() {
        $( ".grid-container" ).show();
        $( ".list-container" ).hide();
    });

    //Toggle list view
    $(".glyphicon-align-justify").click(function() {
        $( ".list-container" ).show();
        $( ".grid-container" ).hide();
    });

note that you must set

.list-container {display: none}

in your style.css! That is what I have thought out and done, it works perfectly!

Jacques Vincilione
Jacques Vincilione
17,292 Points

Good job trying to figure out an alternate way to make this work. It is a very well thought out solution.

Just a tip for future reference, asking the right questions is critical in getting the answers you need. For instance, you probably would have a received a suitable solution to your problem had you asked the right question.

You asked for a way to alternate between a list and a grid(tile) view, but what you really needed was a way to alternate between a grid/tile view and a table view. The prior (what you asked for) does not require new markup for the changes to work, just css. However, needing the data to be presented in a tabular view requires separate markup from the grid view, and is why you had to come up with your own solution.

While it very may well be that you are not familiar with all the "lingo" of web development, it would have helped to post an example of what you wanted the code and/or what you wanted each view to look like (An image or jsfiddle.com/codepen.com) if you were unsure of the terminology. Specifically since none of the answers involved using tables.

I hope we can be of more help in the future. I encourage you to continue learning and improving as a developer! Good luck!

Boris Kamp
Boris Kamp
16,660 Points

I understand! thanks for pointing this out to me!

Jacques Vincilione
Jacques Vincilione
17,292 Points

You cannot have multiple archive templates per say, but you can do what you're talking about in another way; and here is how:

  1. When the archive page loads, show whichever you want to be default.
  2. Add buttons that allow them to change the view. (IE: A "List Style" button, and a "Tile View" button)
  3. Add a archive tile class that would essentially change the styling of the list items to show up as tiled.
  4. Use jquery/javascript to add/remove the archive tile class and alter the layout. If you have any questions, let me know.
Jacques Vincilione
Jacques Vincilione
17,292 Points

I figured I should show a code example, this assumes jquery is being used, and also is just the html, as I don't know how your structure in your template is set up:

<style>
#titleButton, #listButton{
    background: #0f0;
    padding:5px 10px;
}
.archive-tiled{
    display:block;
    width: 30%;
    float: left;
    margin-right: 2%;
    margin-top: 10px;
}

</style>
<script>
    $("#titleButton").click(function(){
        $(".archive-list-item").addClass("archive-tiled");
    });
    $("#listButton").click(function(){
        $(".archive-description").hasClass("archive-tiled") ? $(".archive-list-item").removeClass("archive-tiled") : null;
    });
</script>
<span id="tileButton">Tile View</span>
<span id="listButton">List View</span>
<li class="archive-list-item">
    <h2>My Title</h2>
    <p>Some description here</p>
</li>
<li class="archive-list-item">
    <h2>My Title2</h2>
    <p>Some description here</p>
</li>
<li class="archive-list-item">
    <h2>My Title3</h2>
    <p>Some description here</p>
</li>

This code is not tested*

Well thought-out but he asked for a "tile" view, so I'm assuming a view where each blog posts appears as a rectangular div.

Jacques Vincilione
Jacques Vincilione
17,292 Points

I mis-read tiles and "titles." I'll adjust my code accordingly.

Jacques Vincilione
Jacques Vincilione
17,292 Points

Code example has been updated.

There is no need for containing divs, that would just be extra (and most likely) unneeded markup.

My suggestion would be to have two different stylesheets for this page, with one being your tile view and the other being your list view. You can attach an ID attribute to your stylesheets, so that you can target them using jQuery, allowing your user to be able to click and toggle the different views.

Assuming your page loads with a stylesheet with an ID of "styles2", your jQuery would look something like:

  '''javascript
   $('.btn').click(function(){
   $(head).append('<link href="styles1.css" rel="stylesheet" id="styles1">');
   $('#styles2).remove();
   });

'''

Then you would do the opposite for your other button.

Jacques Vincilione
Jacques Vincilione
17,292 Points

That's a pretty good idea, but there are two issues:

  1. This would require a separate header.php file for the archive page. and
  2. This would require and http request each time a button is clicked.

I don't believe it would require a separate header file. When the user clicks on the button, the head will exist in the DOM. If the stylesheet is sitting on the server but not being loaded, then a simple append would do the trick.

Jacques Vincilione
Jacques Vincilione
17,292 Points

Good point on the header part, but the problem would still be that you have to load another http request each time you clicked a button. It's better to have one stylesheet anyway due to keeping http requests down.

Boris Kamp
Boris Kamp
16,660 Points

Thanks for the help guys! I will look into it soon as I arrive at this part of my website! I will definitely post back here. Thanks!