wordpress-sdk icon indicating copy to clipboard operation
wordpress-sdk copied to clipboard

Allow to embed the account, contact and pricing pages inside other pages

Open daigo75 opened this issue 4 years ago • 0 comments

🚀 feature request

Not all plugins can use sub-menus or Freemius' specific tabs structure to show the account, contact and pricing pages. It would be good to have some way to embed these pages in another page, without having to implement specific menu or HTML structures. This could be achieved using shortcodes.

Description

My plugins use an architecture that allows to show a settings page that already contains tabs. The tabs are rendered using jQuery UI and are part of the same page (i.e. clicking on a tab doesn't reload the page and doesn't point to another URL).

Since I can't rewrite the rendering of the existing settings pages, I tried to find a way to embed the Freemius account, contact and pricing pages by using some custom shortcodes, which call the Freemius SDK functions directly. This approach gives different results, depending on the rendered page:

1. Account page

Rendering logic

$fs_integration->_account_page_load();
$fs_integration->_account_page_render();

Result The page is displayed correctly, but it doesn't work, because it contains several <form> elements. Due to that, it can't be embedded inside another <form> element, such as the settings page rendered by my framework.

Possible solution: if the Account page could be rendered inside an iframe, like the other two, that would allow it to keep using its sub-forms, even when it's embedded inside another form.

2. Contact page

Rendering logic

Freemius::_clean_admin_content_section();
$fs_integration->_contact_page_render();

Result The page is displayed correctly and it works as expected.

3. Pricing page

Rendering logic

Freemius::_clean_admin_content_section();
$fs_integration->_pricing_page_render();

Result The page is rendered correctly, but in the wrong place and it doesn't work as expected. The bugs are the following:

  1. The Pricing page tries to append a frame to the target element #fs_frame. The Contact page uses the same target. If one wishes to render the Contact page in one location (e.g. under a jQuery tab, see https://jqueryui.com/tabs/) and the Pricing page in another location, on the same page, that won't work, because both frames are rendered under the same target element. Possible solution: use two different IDs for the target element of the iframe, such as fs_frame_contact and fs_frame_pricing. This should allow to render the two iframes independently.
  2. The Checkout logic doesn't work, because it takes the wrong menu slug. The issue seems to be due to the following logic, found inside the Pricing page iframe:
FS.Context.plugin({
  id          : '6708',
  slug        : 'my-plugin-slug',
  unique_affix: 'my-plugin-slug',
  menu_slug   : page.substring(0, page.length - ('-pricing').length)
});

The code tries to determine the menu slug by taking a substring from the page URL argument. It looks like the original idea is that the page argument is something like my-plugin-slug-pricing, therefore the substring operation would return my-plugin-slug. Unfortunately, this doesn't work if the Pricing page is embedded inside another page, with a different page argument. For example, one of my plugins uses a URL like /wp-admin/admin.php?page=aelia_cs_options_page. The script extracts the menu_slug as aelia_cs_opti, then it appends -pricing to it, resulting in the value aelia_cs_opti-pricing, which is a "garbage" value. Due to that, clicking on any upgrade button on the Pricing page results in an error message "Sorry, you are not allowed to access this page." (which means that the page doesn't exist, which is correct).

I can't suggest a solution for this issue. The content of the Pricing page comes from the iframe, which relies on assumption that the page argument contains the plugin slug, followed by -pricing. This is not the case, and there is no way to pass the correct menu slug to the iframe from the calling page. Perhaps it could make sense to just take the plugin slug, instead of the menu page, as that's the value that the Pricing page scripts expect, anyway.

Describe the solution you'd like

Ideally, I would like to see a way to render the account, contact and pricing pages anywhere, without having to rely on direct calls to the Freemius framework. Also, it would be ideal to decouple the pages from the specific implementation of the settings page, so that they can work no matter what the page URL, and its arguments are.

Describe alternatives you've considered

I tried the default options offered by the Freemius SDK. The sub-menus won't work, because a customer can have multiple plugins installed, cluttering the Admin section with menu entries.

The tabs won't work, either, because the settings page is not designed to work the way the Freemius SDK handles tabs. Also, the tabs feature seems to be affected by a couple of bugs, which I reported earlier:

  • https://github.com/Freemius/wordpress-sdk/issues/495
  • https://github.com/Freemius/wordpress-sdk/issues/494

daigo75 avatar May 24 '21 20:05 daigo75