Jump to content
mike62

Displaying the most recent blog posts using different layouts for each

Recommended Posts

I'm new to PW... I'd like to have some blog posts displayed on our homepage based off the attached mockup.

I want each post to use a slightly different layout.

Is this possible?

blog-posts.jpg

Share this post


Link to post
Share on other sites

Here are two ways:

<?php namespace ProcessWire;
/** @var $pages Pages */
$posts = $pages->find('template=post, sort=-published');
$latest = $posts->shift(); // removes first item off of $posts

?>
<ul class="post-list">
    <li class="item--latest item">
        <?= $latest->title ?>
    </li>
    <?php if ($posts->count): ?>
        <?php foreach ($posts as $i => $p): ?>
            <?php $itemClass = ($i % 3 == 0) ? "item--hoverable" : ''; ?>
            <li class="<?= $itemClass ?> item"><?= $p->title ?></li>
        <?php endforeach; ?>
    <?php endif; ?>
</ul>

<!-- OR -->
<?php if ($posts->count): ?>

    <ul class="post-list">
        <?php foreach ($posts as $i => $post): ?>
            <?php if ($i === 0): // LATEST POST ?>
                <li class="item--latest item">
                    Latest: <?= $post->title ?>
                </li>
            <?php elseif ($i === 1): // BASIC ?>
                <li class="item--basic item">
                    Basic: <?= $post->title ?>
                </li>
            <?php elseif ($i % 3 === 0): // HOVERABLE  ?>
                <li class="item--hoverable item">
                    Hover Me: <?= $post->title ?>
                </li>
            <?php endif; ?>
        <?php endforeach; ?>
    </ul>
<?php else: ?>
    <p>No posts found</p>
<?php endif; ?>

 

Edited by abdus
changed semicolon to colon
  • Like 2

Share this post


Link to post
Share on other sites

Optionally, you can create a select field, or better, a page field and select flavors for each post while editing and render items depending on that

https://processwire.com/blog/posts/making-efficient-use-of-fields-in-processwire/#use-page-fields-rather-than-individual-checkboxes

if($item->flavors->get("name=hoverable")) {
    // this page has the "hoverable" flavor set
}
  • Like 2

Share this post


Link to post
Share on other sites

Ooooh wonderful, that's excellent to know. I likely won't use it for this site, because they want the layout to remain the same on the homepage, and have the content just flow into it, but good to know for the future. Thanks!!

Share this post


Link to post
Share on other sites

@abdus I've got this *almost* working... but I'm stumped with simply getting the sort order to be reversed, so that the newest post shows at the top. Also, can I easily limit this query to 4 posts? Thanks!

Share this post


Link to post
Share on other sites

@kongondo Thanks! I literally JUST found both those in the docs. Some things are hard for me to find in these docs. Is there a way to search *just* the docs, on the site?

Share this post


Link to post
Share on other sites
2 minutes ago, mike62 said:

@kongondo Thanks! I literally JUST found both those in the docs. Some things are hard for me to find in these docs. Is there a way to search *just* the docs, on the site?

https://processwire.com/talk/topic/6196-easy-search-on-pw-forums-with-google/?tab=comments#comment-60632

https://processwire.com/talk/topic/6196-easy-search-on-pw-forums-with-google/?do=findComment&comment=153343

 

  • Like 1

Share this post


Link to post
Share on other sites
3 minutes ago, mike62 said:

*just* the docs, on the site?

I bookmarked these and update the search word after clicking them and press enter. I know it's crude but it is the fastest way for me :-[

Share this post


Link to post
Share on other sites

Thanks for the tip @Robin S I cannot se how it can be faster than my dead simple solution. Sure, I perform an otherwise useless search but Google is sooo fast ;)

With the "keyword search feature", I need to be able to remember the keyword(s). Well, I already use a lot of them in other contexts so I find it hard to memorize more. Next, I need to type the get there. One click in the Bookmarks Bar and another double click to highlight the dummy search word is what I can do quickly without mistakes. Yeah, it's lame but it works for me.

Share this post


Link to post
Share on other sites

Cool, thanks @SamC that's a good one to know. I ended up using the page field as @abdus suggested, so that each post can "choose" its own layout for the homepage. It's working well. o/

  • Like 2

Share this post


Link to post
Share on other sites
12 minutes ago, mike62 said:

Cool, thanks @SamC that's a good one to know. I ended up using the page field as @abdus suggested, so that each post can "choose" its own layout for the homepage. It's working well. o/

Good to hear! That's a nice technique, will certainly be looking into that one.

Share this post


Link to post
Share on other sites

Hey @SamC  I was looking for a way to style some results of a selector differently than others and found your 'slicing' suggestion fitting perfectly to my scenario. Here is a short example of what I have and would allow any results from to be styled one way and the rest - another:

<?php 			
	// Check if there are any news added
	if (count($news->children)) {
		
		// Create am array with the latest 5 news
		$newsposts = $pages->find("template=news-inner, status=published, sort=-date, limit=6");
		
		// Create a slice of 2 posts for the large image style
		// 0 means the starting record, 2 means the number of records to slice
		$left = $newsposts->slice(0,2);
		
		// Grab the rest of the posts from the list for styling with just a title and a date
		// 2 means that everything except the first two would be assigned.
		// The results limit is set initially at the selector
		$right = $newsposts->slice(2);
		
	}
?>

Having done that, it allowed me to simply loop through the $left and $right results (using foreach) and apply the proper markup for first appearance and the rest. Using this elegant technique would allow to have as many slices for different styling if a need be.

Unfortunately, my markup for the first news was in a row div that was closing before the rest of the posts appear in another row so I had to loop twice with foreach. I am sure there is a better way to include the opening and closing divs to avoid double/tripple etc. looping but as far as the result are not more than 6, I am not that worried about slowing the page down...

Share this post


Link to post
Share on other sites
3 hours ago, MilenKo said:

I was looking for a way to style some results of a selector differently than others

If it's just styling, you should first try a CSS-only solution. You can do a lot with just :nth-child or flexbox.

  • Like 1

Share this post


Link to post
Share on other sites

Thanks @dragan will try your approach to see how would that fit, however it is not just styling but the markup is different where the first 2 news are required to have a large image with some intro text, author, date, likes etc. where the next 4 are just title and date of posting.

That is why initially I thought to "slice" the array but it did not work properly so with $a->slice it did the trick. I will see how to serve the posts with a single foreach to avoid duplication, however the classes of divs are different, some javas are included in the no-image divs and some data handling. Not sure if I add a variable for the class, one for the javas and one for data- values to include in the div which one would be faster since I am looping once through 2 results and once through 4 others.

Maybe I could try using modulus operator or other approach as well ?

Share this post


Link to post
Share on other sites

Well I initially tried with the good old counter approach but things got messed up a bit because of the differences in the markup of large image post and others. Will revise the code and see how to include the opening and closing divs properly. Here is the markup I am working with:

Spoiler

<div class="row">

	<!-- Large image post x 2 -->
	<div class="news-block col-lg-4 col-md-6 col-sm-12 wow fadeInUp animated" style="visibility: visible; animation-name: fadeInUp;">
		<div class="inner-box">
			<div class="image-box">
				<figure class="image"><a href="#"><img src="images/resource/news-1.jpg" alt=""></a></figure>
			</div>
			<div class="lower-content">
				<div class="date">26 Aug. 2018</div>
				<h5><a href="blog-detail.html">Mac Keychain Bug Could Be Big Problem For Apple</a></h5>
				<div class="text">Fed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt ...</div>
				<div class="link-box"><a href="blog-detail.html">Read more</a></div>
			</div>
		</div>
	</div>


	<!-- News Block -->
	<div class="news-list col-lg-4 col-md-12 col-sm-12 wow fadeInUp animated" data-wow-delay="800ms" style="visibility: visible; animation-delay: 800ms; animation-name: fadeInUp;">
		<div class="inner-box">
		
			<!-- List Item x 4 -->
			<div class="list-item">
				<h5><a href="blog-detail.html">Nanotechnology immersion along the information.</a></h5>
				<span class="date">Aug 26 2018</span>
			</div>

		</div>
	</div>
</div>

 

Where Large image post shows twice and List Item show 4 times 😉

Share this post


Link to post
Share on other sites
9 minutes ago, MilenKo said:

<div class="news-block col-lg-4 col-md-6 col-sm-12 wow fadeInUp animated"

<div class="news-list col-lg-4 col-md-12 col-sm-12 wow fadeInUp animated" data-wow-delay="800ms"

I like the developer satisfacion coming through these lines 🙂 

  • Like 1
  • Haha 1

Share this post


Link to post
Share on other sites

@tpr Tell me about it 🙂 Just because of the div opening markup I was crushing my head for some time before I "split" the selector in two and then applied the every foreach inside of every div 😉 This could all goe to the CSS but hey - different people, different taste 🙂

Share this post


Link to post
Share on other sites

Guess you could be clever with modulus and some dynamic class names etc. Or, just go for two loops and call it a day. I did something before and tried to be uber clever about it, turns out it's not so clever when you go back and have to waste time working out how it works.

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 prestoav
      Hi everyone,
      PW version 3.0.123
      I've recently tried to upgrade the Blog module in an installation from 2.4.0 to 2.4.5 and now get the following errors when trying to visit Blog > Posts in admin:
      Fatal Error: Uncaught Error: Call to a member function count() on null in /MYSITE/site/modules/ProcessBlog/ProcessBlog.module:1299 Stack trace: #0 /MYSITE/site/modules/ProcessBlog/ProcessBlog.module(1421): ProcessWire\ProcessBlog->renderItemsSummaries(Object(ProcessWire\PageArray)) #1 /MYSITE/site/modules/ProcessBlog/ProcessBlog.module(1989): ProcessWire\ProcessBlog->renderItemsList(Object(ProcessWire\PageArray)) #2 /MYSITE/wire/core/Wire.php(380): ProcessWire\ProcessBlog->___executePosts() #3 /MYSITE/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___executePosts', Array) #4 /MYSITE/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\ProcessBlog), 'executePosts', Array) #5 /MYSITE/wire/core/ProcessController.php(333): ProcessWire\Wire->__call('executePosts', Array) #6 /MYSITE/wire/core/Wire.php(380): ProcessWire (line 1299 of /MYSITE/site/modules/ProcessBlog/ProcessBlog.module) This error message was shown because: you are logged in as a Superuser. Error has been logged. I can see posts in Blog > Dashboard and all seems to work still on the front end.

      Anyone else seen this or know of a fix?
    • By franciccio-ITALIANO
      Hi everyone.
      I've created 12 templates that are the same but each with an extra bit of html code. 
      The piece of code is as follows:
      <div> <div class="box-pf"> <i class="fa fa-map-pin fa-2x fa-red faa-pulse animated"></i> <a href=""> <span class="uk-text-middle"><i>Sonchus oleraceus</i> 'Grespino degli Orti'</span></b> </a> </div> </div> On the third line we read "fa-red."
      I created 12 similar templates.
      The first template has only one box with fa-red, the last template has 12 boxes with icons of 12 different colors.
      So. is there any way to have only 1 template and add, if I want and when I want, a small or big, same or different piece of html code?
       
    • By Brian Peat
      Hello! I've got a single client on Processwire and it's completely foreign to me. I've been able to find most things, but they've asked for a custom designed page with a full width header image/section, and then a body block and a right side bar below the header. They're using a landing page template, so I duplicated that, figured out how to add it in the admin, and assigned it to the page. Nothing. It doesn't change a thing.
      I feel like I'm missing something obvious. I've made sure all the fields are the same, I tried to set up the parent/child stuff though this page doesn't have a parent that I can tell (though it's under Landing Pages). If I can get the template to actually kick in, I think I can use a bit of code to check for the hero section and load it at the top. I also made a copy of the widget template and set that to load instead of the original. But again, since my main page template isn't kicking in, neither is the new widget template.
      I'd just love some tips on what to check or change to get a landing page to actually render what's in the assigned page template.
      Hopefully I've used the correct terminology here to make sense.
      Thanks!
    • By rookie
      hi there,
      Is there a module or other solution to select a template with a preview image? Sometimes it is not that easy to describe a template.
      e.g. Template with 3 columns (image, title, content, button) or template for a slider with max. 4 pictures.
      Even if it is nice to have a description field for a template, a picture says more than thousand words could describe.
      And no, I don't think I could develop something like that. I don't even know where to start.🙄
    • By muzzer
      I have just upgraded a site from 2.7 to latest v3.
      I have run into a weird issue where a page template setting for slashUrls changes from No to Yes immediately after an ajax call, causing the second ajax call on the page to use the wrong setting.
      There is no reference to the $template->slashUrls() in any of my code.
      This happens every time I load the page, it's 100% consistent.
      I have this running on a second machine under v2.7 and no such weirdness.
      I'm lost as to why this is happening, what would cause a PW setting change for slashUrls? Anyone have any ideas?
       
       
       
×
×
  • Create New...