Make the backend URL a global setting

Nice trick! Maybe we could even release a isDerived() tool based on that code :slightly_smiling_face:

const isDerived = (obj, propName) =>
  typeof Object.getOwnPropertyDescriptor(obj, propName).value === "function";

Regarding the code, I think you still have to check inside state.source.api if state.source.url is from a subdomain.wordpress.com site because you cannot rely on state.wpSource.isWpCom for that:

const api = ({ state }) => {
  // Is it a WordPress.com site with a custom domain?
  const isCustomWpCom =
    !isDerived(state.wpSource, "isWpCom") && state.wpSource.isWpCom;
  // Is it a free WordPress.com site using a subdomain.wordpress.com domain?
  const isFreeWpCom = /^https:\/\/(\w+\.)?wordpress\.com/.test(
    state.source.url
  );

  if (isCustomWpCom || isFreeWpCom) {
    const { hostname } = new URL(state.source.url);
    return addFinalSlash(
      `https://public-api.wordpress.com/wp/v2/sites/${hostname}`
    );
  }

  return addFinalSlash(
    addFinalSlash(state.source.url) + state.wpSource.prefix.replace(/^\//, "")
  );
};

Donā€™t you think?

yep, youā€™re right about that and thatā€™s a clearer implementation as well! :slight_smile:

Awesome. I have just opened a FD for the isDerived util :slightly_smiling_face:

We have a lot of cases so I have made a table to make sure we donā€™t forget any of them and we add tests for all of them.

state.frontity.url state.source.url state.source.api state.wpSource.isWpCom
Free WP com - configured by state.source.url Set by the user: final-domain.com Set by the user: sub.wordpress.com Derived from state.source.url: sub.wordpress.com/wp-json Derived from state.source.api: true
Free WP com - configured by state.source.api Set by the user: final-domain.com Derived from state.frontity.url: final-domain.com Set by the user: public-api.wordpress.com/wp/v2/sites/sub.wordpress.com Derived from state.source.api: true
Personal and Premium WP com - configured by state.source.url and state.wpSource.isWpCom Set by the user: final-domain.com Set by the user: final-domain.com Derived from state.source.url: public-api.wordpress.com/wp/v2/sites/final-domain.com Set by the user: true
Personal and Premium WP com - configured by state.source.url and state.source.api Set by the user: final-domain.com Set by the user: final-domain.com Set by the user: public-api.wordpress.com/wp/v2/sites/final-domain.com Derived from state.source.api: true
Personal and Premium WP com - configured by state.source.api Set by the user: final-domain.com Derived from state.frontity.url: final-domain.com Set by the user: public-api.wordpress.com/wp/v2/sites/final-domain.com Derived from state.source.api: true
WP org and Business WP com - configured by state.source.url Set by the user: final-domain.com Set by the user: wp-domain.com Derived from state.source.url: wp-domain.com/wp-json Derived from state.source.api: false
WP org and Business WP com - configured by state.source.api Set by the user: final-domain.com Derived from state.frontity.url: final-domain.com Set by the user: wp-domain.com/wp-json Derived from state.source.api: false

You can use https://www.tablesgenerator.com/markdown_tables if you want to edit the table. I think copy/pasting shoud work.

Last thing: WordPress.com has 5 plans (https://wordpress.com/pricing/). These are the relations with the configuration:

  • Free: Free WP com
  • Personal and Premium: Personal and Premium WP com
  • Business: WP org and Business WP com (these sites have a final-domain.com/wp-json so they can act as regular WP org sites).
  • eCommerce: I have no idea, to be honest.
1 Like

Does this change have any implications for libraries.source.api.init? Do we need to make any changes to the documentation there?

https://docs.frontity.org/api-reference-1/wordpress-source#libraries-source-api-init

I donā€™t understand some of the cases you mentioned on the table.

When you talk about these three specifically:

  • Free WP com - configured by state.source.api
  • Personal and Premium WP com - configured by state.source.api
  • WP org and Business WP com - configured by state.source.api

What do you mean exactly when you say that state.source.url is derived from state.frontity.url? Shouldnā€™t it be derived from state.source.api?

I thought state.source.url should point to the WordPress instance, not the Frontity one. Except for the embedded mode: in that case, I guess state.frontity.url and state.source.url would be the same.

I donā€™t know why that API is documented, to be honest. That init is internal and not meant to be used by other packages, only by the source package.

In this specific case, we even have plans to remove it in the not so distant future. So could you please remove it from the docs? :slightly_smiling_face:

I think we never thought that state.source.url could be derived from state.source.api if state.source.api is defined by the user (not derived) but I guess that with Michalā€™s isDerived function we can do that.

Actually, that would mean that state.source.url is backward compatible and safer to use than it is today.

Is it feasible technically to do it?

Yup, it is. I already wrote the tests for that and all of them are passing. So, yeah. :+1:

Ok, is this table correct then?

state.frontity.url state.source.url state.source.api state.source.isWpCom
Free WP com - configured by state.source.url Set by the user: final-domain.com Set by the user: sub.wordpress.com Derived from state.source.url: public-api.wordpress.com/wp/v2/sites/sub.wordpress.com Derived from state.source.api: true
Free WP com - configured by state.source.api (backward compatibility only) Set by the user: final-domain.com Derived from state.source.api: sub.wordpress.com Set by the user: public-api.wordpress.com/wp/v2/sites/sub.wordpress.com Derived from state.source.api: true
Personal and Premium WP com - configured by state.source.url and state.wpSource.isWpCom Set by the user: final-domain.com Set by the user: final-domain.com Derived from state.source.url: public-api.wordpress.com/wp/v2/sites/final-domain.com Set by the user: true
Personal and Premium WP com - configured by state.source.url and state.source.api (backward compatibility only) Set by the user: final-domain.com Set by the user: final-domain.com Set by the user: public-api.wordpress.com/wp/v2/sites/final-domain.com Derived from state.source.api: true
Personal and Premium WP com - configured by state.source.api (backward compatibility only) Set by the user: final-domain.com Derived from state.source.api: final-domain.com Set by the user: public-api.wordpress.com/wp/v2/sites/final-domain.com Derived from state.source.api: true
WP org and Business WP com - configured by state.source.url Set by the user: final-domain.com Set by the user: wp-domain.com Derived from state.source.url: wp-domain.com/wp-json Derived from state.source.api: false
WP org and Business WP com - configured by state.source.api (backward compatibility only) Set by the user: final-domain.com Derived from state.source.api: wp-domain.com Set by the user: wp-domain.com/wp-json Derived from state.source.api: false

I am not taking into account state.wpSource.api and state.wpSource.isWpCom now.

Awesome. Did you implement isDerived already? isDerived util

I have done a graph of the logic, but I would like to review this with you. Let me know whenever you can and we will jump in a quick call.

I would like to also review with you:

  • state.wpSource.api
  • state.wpSource.isWpCom

Ok, we have carefully reviewed the logic and I think we got it right this time :slightly_smiling_face:

Not only that, but thanks to @mmczaplinskiā€™s isDerived function and @David who noticed that we can use that to derive state.source.url from state.source.api, now state.source.url is backward compatible and safe to use in any package!! :tada::tada:.

Awesome work guys :slightly_smiling_face:

Thanks also to @mburridge for bringing into our attention the problem with wordpress.com sites that have custom domains but canā€™t use /wp-json.

This is the final logic @david is implementing:

@luisherranz Iā€™ve created this issue.

1 Like

I think that there is a small error in the table that youā€™ve created @luisherranz. Iā€™ve explained it in the Loom.

I just wanted to clarify this because the DevRel team is currently documenting the feature and I want to make sure that we really nail it :slight_smile:

Also, think that the crucial bit that should be documented is which settings the user will need depending on what kind of hosting they are on. I think that the final table should look like:

Free, Personal or Premium wordpress.com Business wordpress.com or wp.org
needs state.source.url YES YES
needs state.source.api should either set this NO
needs state.wpSource.isWpCom or set that or both NO

Iā€™ve linked here from the PR to add docs for state.source.url because it was not 100% clear to the DevRel team from the Discussion above which information should be documented and which one was implementation detail.

Iā€™m not 100% sure I got the problem you see. To me the table is right. Iā€™ve made a video explaining it in more depth: Loom | Free Screen & Video Recording Software

Let me know if that is correct or there is still something I am not getting :slightly_smiling_face:

For me the table for the docs should be something like this:

Free wordpress.com Personal or Premium wordpress.com Business wordpress.com or wp.org
needs state.source.url YES YES YES
needs state.wpSource.isWpCom NO YES NO

Yikes, youā€™re correct @luisherranz, sorry for the confusion! Iā€™ve missed that weā€™re checking if itā€™s a free Wordpress dot com site in here as you pointed out.

However, I think that I wrongly thought that because the state.source.api in the first case should also be public-api.wordpress.com/wp/v2/sites/sub.wordpress.com.:point_down:


This table is also the correct one then. @juanma Could you take a look and see if we need to update the docs according to this? The table that I have made is superseded by the one that Luis made.

You are right, that cell was wrong. I have fixed it now, sorry for the confusion :slightly_smiling_face::+1:

1 Like

Awesome, thanks! :smiley:

1 Like