Jump to content

Featured news item in list of news items


SamC
 Share

Recommended Posts

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 :)

Capture.JPG

 

---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

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

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 by SamC
Mistyped code
Link to comment
Share on other sites

@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');

 

  • Like 2
Link to comment
Share on other sites

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().

  • Like 3
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

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! }

  • Like 2
Link to comment
Share on other sites

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 by SamC
Final code revision for this thread
  • Like 1
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...