Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user-defined shortcode components to be rendered #134

Merged
merged 1 commit into from
Oct 6, 2018

Conversation

christianwach
Copy link
Member

@christianwach christianwach commented Sep 25, 2018

Overview

Completes the work begun in #131

Before

WordPress plugins and CiviCRM Extensions which defined custom components for the [civicrm] shortcode found that the shortcode was not rendered.

After

Allow custom components to be defined for the [civicrm] shortcode and for those shortcodes to be rendered.

Technical Details

WordPress plugins and CiviCRM Extensions will need to use the civicrm_shortcode_preprocess_atts and civicrm_shortcode_get_data filters to add their component to the [civicrm] shortcode.

For example, consider the following bare-bones shortcode [civicrm component="my-component"]. We can extend the CiviCRM shortcode like this:

if ( function_exists( 'add_filter' ) ) {
	add_filter( 'civicrm_shortcode_preprocess_atts', 'extensionprefix_amend_args', 10, 2 );
	add_filter( 'civicrm_shortcode_get_data', 'extensionprefix_amend_data', 10, 3 );
}

/**
 * Filter the CiviCRM shortcode arguments.
 *
 * Add our component and a CiviCRM path.
 *
 * @param array $args Existing shortcode arguments.
 * @param array $shortcode_atts Shortcode attributes.
 * @return array $args Modified shortcode arguments.
 */
function extensionprefix_amend_args( $args, $shortcode_atts ) {

	// pass through if not our component
	if ( $shortcode_atts['component'] !== 'my-component' ) {
		return $args;
	}

	// add our custom component
	$args['component'] = 'my-component';

	// add a component path
	$args['q'] = 'civicrm/my-component/foo';

	return $args;

}

/**
 * Filter the CiviCRM shortcode data array.
 *
 * Let's add some arbitrary text to the pre-rendered shortcode's description to
 * indicate that this extension has something to say.
 *
 * @param array $data Existing shortcode data
 * @param array $atts Shortcode attributes array
 * @param array $args Shortcode arguments array
 * @return array $data Modified shortcode data
 */
function extensionprefix_amend_data( $data, $atts, $args ) {

	// pass through if not our component
	if ( $args['component'] !== 'my-component' ) {
		return $data;
	}

	// add some arbitrary text to pre-rendered shortcode
	$data['text'] = ts('Hello from My Component!');

	return $data;

}

This produces the following when the shortcode is rendered:

screen shot 2018-09-25 at 13 35 22

Comments

Related #112

@agileware-fj
Copy link

@christianwach We're currently reviewing internally an alternative callback-based approach, see CIVICRM-972 in our fork – our change is a little more involved, would be interested to know what you think about this approach though.

@christianwach
Copy link
Member Author

@agileware-fj Interesting approach which achieves pretty much the same result. Some thoughts off the top of my head:

My first impression is that this code seems to be replicating a subset of the functionality of apply_filters in a Drupal-esque way. Perfectly valid, of course, but somewhat redundant in my opinion.

Secondly, since preprocess_atts() is called on a per-shortcode basis, the civicrm_shortcode_components filter assembles the array of callables for every [civicrm] shortcode even though the method is only really interested in populating the $args array for the shortcode currently being processed. Not sure this matters much, but again, seems like redundant processing to me.

Thirdly, introducing an additional filter means that your technique diverges somewhat from the existing method by which extensions/plugins can add additional key/value pairs to the [civicrm] shortcode. It seems to me that keeping the same "code architecture" for these two tasks is worthwhile.

Fourthly, your approach would still need tweaking to allow the "Do not know how to handle this shortcode" text to be rendered when a component is not found. You'll notice that this doesn't render where it is.

Lastly, I always prefer to reduce complexity where possible. This PR merely rearranges existing code such that it works as expected rather than introducing new code and techniques.

Well, you did ask! :-)

@agileware-fj
Copy link

Thanks @christianwach – that makes sense and covers any questions I was going to ask about your PR as well :)

We'll defer to this since it's more idiomatic to WP.

+1 to merge this 👍

@kcristiano
Copy link
Member

  • (r-explain) Pass
  • (r-test) Pass
  • (r-code) Pass
  • (r-doc) Undecided
  • (r-maint) Pass
  • (r-run)Pass: tested with a new component based on example in PR. Worked as expected. Using an invalid shortcode returns the standard error. Existing shortcodes continue to work as expected,.
  • (r-user) Pass:
  • (r-tech) Pass:

Will need updates to the Shortcode documentation for https://docs.civicrm.org/sysadmin/en/latest/integration/wordpress/#using-shortcodes-to-publish-civicrm-content-in-wordpress

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants