Iframe: Add support for WordPress
(I got a PM from someone considering implementing the Iframe-WP integration -- looking for pointers. I don't think there's an existing issue, so I'll just put the notes here.)
Intro
There are a couple ways to attack this. They trade-off between development-risk and server-compatibility:
-
Top Level
/iframe.php
: In this approach, you have more examples to inspect/imitate, so I'd be more optimistic about development. But it requires the site-builder have full control over their web-site. -
Pre-Existing Entrypoint: In this approach, you find some other way to make an existing entry-point (
index.php
) work. The examples aren't as clear. But if it works, then it would have broader compatibility (espwpengine
).
In both cases, the actual difficulty will depend on obscure aspects of the CMS's APIs for session/cookie management.
(Note: If you asked Kevin and Christian -- who specialize in WP -- they would want to go straight to the harder version. I'm more circumspect; after taking deep-dive into D7/8/9/10, BD, and J -- I know that all those platforms put session-management in a place that's hard to control. Of course, WP API's could be better. But since that's an unknown, I have to describe both contingencies.)
/iframe.php
Approach 1: Top Level (This one is "easier" in the sense that there are working examples to compare. However, the actual difficulty will depend a lot on how the CMS APIs are shaped.)
-
Step 1: Understand the role of
iframe.php
.- This already works in Drupal+Backdrop, so trying it there is a good comparison.
- One can use the video and/or the README to get oriented.
-
Step 2: Enable
iframe
extension on WordPress. Check system-status. It shows this error:The IFrame Connector cannot be deployed. The template class ("Civi\Iframe\EntryPoint\WordPress") is missing.
-
Step 3: So create/update
WordPress.php
in the relevant folder.Formally speaking, you want to write a class which:
- Defines a
main()
method to do all its work. - Bootstraps the CMS.
- It should use a new/different cookie-name for sessions.
-
It should allow IFRAME loading. (Do not let CMS set
X-Frame-Options:
header.)
- Bootstraps Civi.
- It should set some constants so that Civi knows it's in an iframe.
- Delegates to
Civi::service('iframe.router')
.
But I find it easier to go by examples. Some good references:
- The existing templates for
Backdrop
,Drupal
,Drupal8
. - The main PHP entry-points in the CMS (
index.php
et al). - In Google or ChatGPT, use a prompt like
make a top level php file that bootstraps wordpress
- Defines a
-
Step 4: Install the
iframe.php
from the template. There should be a button in "System Status" screen. Or you can use CLI:cv api4 Iframe.installScript
-
Step 5: Try to use some CiviCRM pages, e.g.
-
/iframe.php/civicrm/event/info?reset=1&id=1
, or -
/iframe.php/civicrm/contribute/transact?reset=1&id=1
,
-
-
Step 6: There will probably be bugs. Go back to Step 3 -- tweak the template, then repeat.
The real essence of this is "Step 3" (esp booting CMS while controlling cookie policy -- then delegating to iframe.router
).
The reason for all the other stuff -- /iframe.php
, template-files, etc -- is that it's the most effective way to exercise control over session/cookie policy in many PHP frameworks. (The sessions+cookies in /iframe.php
should be separate from the ones in regular page-views.)
However, some WordPress hosts (eg wpengine
) don't allow you to put PHP files in the web-root. So this way won't work everywhere.
Approach 2: Other Iframe Entrypoint
(This is harder in the sense that there is less of a roadmap. However, the actual difficulty will depend a lot on how the CMS APIs are shaped.)
WordPress may be in a different position than Drupal/Backdrop/Joomla -- their session/cookie APIs may work differently. It already has a few different entry-points (index.php
, /wp-admin/
, /wp-rest
). You may be able to find some mix of events+APIs that work sufficiently on one of these entry-points.
To make such an arrangement:
-
IFRAME requests will go through the pre-existing entry-point. The URL formula will look different. I don't know what that be. Hypothetically...
/index.php?_civiIframe=1&route=civicrm/event/info&id=1&reset=1 /wp-json/civi-iframe/civicrm/event/info?id=1&reset=1
Whatever the formula is, it will be a different from any existing page.
-
When processing that request, it should use different cookie/session than regular requests.
-
When processing that request, it should setup
civicrm_url_defaults
andiframe.router
(like the earlier templates). -
The URL generator for Civi-Iframe will need to know about this formula.
-
The ScriptManager will need to be turned off WP. (No need for site-builders to install
/iframe.php
.)