SamC Posted November 27, 2016 Share Posted November 27, 2016 Hi, I have a page which list news items but I wanted to be able to have the most recent one at the top as a featured news item. Like this: -- NEWS ITEM 1 -- - news item 2 - news item 3 - news item 4 I'm not sure how to list just one news item (most recent) and then list the rest underneath but skipping the first one, offset of 1. Here's the code so far: // news-index.inc <?php $entries = $pages->find("template=news-entry, limit=6, sort=-sort"); $pagination = $entries->renderPager(); ?> <div class='large-image-wrapper'> <div class='title-wrapper'> <h1><?php echo $title; ?></h1> </div> </div> <div id="page-tabs-wrapper"> <div class='page-tabs'> <div class='upper'> <?php echo $pagination; ?> </div> </div> </div> <div id='news-row'> <?php foreach ($entries as $entry): ?> <?php $publish_date = date('d/m/y', $entry->created); $created_by = $entry->createdUser->displayName; if ($entry->mainImage) { $image = $entry->mainImage->size(768, 280, 'center'); $thumbnail = $image->url; } else { $thumbnail = $assets . '/images/placeholder.jpg'; } ?> <div class='news-column news-column-left'> <div class='news-index-image-wrapper' style='background-image: url("<?php echo $thumbnail; ?>");'> <h2> <a href='<?php echo $entry->url; ?>'><?php echo $entry->title; ?></a> </h2> </div> </div> <div class='news-column news-column-right'> <div class='entry-info'> <span class='fa fa-calendar' aria-hidden='true'></span> Posted by <span class='entry-highlight'><?php echo $created_by; ?></span> on <span class='entry-highlight'><?php echo $publish_date; ?></span> </div> <?php if ($entry->summary) { echo $entry->summary; } ?> <?php if ($entry->body): ?> <p class='read-more'><a href='<?php echo $entry->url; ?>'>Read full article <span class='fa fa-arrow-circle-right' aria-hidden='true'></span></a></p> <?php endif; ?> </div> <?php endforeach; ?> </div> <div class='page-tabs'> <div class='lower'> <?php echo $pagination; ?> </div> </div> Do I have to loop twice? i.e. the first one loops and grabs item 1, the next loop offsets item 1 and grabs items 2 onwards. The first item will be further up the page using the page title to show the latest news title i.e. // FROM <div class='large-image-wrapper'> <div class='title-wrapper'> <h1><?php echo $title; ?></h1> // prints 'Latest News' </div> </div> // TO <div class='large-image-wrapper'> <div class='title-wrapper'> <h1><?php echo FIRST NEWS ITEM TITLE; ?></h1> // prints 'This is my first news item' <p>FIRST NEWS ITEM SUMMARY</p> // textfield with 220 character limit <span class='button'><a href='#'>LINK TO FIRST NEWS ITEM</a></span> </div> </div> ...then the rest of the page will be item 2 onwards. Make sense? I attach a screenshot to further demonstrate what I'm talking about. Thanks for any advice ---EDIT--- Just had a thought, not sure how this is gonna work on page 2, page 3 etc... any thoughts on that are welcome too! ---EDIT 2--- The whole thing can go in the loop, that'll stop the item 1 being the same on every subsequent page. Maybe something like this: for each (if is item 1) output HTML (item 1) (else) output this HTML (every other item) endforeach Link to comment Share on other sites More sharing options...
Zeka Posted November 27, 2016 Share Posted November 27, 2016 Hi @SamC You can use find("")->first(); $entries = $pages->find("template=news-entry, limit=6, sort=-sort"); $firstItem = $entries->first(); $otherItems = $entries->not("$firstItem"); 2 Link to comment Share on other sites More sharing options...
SamC Posted November 27, 2016 Author Share Posted November 27, 2016 16 minutes ago, Zeka said: Hi @SamC You can use find("")->first(); $entries = $pages->find("template=news-entry, limit=6, sort=-sort"); $firstItem = $entries->first(); $otherItems = $entries->not("$firstItem"); Ok, thanks, I get it now. Link to comment Share on other sites More sharing options...
SamC Posted November 27, 2016 Author Share Posted November 27, 2016 (edited) Actually having another problem, that is, getting the mainImage field from the page being used for the highlighted item and then pass on resized options to generate a few CSS rules for a background image. Trying this: <?php $entries = $pages->find("template=news-entry, limit=6, sort=-sort"); $firstItem = $entries->first(); $otherItems = $entries->not("$firstItem"); $pagination = $entries->renderPager(); $small = $firstItem->mainImage->size(768, 256, 'center'); $large = $firstItem->mainImage->size(1500, 500, 'center'); $xLarge = $firstItem->mainImage; $smallBgImage = $small->url; $largeBgImage = $large->url; $xLargeBgImage = $xLarge->url; ?> ...but on line 7 ($small = $firstItem->id->mainImage->size(768, 256, 'center');) I'm getting an error: Fatal error: Uncaught Error: Call to a member function size() on null If $firstItem is an id (1017 in my case), I thought the above would work. I need to grab the mainImage field from the page that this id refers to, but only for the first item, the rest of the page works perfect (showing item 2 onwards). Edited November 27, 2016 by SamC Mistyped code Link to comment Share on other sites More sharing options...
Zeka Posted November 27, 2016 Share Posted November 27, 2016 @SamC check you image field settings on "Details" tab. If you want to upload only one image to this field you should choose third option "Single item" , after this change your code should work. Or try $firstItem->mainImage->first()->size(768, 256, 'center'); 2 Link to comment Share on other sites More sharing options...
SamC Posted November 27, 2016 Author Share Posted November 27, 2016 @Zeka thanks for the help. Here's what I've currently got so I thought the code should have been ok. Especially since I call the same size() function later in the code within the loop and it works fine. Link to comment Share on other sites More sharing options...
Robin S Posted November 28, 2016 Share Posted November 28, 2016 17 hours ago, SamC said: ...but on line 7 ($small = $firstItem->id->mainImage->size(768, 256, 'center');) I'm getting an error This line is different to what you show in the codeblock above it: namely, there is the extra ->id in there. The ID property of a page is an integer, so it doesn't have a mainImage that you can call size() on. If you remove the ->id it should work, but I recommend you check to make sure mainImage is actually populated (i.e. that an image has been uploaded to the field) before you do size(). 3 Link to comment Share on other sites More sharing options...
SamC Posted November 28, 2016 Author Share Posted November 28, 2016 4 hours ago, Robin S said: but I recommend you check to make sure mainImage is actually populated (i.e. that an image has been uploaded to the field) before you do size(). Ok, the penny has dropped finally :-p I needed a default image so I could visualize how the page looked... <?php $publish_date = date('d/m/y', $entry->created); $created_by = $entry->createdUser->displayName; if ($entry->mainImage) { $image = $entry->mainImage->size(768, 280, 'center'); $thumbnail = $image->url; } else { $thumbnail = $assets . '/images/placeholder.jpg'; // <<< my page is full of these! } ?> I think that check for an image may be a good idea. Thanks people. 1 Link to comment Share on other sites More sharing options...
Zeka Posted November 28, 2016 Share Posted November 28, 2016 As alternative to this part of code you can use "Default value (when empty)" in image field settings. 38 minutes ago, SamC said: else { $thumbnail = $assets . '/images/placeholder.jpg'; // <<< my page is full of these! } 2 Link to comment Share on other sites More sharing options...
SamC Posted November 28, 2016 Author Share Posted November 28, 2016 (edited) Ok, so I've gone for this approach. My images are being created in a few places and the templates are getting a bit unruly, so I thought I'd get this into a function. Of course, any improvements I can make are appreciated. The function and new news-index.php look like this now. // _func.php /** * * @param PageID $item * @param $img string (medium, large, xLarge) * @return $imgUrl string * */ function getImage($item, $img) { if ($item->mainImage) { switch ($img) { case 'medium': $img = $item->mainImage->size(750, 250, 'center'); break; case 'large': $img = $item->mainImage->size(1500, 500, 'center'); break; case 'xLarge': $img = $item->mainImage->size(2400, 800, 'center'); break; } $imgUrl = $img->url; return $imgUrl; } } // news-index.php <?php $entries = $pages->find("template=news-entry, limit=6, sort=-sort"); $firstItem = $entries->first(); $otherItems = $entries->not("$firstItem"); $pagination = $entries->renderPager(); $firstItemPublishDate = date('d/m/y', $firstItem->created); $firstItemCreatedBy = $firstItem->createdUser->displayName; ?> <style type="text/css"> .large-image-wrapper { background-image: url('<?php echo getImage($firstItem, 'medium'); ?>'); } @media screen and (min-width: 850px and max-width: 1499px) { .large-image-wrapper { background-image: url('<?php echo getImage($firstItem, 'large'); ?>'); } } @media screen and (min-width: 1500px) { .large-image-wrapper { background-image: url('<?php echo getImage($firstItem, 'xLarge'); ?>'); } } </style> <div class='large-image-wrapper'> <div class='title-wrapper'> <h1><a href='<?php echo $firstItem->url; ?>'><?php echo $firstItem->title; ?></a></h1> <?php if ($firstItem->summary) { echo $firstItem->summary; } ?> <div class='entry-info'> <span class='fa fa-calendar' aria-hidden='true'></span> Posted by <span class='entry-highlight'><?php echo $firstItemCreatedBy; ?></span> on <span class='entry-highlight'><?php echo $firstItemPublishDate; ?></span> </div> </div> </div> <div id="page-tabs-wrapper"> <div class='page-tabs'> <div class='upper'> <?php echo $pagination; ?> </div> </div> </div> <div id='news-row'> <?php foreach ($otherItems as $entry): ?> <?php $publishDate = date('d/m/y', $entry->created); $createdBy = $entry->createdUser->displayName; ?> <div class='news-column news-column-left'> <div class='news-index-image-wrapper' style='background-image: url("<?php echo getImage($entry, 'medium'); ?>")'> <div class='news-index-title-wrapper'> <h2> <a href='<?php echo $entry->url; ?>'><?php echo $entry->title; ?></a> </h2> <div class='entry-info'> <span class='fa fa-calendar' aria-hidden='true'></span> Posted by <span class='entry-highlight'><?php echo $createdBy; ?></span> on <span class='entry-highlight'><?php echo $publishDate; ?></span> </div> </div> </div> </div> <div class='news-column news-column-right'> <?php if ($entry->summary) { echo $entry->summary; } ?> <?php if ($entry->body): ?> <p class='read-more'><a href='<?php echo $entry->url; ?>'>Read full article <span class='fa fa-arrow-circle-right' aria-hidden='true'></span></a></p> <?php endif; ?> </div> <?php endforeach; ?> </div> <div class='page-tabs'> <div class='lower'> <?php echo $pagination; ?> </div> </div> // _images.scss .large-image-wrapper { padding-top: 0; @include media($tablet) { padding: 75px 0; } @include media($hidpi) { padding: 150px 0; } background-position: center; background-repeat: no-repeat; background-size: cover; } I have set a default image as suggested by @Zeka (awesome feature!) and my max upload width is 2400px, with min also being 2400px. The biggest size image I will ever display is 2400px (the xLarge size will just be cropped in height). Next step is making '<?php echo $created_by; ?>' into a link which lists all news items posted by that user. Not sure whether I'll end up with a URL like site.com/news/username/ or site.com/user/news/ or whatever. Cross that bridge when I get to it. Seems to work ok so far though. I still like the fact that I can focus on the design so much better than I could in other CMS's I've used. Edited November 29, 2016 by SamC Final code revision for this thread 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now