Skip to content
Grav 2.0 is officially stable. Read the announcement →

Community guidelines

Please keep discussions civil and on-topic. Repeated violations may lead to a temporary ban.

Plugins

Comment count on article/blog listing

Started by Seth 8 years ago · 2 replies · 913 views
8 years ago

Hi, I've been looking to add a comment count next to article titles in the blog listing, but it doesn't look like that data is exposed by page.find(). The Comments plugin gets that count in the admin panel with the following function:

PHP
/**
 * Return the latest commented pages
 */
private function fetchPages() {
    $files = [];
    $files = $this->getFilesOrderedByModifiedDate();

    $pages = [];

    foreach($files as $file) {
        $pages[] = [
            'title' => $file->data['title'],
            'commentsCount' => count($file->data['comments']),
            'lastCommentDate' => date('D, d M Y H:i:s', $file->modifiedDate)
        ];
    }

    return $pages;
}

Is there any way I could obtain a similar count for a specific page? I have a workaround that works by using p.title from page.find() to cross-reference pages.title from fetchPages(), but that forces me to loop through every commented page on the site:

TWIG
    {% set articles = page.find('/news').children.order('date', 'desc').slice(0,3) %}
    {% for p in articles|slice(0,3) %}
    <div class="latest-post">
        <h2><a href="{{p.url}}">{{ p.title|e }}</a></h2>&nbsp;&mdash;&nbsp;{{ p.date|date("M j, Y") }}
        {% for page in grav.twig.pages %}
            {% if page.title == p.title %}
                &nbsp;&ndash;&nbsp;{{page.commentsCount}} comment{% if page.commentsCount > 1 %}s{% endif %}
            {% endif %} 
        {% endfor %}
        {{p.content}}
    </div>
    {% endfor %}

I couldn't find a way to find an array key from a value to avoid looping (something like get_key_for_value(value, array)). What's more, I'm not sure whether Grav allows duplicate names for pages, but I feel like searching based on route would be safer. Any help would be very appreciated.

last edited 06/05/18 by Seth
8 years ago

OK I think I follow this.

A few Twig things:

  • you've sliced that page collection twice (lines 1 & 2) - I'd recommend removing all that slicing and ordering while you debug this
  • look into using {% for ... if ... %} rather than separate blocks, you can even add an else block - BUT! you don't need any of this here as per my next point
  • your inner loop seems completely redundant to me - don't you already have access to p.commentsCount in your outer loop?
  • Grav has a custom Twig filter called pluralize for the part where you add an 's', so you can simply say p.commentsCount 'comment'|pluralize(p.commentsCount)

You don't need this either if you remove the inner loop, but you could have reliably matched on the unique url property rather than title.

Does that get you back on track?

8 years ago

@hughbris:

  • you’ve sliced that page collection twice (lines 1 & 2) - I’d recommend removing all that slicing and ordering while you debug this
    (snip)
  • Grav has a custom Twig filter called pluralize for the part where you add an ‘s’, so you can simply say p.commentsCount 'comment'|pluralize(p.commentsCount)

Oh, thanks. I saw that filter during my searches but didn't bother to implement it at the time.

@hughbris:

  • look into using {% for ... if ... %} rather than separate blocks, you can even add an else block - BUT! you don’t need any of this here as per my next point
  • your inner loop seems completely redundant to me - don’t you already have access to p.commentsCount in your outer loop?

Nope, that doesn't display anything. As far as I can tell (which is not very far), commentsCount comes specifically from the Comments plugin so page.find doesn't have a way to access it.

@hughbris:
You don’t need this either if you remove the inner loop, but you could have reliably matched on the unique url property rather than title .

fetchPages() doesn't give me a URL/route property to work with, but more importantly I just found out that it only fetches comments from the past 7 days (by virtue of getFilesOrderedByModifiedDate() having that limitation), which doesn't work for my use case. Ideally, I'd rather have a way to target a specific comment thread, but I don't know how I would make those look-ups from Twig without having to pregenerate results for every existing page at every page load anyway, which is insane. It would be so trivial if I could just use PHP =/

For the time being, I think I have it working with a customized copy of fetchPages() and getFilesOrderedByModifiedDate() that only collects comments from a specific, hard-coded folder regardless of date. I can then iterate through only those in my template and compare the URLs since I changed the standard comment format to include the route as part of the parameters. It still feels very hacky, but at least it cuts down on a lot of iteration. It's still not ideal if I wanted to show comment counts on blog listings for several categories, but since I only need it for my news feed for the time being, it is serviceable.

With your advice, the output is now as follows:

TWIG
    {% set articles = page.find('/news').children.order('date', 'desc').slice(0,3) %}
    {% for p in articles %}
    <div class="latest-post">
        <h2><a href="{{p.url}}">{{ p.title|e }}</a></h2>&nbsp;&mdash;&nbsp;{{ p.date|date("M j, Y") }}
        {% for newspage in grav.twig.newspages if base_url_relative ~ newspage.route == p.url %}
            &nbsp;&ndash;&nbsp;<a href="{{p.url}}#comments">{{ newspage.commentsCount }} {{ 'comment'|pluralize(newspage.commentsCount) }}</a>
        {% endfor %}
        {{p.content}}
    </div>
    {% endfor %}

Thanks for the pointers! (Though I'm still very interested if anyone can think of a way to target specific comment pages from Twig.)

Suggested topics

Topic Participants Replies Views Activity
Plugins · by Rene, 1 week ago
2 54 1 week ago
Plugins · by Xavier, 4 weeks ago
2 61 4 weeks ago
Plugins · by Luka Prinčič, 7 years ago
3 1188 1 month ago
Plugins · by Sebastian van de Meer, 1 month ago
1 54 1 month ago
Plugins · by PIERROT Alain, 2 months ago
3 79 2 months ago