@frontity/wp-comments

API reference of `@frontity/wp-comments` package

Comments package that adds integration for WordPress native comments.

Installation

Add the wp-comments package to your project:

npm i @frontity/wp-comments

Settings

In WordPress

In order to use this package, you will need to add a single line of configuration to your Wordpress installation:

add_filter( 'rest_allow_anonymous_comments', '__return_true' );

This filter enables creating comments for anonymous users via the REST API.

You can add this snippet directly in your theme's functions.php file or use a Code Snippets plugin.

In Frontity

This package doesn't have any configuration. It just needs to be added to the packages array in frontity.settings.js.

frontity.settings.js

export default {
  packages: ["@frontity/wp-comments"],
};

Usage

Getting comments of a post

We can use the @comments/:id handler to fetch all the comments of a specific post (actions.source.fetch("@comments/60")).

This data will be populated to the state so then we can do state.source.get("@comments/60") to get the ID's of these comments.

>> frontity.state.source.get("@comments/60/")
{
  "isFetching": false,
  "isReady": true,
  "link": "@comments/60/",
  "route": "@comments/60/",
  "query": {},
  "page": 1,
  "postId": 60,
  "items": [
    {
      "type": "comment",
      "id": 285
    },
    ...,

    {
      "type": "comment",
      "id": 274,
      "children": [
        {
          "type": "comment",
          "id": 276
        }
      ]
    },
  ...
  ],
  "total": 32,
  "totalPages": 1,
  "type": "comments",
  "isComments": true
}

With each ID we can get the details from the state at state.source.comment[id]`.

>> frontity.state.source.comment[285]
{
  "id": 285,
  "parent": 0,
  "author": 0,
  "author_name": "mario",
  "author_url": "",
  "date": "2020-07-31T11:30:25",
  "content": {
    "rendered": "<p>Let&#8217;s see it</p>\n"
  },
  "link": "/2016/the-beauties-of-gullfoss/comment-page-5/#comment-285",
  "type": "comment",
  "author_avatar_urls": {...},
  ...
  }
}"

Take a look at this diagram to learn more about this.

Sending new comments for a post

Every post with a comments form (to send comments) will use state.comments.forms[postId] to store the data of the comment and the submission status.

The data at state.comments.forms[postId] can be updated through the action actions.comments.updateFields().

>> frontity.actions.comments.updateFields(60, {
  content: "Hello world!",
  authorName: "Jamie",
  authorEmail: "jamie@gmail.com"
});
>> frontity.state.comments.forms[60].fields
{
  "content": "Hello world!",
  "authorName": "Jamie",
  "authorEmail": "jamie@gmail.com"
}

To send new comments you can use the action actions.comments.submit() which will send the data available at state.comments.forms[postId].fields.

The submission status will be stored under under state.comments.forms[postId] and if there are errors they will be available at the properties errorMessage, errorCode and errorStatusCode.

>> frontity.state.comments.forms[60]
{
  "fields": {
    "content": "Nice post!",
    "authorName": "Johnny",
    "authorEmail": "johnny@gmail"
  },
  "isSubmitting": false,
  "isSubmitted": false,
  "isError": true,
  "errorMessage": "Invalid parameter(s): author_email",
  "errorCode": "rest_invalid_param",
  "errorStatusCode": 400
}

Take a look at this diagram to learn more about this.

API Reference

Handlers

@comments/:id

This wp-source handler gets all comments published in the specified post (using its ID) and creates a tree structure with comments and their replies in the data object.

For example, to fetch all comments that belong to the post with ID 60 you would do:

await actions.source.fetch("@comments/60");

This would fetch all comments associated with that post and populate a data object inside the state (frontity.state.source.data["@comments/60/"]) with a tree structure of comments and replies, sorted by date (most recent first).

Have a look at the section Getting comments of a post to learn more

To access the fetched comments you could use something similar to this example:

const Comments = connect(({ postId, state }) => {
  // Get comments from state.
  const data = state.source.get(`@comments/${postId}`);

  // Utility to render comments and replies recursively.
  const renderComments = (items) =>
    items.map(({ id, children }) => (
      // You should define your own <Comment/> component!
      <Comment key={id}>
        {/* Render replies */}
        {children && renderComments(children)}
      </Comment>
    ));

  // Render comments if data is ready.
  return data.isReady ? renderComments(data.items) : null;
});

State

state.comments.forms[postId]

The wp-comments package stores a map of objects by post ID in state.comments.forms. Each of these objects represents one comment form. These objects are intended to be used as the state of React <form> components and contain the input values as well as the submission status. They have the following properties:

state.comments.forms[postId].fields

The following map of fields, representing the current field values that have been input in the form rendered in the given post. The content of this property is updated using the updateFields() action described later.

See the section Sending new comments for a post to learn more.

state.source.comment[id]

This is the portion of the state where the comments are stored after being fetched from the REST API or POSTed through the comments.submit() action.

Thanks to the handler @comments/:id you can get the ID's of the comments in a specific post.

With this list of ID's you can get the details for each one at state.source.comment[id].

See the section Getting comments of a post to learn more.

Example

const data = state.source.get(`@comments/${postId}`);

data.items
  .map(({ id }) => {
    // For each ID we can get the details of each comment at state.source.comment[id]
    const authorName = state.source.comment[id].author_name || "Anonymous";
    const content = state.source.comment[id].content.rendered;
    const date = state.source.comment[id].date;
    return { id, authorName, content, date };
  })
  .forEach(console.log);

Check a fully working example of this in this wp-comments demo.

Actions

actions.comments.updateFields()

Update the fields of the form specified by postId. This action simply updates what is stored in state.comments.forms[postId].fields with the given values.

If no fields are specified, the form fields are emptied.

These fields will be used by actions.comments.submit() when submitting the comment.

Syntax

(postId: number, comment: object) => Promise;

Arguments

actions.comments.updateFields(60, {
  content: "Hello world!",
});

See the section Sending new comments for a post to learn more.

actions.comments.submit()

This asynchronous action publishes a new comment for the post specified by postId. It submits the fields stored in the respective form (i.e. state.comments.forms[postId]) or the fields passed as a second argument. If fields are passed, those replace the current values stored in state.comments.forms[postId].fields.

After calling this action, you can access state.comments.forms[postId].isSubmitted property (described above) to determine the submission status.

Take into account that this action does not validate input. This means requests are made even though some fields are empty or have invalid values. If that is the case, WordPress will return an error message and populate the error status accordingly.

Syntax

(postId: number, comment: object) => Promise;

Arguments

// Submit the comment to the post with ID 60
// using the values stored in `state.comments.forms[60].fields`.
await actions.comments.submit(60);

// Submit the comment to the post with ID 60
// using the values passed as the second argument.
await actions.comments.submit(60, {
  content: "This is a comment example. Hi!",
  authorName: "Frontibotito",
  authorEmail: "frontibotito@frontity.com",
});

Take a look at the section Sending new comments for a post to learn more.

Demo

This short video demonstrates the usage of the @frontity/wp-comments package.

The project used in the video is available here.

Last updated