Questions about adding custom pattern handlers

Hi,
Iā€™m really interested in using Frontity to build a new front, but the site is heavily customized with lots of rewrites, filters etc, so there are a few kinks I need to make sure that I can work out before I can get started on a theme.

Iā€™ve been trying to add a custom path pattern, but I have run in to some issues and I canā€™t seem to find my answer in the documentation.

I used the example from the documentation and edited it to fit my purpose:

init: ({ libraries }) => {
        libraries.source.handlers.push({
          name: "country-info",
          priority: 1,
          pattern: "/:slug",
          func: async ({ route, params, state, libraries, force }) => {
            const response = await libraries.source.api.get({
              endpoint: "country-info",
              params: { slug: params.slug },
            });

            const [countryInfo] = await libraries.source.populate({
              response,
              state,
              force,
            });

            Object.assign(state.source.data[route], {
              id: countryInfo.id,
              type: countryInfo.type,
              isPostType: true,
              isCountryInfo: true,
            });
          },
        });
      },

The handler works fine when the slug matches an existing post, but when I enter a non-existing slug I get this Error:

  TypeError: Cannot read property 'id' of undefined
      at Object.func (webpack-internal:///./packages/mars-theme/src/index.js:14:558)
      at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:182:7)

And the site only displays ā€˜Internal Server Errorā€™.

So hereā€™s what Iā€™d like to know:

  1. What would you recommend that I check for in the response to see if a post was found or not?

  2. If no posts where found, what should I do to generate a proper 404 error and make the 404 page show up?

  3. Letā€™s say I get a result that I for some reason want to ignore on the front end, how can I make Frontity move on and try to match the next pattern in the priority chain? (As if the pattern didnā€™t match)

Also, thank you for making this framework. I love working with WordPress and I love working with React. I have often used React apps in websites I built in WordPress, but your framework is exactly what I have been looking for! Keep up the good work!

Fred

Hi Fred! Iā€™m happy that youā€™re enjoying working with Frontity! :slight_smile:

As to your questions:

  1. Under the hood, source.api.get just makes a regular http request to the WP REST API using fetch, and gives you a Response back. You can check for whatever you like then, depends on what you are looking for :slight_smile:

  2. This is a good question and I donā€™t have an official answer for you because we donā€™t have an ā€œofficialā€ and documented way of doing that. In the framework, we are catching the errors and then checking if itā€™s an internal error or an error that was thrown by the framework (e.g. because one of the handlers encountered a 404).

You could follow a similar strategy and if your condition fails (e.g. post was not found) you can assign an ā€œerror objectā€ to your current route with something like:

const response = await libraries.source.api.get({
   endpoint: "country-info",
   params: { slug: params.slug },
});

if (!response.ok) {
  const errorData = {
    isError: true,
    isReady: true,
    isFetching: false,
    is404: true,
    errorStatus: 404,
    errorStatusText: 'Page Not Found',
  };
  source.data[link] = errorData;
}

Then your UI should just show the 404 page

  1. If fetch the data from the WP REST API with libraries.source.api.get() but you donā€™t call libraries.source.populate() and donā€™t assign anything to state.source.data like mentioned in the example, the handler will not really do anything useful and move on to process the handler with the next highest priority! :slight_smile:

Hope this helps!

2 Likes

Not really, right now only one handler is executed per fetch. I have a proposal to change that for version 2.0 of source because it seems to be a recurring problem.

What we are doing right now is handle that logic inside the handler itself, like this: https://github.com/frontity/frontity/blob/dev/packages/wp-source/src/libraries/handlers/postType.ts#L20-L35

I hope that helps.

2 Likes

Whoops, sorry youā€™re right @luisherranz I did not know that.

@pommes.fritte Please follow Luisā€™s advice on point 3., heā€™s one of the original designers of the framework :slight_smile:

1 Like

Thank you for the quick reply, sorry for the slow response!

Ok, I should be able to make it work somehow then. I quickly tried your example of checking if the response status is ok, but I quickly realized that WordPress doesnā€™t actually send a 404 when thereā€™s no matching post, just a normal 200 with an empty array. So Iā€™ll have to parse the data and look for the size of the array I suppose.

Ok, Iā€™ll try just setting the error manually!

I see. I guess I could just combine all overlaping handlers into one big handler. It should be possible in one request if I query multiple post types at the same time.
Iā€™m glad to hear your working on a solution though! It would be nice to just be able to call next_path() or maybe return false to make the source library jump to the next path in line. (It would similarly be nice to have an equally simple way of letting frontity know that it the requested path is a 404. Like calling not_found(), returning a null or whatever it might be.

Thanks for all the help guys!

1 Like

Iā€™ll let you know once I finish the proposal so you can give us feedback :slightly_smiling_face:

3 Likes