Where to add comments?

So, I have set up my new Kirby 4 version of an existing site and added comments to my blog posts. Everything is done, the registration and login forms. The form on the page to accept comments is also done.

But here is where I am hesitating, and that is where to put the comments. I see three options.

  1. Store the comments on the blog page itself.
  2. Store the comments in a new page within each post folder called comments.txt
  3. Store all comments in a single page.

One seems reasonable; all comments are stored on the same page as the blog post, and everything is contained on one page.

Three is probably the worst option, as it will undoubtedly be the slowest option if many comments get added over time.

I am asking because I think two will be the most commonly suggested approach, and I am edging towards one. I don’t know what I am missing, if anything, as to why I should go for one and not two.

Any views are appreciated. I want to get it right first time :slight_smile:

I’d go with option 2, i.e. a subpage for comments, probably even subpages for each comment. Especially with many comments, subpages would be the better option. If you go with this option, you should have a route in place or add templates that prevent direct access to the comments page and its children.

If they are separated from your page content, this cannot be messed up by many attempts to store something in the page at the same time.

Another option you did not list above would be to store comments in a SQLite database.

Thanks, @texnixe, that makes sense. I can see how that would be an issue, especially on the multiple attempts to store something causing page locks.

I did consider SQLite but didn’t want to go with that as, on this site, the number of comments will be little enough that a DB wouldn’t be justified. If I were going to use it for more than just comments, that would likely be a better option. Or maybe I should do that to solve the potential for page locking.

In honesty, I am implementing this as proof it works, as my next project will need it, and that page-locking issue may be far more likely.

SQLite generates just a file with a special file format and is installed on most systems, so not a huge database, and fits Kirby very well, in my opinion. Also used by the Retour plugin, for example. Just something to consider when you have many comments, for everything else, I’d go with the file system storage but consider single subpages per comment.

I am trying the comment-per-page option. I have got it all working as a rough design. Each page is being created correctly, but it’s storing all the comments in the _drafts folder. What have I missed?

In my controller:

    return function($page, $pages)
    {
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $text = get('comment');
    
        if ($text) {
            $author = null;
    
            // Check if a user is logged in
            if ($user = kirby()->user()) {
                $author = $user->username();
            }
    
    $page->createChild([
    
        'slug'    => 'comment-' . time(),
        'template' => 'comment',
        'content' => [
            'author' => $author,
            'text'   => $text,
        ],
        'num'     => $page->children()->count() + 1,
        'status'  => 'listed',
            ]);
    
            
            go($page->url() . '#comments');
        }
    }
    
    };

The comments are all listed as expected; see the screenshot below. Just in the wrong place.

Screenshot 2024-01-13 at 11.56.58

Edit: didnt copy the code correctly.

A newly created page is by default in the _drafts folder. However, I think it would be better to create a new parent folder comments within each article folder, then within this comments folder, create the comments.

To publish the comments, you can

  1. Make this a manual process, so that comments need to be reviewed before they are published. You will usually get a lot of spam, so IMO, this is the best option.
  2. Auto-publish the comments, by setting the draft option to false in the createChild method.
1 Like

Thanks, I reworked the code to create a comments folder; of course, I already have a couple of hundred posts, so I need to check and create first if it does not exist.

There is still some work to do, but everything works as expected. I can now tidy it all up. Thanks as always for your help, @texnixe.

    <?php 
    
    return function($page, $pages)
    {
    
    if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $text = get('comment');
    
        if ($text) {
            $author = null;
    
            // Check if a user is logged in, may not need this, check already done before you can see the form on the blog post.
            if ($user = kirby()->user()) {
                $author = $user->username();
            }
    
            // Check if the comments folder already exists (hundreds of existing posts at this point), if not then create it.
            $commentsFolder = $page->find('comments');
    
            if (!$commentsFolder) {
                // Create the comments folder from template
                $commentsFolder = $page->createChild([
                    'slug'    => 'comments',
                    'template' => 'comments',
                    'content' => [
                        'title' => 'Comments',
                    ],
                    'num'     => 1, 
                    'status'  => 'listed',
                    'isDraft' => false,
                ]);
            }
    
            // Now create a new folder inside the comments folder for each comment made.
            $commentsFolder->createChild([
                'slug'    => 'comment-' . time(),  // need something better than this. do it like other pages 
                                                                            1_comment, 2_comment etc..
                'template' => 'comment',
                'content' => [
                    'author' => $author,  // Can only comment if logged in so $author is always a 
                                                            registered user.
                    'text'   => $text,
                ],
                'status'  => 'listed',
                'isDraft' => false,
            ]);
    
            // redirecting back to the comments section on the page.
            go($page->url() . '#comments');
        }
    }
    
    };

Okay, I didn’t think this all the way through. I need the comments displayed on the panel page, but I can’t seem to get it working correctly.

When I do it this way it suggests there is nothing to display, note that it’s the comments section at the bottom I have added.

title: Blog Single Post
fields:
  postImage:
    label: Post Image
    type: files
  date:
    label: Date
    type: date
    width: 1/4
  category:
    label: Category
    type: select
    options:
      News: Industry News
      Mortgages: Regulated Mortgages
      Buy To Let: Buy To Let
      Interesting Property: Interesting Property
      Regulation: Regulation
      Valuations: Valuations
      Taxation: Taxation
      Questions: Questions
      General: General
      Guides: Guides
    width: 1/4
  featured:
    label: Featured post?
    type: checkboxes
    options:
      feature: Feature
    width: 1/4  
  postTags:
    label: Post Tags
    type: tags
    width: 1/4
  pageSummary:
    label: Page Summary
    type: textarea
    size: small
    width: 2/3
  pageFiles:
    label: Page Files
    type: files
    width: 1/3
  text:
    label: Text
    type: textarea
    size: large
    width: 2/3
  gallery:
    label: Gallery
    type: files
    layout: cards
    width: 2/3
  comments:
    label: Comments
    type: pages
    headline: Comments
    info: "{{ page.num() }} comments"

What am I doing wrong? I never really had to do anything complex in the blueprints before; this has me quite confused.

To show the comments for a article, you need a pages section. However, you added a pages field.

Your pages section would need the comments page as parent.

1 Like

Yes, I understood, I will fix that now!

Sorry, I do not understand the documentation on this.

If my blog post blueprint contains nothing but:

title: Blog Single Post
sections:
  drafts:
    label: Drafts
    type: pages
    status: draft
    templates: product
  published:
    label: Published Products
    type: pages
    status: listed
    templates: product
  pages:
    label: Main Pages
    status: all

I see the following on the page. The child page called comments

Screenshot 2024-01-13 at 20.49.49

And if I click on that, I get what I expect: a list of all comments that can be displayed, edited, and so on.

But I can’t combine any of the above with the existing blueprint, and I can’t seem to get the comments pages to display simultaneously with the existing fields needed for the blog post. Confused.

I think you are missing some basics how to create blueprints with fields and sections…

To mix fields and sections, your fields need to go into a section as well:

title: Blog Single Post
sections:
  fields:
    type: fields
    fields:
      postImage:
        label: Post Image
        type: files
      date:
        label: Date
        type: date
        width: 1/4
      # more fields...
   
  comments:
    type: pages
    label: Comments
    parent: page.children.find('comments')
    layout: list
    template: comment

You might want to use columns or tabs to clean this up a bit.

As regards the comments parent page, it might make sense to auto-create this page when a new article is created, see Subpage builder | Kirby CMS, because the above section will throw an error when this page doesn’t exist yet.

1 Like

Oh damn… It was this bit below I wasn’t getting, missed the need to do part of this. Sorry, @texnixe will need to spend a bit more quality time with the blueprints; never had to stretch further than a really basic approach until now.

sections:
  fields:
    type: fields
    fields:

So I thought everything was done, but I have come across a final issue I can’t figure out.

When creating a blog post, everything works as expected until I try to upload an image/file. Then I get this.

Screenshot 2024-01-14 at 20.36.35

Here is my blueprint

title: Blog Post
sections:
  fields:
    type: fields
    fields:
      postImage:
        label: Post Image
        type: files
      date:
        label: Date
        type: date
        width: 1/4
      category:
        label: Category
        type: select
        options:
          News: Industry News
          Mortgages: Regulated Mortgages
          Buy To Let: Buy To Let
          Interesting Property: Interesting Property
          Regulation: Regulation
          Valuations: Valuations
          Taxation: Taxation
          Questions: Questions
          General: General
          Guides: Guides
        width: 1/4
      featured:
        label: Featured post?
        type: checkboxes
        options:
          feature: Feature
        width: 1/4  
      postTags:
        label: Post Tags
        type: tags
        width: 1/4
      pageSummary:
        label: Page Summary
        type: textarea
        size: small
        width: 2/3
      pageFiles:
        label: Page Files
        type: files
        width: 1/3
      text:
        label: Text
        type: textarea
        size: large
        width: 2/3
      gallery:
        label: Gallery
        type: files
        layout: cards
        width: 2/3
  comments:
    type: pages
    label: Comments associated with this blog post
    parent: page.children.find('comments')
    layout: table
    columns:
      date: true
      author: true
      text: true
        width: 1/2
    template: comment

The way I have set the page up is only to create a folder for comments on the first comment made on each post. Seems sensible. Anything I do to the post will save it, and it updates fine. Only when I try to add a file does it break with the error message above?

It’s related to not having a comments folder; if I create a comment and then try to upload a file, it’s fine.

Any pointers. I guess I need something that says ignore the query if there are no comments.

When you upload an image to where? To the comments page? Or to the blog post?

As I mentioned above, this section should even show an error if the comments page is not present.

When uploading an image to the blog post.

I am too busy looking at pages with comments, which, of course, look fine. I see this when I look far enough down on a page with no comments. Not paying attention!

But yes I got your previous comment about it throwing an error and I can of course create, maybe I should just mass create it for all the existing posts as well to fix this?

Yes, that would make sense to get rid of this error message.

so you get this upload error message when uploading a file to this post image field?

However, this should go away once you create the comments page for existing and new pages. Don’t know why the uploader evaluates this query, though.

Yes, when uploading a postImage. I was confused and interested to understand why it had an issue only when uploading. No error message if you complete any other field and save, updates fine and no complaints about the query.

@texnixe. Apologies, I need a bit more help with this. Thinking it through, I need to create a child of blog posts called comments when a new blog post is created. I need the comments folder to be created before uploading an image, or the error will appear.

So is the best option to use a hook with page.create:before to achieve this or a different method?

Did you miss my link to a recipe above:

1 Like