Skip to content

Developer Documentation

Justin Sternberg edited this page May 5, 2017 · 44 revisions

Welcome to our Developer Documentation!

As of our 3.0 release, there are dozens of actions and filters that developers may use to extend our plugin to suit their specific needs. If you find that the existing filters are insufficient for your use case, feel free to create an issue proposing a new filter or action and we're more than happy to consider it. If you've never used the Hooks (actions and filters) API in WordPress, you're in for a treat! If you're coming from a non-WordPress programming background - consider actions and filters (known collectively as hooks) to be a type of observer paradigm, an event bus, or a simplified pub-sub system.

Actions and filters are nearly identical, outside of a fairly small, but important, distinction. Actions expect to be hooked into with a function (or a method) that does not return a value. It may execute a function, spawn a process, or echo a string or HTML - but it should not return a value. Filters, on the other hand, expect a value to be returned. Not understanding these differences can cause loads of frustration for programmers that are new to WordPress.

For more information on this API in WordPress, visit the documentation.

Note: Examples below will use anonymous functions for brevity. You should likely provide named callbacks so that your callbacks can be unhooked/rehooked by other developers if needed.

Actions

do_action( "gc_{$this->direction}_items", $mapping );

This action fires upon syncing items with GatherContent.

The dynamic $this->direction can be either push or pull, resulting in a hook name of gc_pull_items or gc_push_items.

The $mapping variable is the actual post object, represented by a Mapping_Post object, which is a wrapper for the WP_Post object, decorated with additional data surrounding the mapping of this object.

Example

// Executes a specific function every time a WooCommerce product with a specific Gather Content template is pushed.
add_action( 'gc_push_items', function( $mapping ) {
	$template = $mapping->get_template();
	if ( 'product' === $mapping->post->post_type && 'special_product_template' === $template  ) {
		execute_special_function();
	}
} );

do_action( 'wp_async_save_post_gc_templates', $post_id, $post );

A hook similar to 'save_post', but fires asynchronously whenever the template-mapping posts are saved.


do_action( 'gc_mapping_pre_post_update', $post_data );

An hook that fires before a template-mapping post is updated.


do_action( 'gc_mapping_pre_post_create', $post_data );

An hook that fires before a template-mapping post is created.


do_action( 'wp_async_gc_pull_items', $mapping_post );

An asynchronous hook that compliments the 'gc_pull_items' hook.


do_action( 'wp_async_gc_push_items', $mapping_post );

An asynchronous hook that complements the 'gc_push_items' hook.


do_action( 'gc_sync_items_result', $result, $this );

Hook that fires after a sync has performed (either a push or a pull). The first parameter, $result is the result of the sync process, and will be either the post ID (for a pull), the GatherContent item (for a push), or a WP_Error object if a failure occurs. The second parameter, $this represents the Push or Pull object.


do_action( 'gathercontent_loaded' );

This action fires when plugin is first loaded, and before it is initiated. You can use this to load functionality that is GatherContent specific.

Example

// Executes when the GatherContent plugin is first loaded.
add_action( 'gathercontent_loaded', function() {
	// Include gathercontent modifications.
	require_once 'gathercontent-modifications.php';
} );

do_action( 'gathercontent_init', $general );

This action fires when the plugin is fully initiated, and only occurs in the admin. It is passed the GatherContent General object, which is a wrapper for all the GatherContent objects.

The below is a somewhat contrived example to remove the GatherContent metabox and functionality from the post-edit screen.

Example

// Executes when the GatherContent plugin is first initiated.
add_action( 'gathercontent_init', function( $general ) {
	// Need to check if the single_ui object is instantiated.
	// It won't be if the GatherContent connection settings have not been filled out.
	if ( $general->single_ui ) {
		remove_action( 'admin_enqueue_scripts', array( $general->single_ui, 'ui' ) );
	}
} );

do_action( 'gathercontent_field_type_option_underscore_template', $this );

This action is fired inside the mapping data types <select> element. It can be used to add additional options to the underscore template. It is used internally to register the options for each available field type in GatherContent, "Post Data", "Media", "Custom Fields", "Taxonomy/Terms", and "SEO" (if you have WordPress SEO installed). It is preferable that you instead use the gathercontent_register_field_types_handlers filter and follow the example listed for that filter.


do_action( 'gathercontent_field_type_underscore_template', $this );

Similar to gathercontent_field_type_option_underscore_template, but this action is fired after the mapping data types <select> element, so that additional field type <select> dropdowns can be output, which would be dynamically shown based on the mapping data types selected option.

Each field type internally hooks in here to add additional underscore templating.

It is preferable that you instead use the gathercontent_register_field_types_handlers filter and follow the example listed for that filter.

Filters

apply_filters( 'gc_prepare_js_update_data_for_posts', $post_updates );

Similar to "gc_prepare_js_data_for_$type", but on some occoasions is called when the Javascript models are asynchronously updated. The $post_updates value is an array of arrays, where each array will contain the following properties:

  • 'id' - The WordPress post ID.
  • 'status' - The GatherContent status object, if applicable.
  • 'itemName' - The GatherContent item name, if applicable.
  • 'updated_at' - The GatherContent item's updated_at value, if applicable.
  • 'current' - Whether the WordPress post is current with the GatherContent item.

apply_filters( 'gathercontent_localized_data', $args );

This filter allows passing of additional data to Javascript before wp_localize_script() is called. This filter is used internally. If adding your own javascript, you would likely instead use wp_enqueue_script() and wp_localize_script().


apply_filters( 'gc_admin_notices', $notices );

Register additional notices on the GatherContent admin pages. Filter the array and add your own array. Your notice array needs to contain at least the first 2 of the following fields:

  • 'id' - The ID of your notice box.
  • 'message' - The message.
  • 'type' - Optional. Default is 'error'. Can be 'error', 'updated', 'info', 'notice-info', or 'notice-warning'.

These are registerd and then passed to WordPress' native add_settings_error() function.

Example

add_filter( 'gc_admin_notices', function( $notices ) {
	$notices[] = array(
		'id'      => 'gc-custom-notice',
		'message' => 'Hello World',
		'type'    => 'info',
	);

	return $notices;
} );

apply_filters( 'gathercontent_importer_custom_field_keys', $meta_keys );

By default, the values for the "Custom Fields" dropdown are populated by a list of all the unique meta keys in the postmeta database table. You can add your values with this filter, even if they haven't yet been added to the database.

Example

add_filter( 'gathercontent_importer_custom_field_keys', function( $meta_keys ) {
	$meta_keys[] = '_gccuston_first_name';
	$meta_keys[] = '_gccuston_last_name';

	return $meta_keys;
} );

apply_filters( 'gathercontent_importer_custom_field_keys_blacklist', $keys );

There are several meta keys which GatherContent does not want the user to be able to map custom fields to, mostly meta keys which are used internally by the GatherContent plugin. If you wish to blacklist additional meta keys, you can do so with this filter. Keep in mind you need to add to the array and the array key needs to be the meta_key, and the array value can be anything.

Example

add_filter( 'gathercontent_importer_custom_field_keys_blacklist', function( $meta_keys_blacklist ) {
	$meta_keys_blacklist['_gccuston_dont_show'] = 1;

	return $meta_keys_blacklist;
} );

apply_filters( 'gc_media_location_options', $options );

Register additional media locations for the Media locations dropdown. Default options are "Featured Image", "Excerpt Image(s)", "Gallery", and "Attachment(s)". You will be responsible for hooking in during the pull process to process the media according to the location, possibly using the gc_media_replacements filter, and the like.

Example

add_filter( 'gc_media_location_options', function( $options ) {
	$options['gccustom'] = 'GatherContent Image Field';
	
	return $options;
} );

apply_filters( 'gathercontent_register_field_types_handlers', $this->core_types );

Register additional field-type handlers. Must pass back an object that uses the GatherContent\Importer\Admin\Mapping\Field_Types\Type interface and the GatherContent\Importer\Admin\Mapping\Field_Types\Base class should be extended.

Below is an example which registers a custom meta handler (similar to how the WPSEO handler works). You would likely put in a separate file, something like my-custom-gc-handler.php.

There are 4 important elements:

  • The $type_id property. This defines where the data gets stored, and gets split on --, so in our case, we want to store to post-meta.
  • The $option_label property. Just as it sounds, it defines the <option> label for the 'gathercontent_field_type_option_underscore_template' filter. If you need to use WordPress' translation functions (__()), you would need to define this in the __construct() method.
  • The $supported_types. This defines which type of GatherContent fields are allowed to be mapped to this field type. The option will not show for fields which are not of these types.
  • The underscore_template() method, which is required, and defines the underscore template for the secondary <select> element, which shows when your $type_id/$option_label is selected from the first <select> dropdown. In the example, we're using several methods we've inherited from the GatherContent\Importer\Admin\Mapping\Field_Types\Base class.

Example

<?php
use GatherContent\Importer\Admin\Mapping\Field_Types\Base;
use GatherContent\Importer\Admin\Mapping\Field_Types\Type;
use GatherContent\Importer\Views\View;

class My_Custom_GatherContent_Type_Handler extends Base implements Type {

	/**
	 * This will be of the `wp-type-meta` type, but have an additonal id of `gccustom`.
	 *
	 * @var string
	 */
	protected $type_id = 'wp-type-meta--gccustom';

	/**
	 * Creates an instance of this class.
	 */
	public function __construct() {
		$this->option_label = 'GatherContent Custom Fields';
	}

	/**
	 * Array of supported GatherContent template field types.
	 *
	 * @var array
	 */
	protected $supported_types = array(
		'text',
		'text_rich',
		'text_plain',
	);

	public function underscore_template( View $view ) {
		$options = array(
			// key is the meta key where the mapped data will be saved.
			// Value is the option label value.
			'_gccuston_first_name' => 'First Name',
			'_gccuston_last_name' => 'Last Name',
		);

		?>
		<# if ( '<?php $this->e_type_id(); ?>' === data.field_type ) { #>
			<select class="wp-type-value-select <?php $this->e_type_id(); ?>" name="<?php $view->output( 'option_base' ); ?>[mapping][{{ data.name }}][value]">
				<?php $this->underscore_options( $options ); ?>
				<?php $this->underscore_empty_option( __( 'Do Not Import', 'gathercontent-import' ) ); ?>
			</select>
		<# } #>
		<?php
	}

}

add_filter( 'gathercontent_register_field_types_handlers', function( $types ) {
	$types[] = new My_Custom_GatherContent_Type_Handler;

	return $types;
} );

apply_filters( "gathercontent_importer_section_{$id}", $section, $this );


apply_filters( "gathercontent_importer_field_{$this->id}_{$id}", $field, $this );


apply_filters( "{$this->option_name}_default_options", $this->options );


apply_filters( 'gc_get_element_value', $val, $this->element, $this->item );


apply_filters( "gc_can_append_{$field}", $can_append, $this->element, $this->item );


apply_filters( 'gc_only_update_if_newer', true );


apply_filters( 'gc_media_objects', $attachments, $post_data );


apply_filters( 'gc_update_wp_post_data', $post_data, $this );

Allows updating/modifying the array of post data when a GatherContent pull takes place. This hooks only runs when mapped WordPress item already exists and is being updated. To update the post data instead/also when the post is created for the first time, you'll also need to hook into 'gc_new_wp_post_data';

function my_prefix_maybe_update_post_meta( $post_data, $pull ) {
	if ( ! empty( $post_data['meta_input']['some_meta_key'] ) ) {
		$post_data['meta_input']['some_meta_key_supporting_data'] = 'some value';
	}

	return $post_data;
}
add_filter( 'gc_update_wp_post_data', 'my_prefix_maybe_update_post_meta', 10, 2 );	
add_filter( 'gc_new_wp_post_data', 'my_prefix_maybe_update_post_meta', 10, 2 );	

apply_filters( 'gc_new_wp_post_data', $post_data, $this );

See documenation for 'gc_update_wp_post_data';


apply_filters( 'gc_get_element_terms', $terms, $this->element, $this->item );


apply_filters( 'gc_sanitize_meta_field', $this->element->value, $this->element, $this->item );


apply_filters( 'gc_sanitize_media_field', $this->element->value, $this->element, $this->item );


apply_filters( 'gc_content_image', $img, $media, $attach_id, $post_data );


apply_filters( 'gc_content_gallery_shortcode', $shortcode, $gallery_ids, $post_data );


apply_filters( 'gc_media_replacements', $replacements, $attachments, $post_data );


apply_filters( 'gc_replace_attachment_data_on_update', false, $attachment );


apply_filters( 'gc_update_gc_config_data', $config, $this );


apply_filters( "gc_get_{$post_column}", $value, $this );

This filter allows you to modify the WordPress post data before it is pushed to GatherContent. The dynamic portion, $post_column, represents the column in the post table being transferred to GatherContent. The first parameter, $value, is the value of that post data column, and the second parameter, $this, is the Push object. Be sure to rename it in your filter, as using $this will throw errors. In the example below, it's named $gc_push.

Example

// Fix mentions of GatherContent which are not title-cased before pushing to GatherContent.
add_filter( 'gc_get_post_content', function( $value, $gc_push ) {
	$value = str_replace( 'gathercontent', 'GatherContent', $value );
	return $value;
}, 10, 2 );

apply_filters( 'gc_field_type_names', $types );

This filter allows you to modify the GatherContent field-types nice names.

Example

add_filter( 'gc_field_type_names', function ( $names ) { 

	$names['text_rich']  = 'Text - Rich'; // Default is 'Rich Text'.
	$names['text_plain'] = 'Text - Plain'; // Default is 'Plain Text'.

	return $names;
} ); 

apply_filters( "gc_template_args_for_{$this->template}", $this->args, $this );

The GatherContent plugin uses template views to handle outputting markup. Using this filter, you can modify the arguments sent to those templates. $this refers to the View object.

Example

add_filter( 'gc_template_args_for_tmpl-gc-mapping-defaults-tab', function ( $args ) { 

	// Get all non-public post-types and add them to the list of available mapping post types.
	$post_types = get_post_types( array( 'public' => false ), 'objects' );

	foreach ( $post_types as $type ) {
		$args['post_type_options'][ $type->name ] = $type->labels->singular_name;
	}

	return $args;
} ); 

apply_filters( "gc_prepare_js_data_for_$type", $args, $type, $item );

Filters the data being sent to the JavaScript Backbone collection for each WordPress post and GatherContent item. You would likely only use this filter if you wanted to send additional post or item-related data to JavaScript.

The dynamic $type can be either post or item, resulting in a hook name of gc_prepare_js_data_for_post or gc_prepare_js_data_for_item. The $type variable is also provided as the 2nd parameter to the filter.

The $args variable is the array of data for that post or item, prepared for JavaScript. The $item variable will be the GatherContent item or null. It will only be null if using the gc_prepare_js_data_for_post filter, and that particular post does not have an associated GatherContent item.

Example

add_filter( 'gc_prepare_js_data_for_post', function( $args, $type, $item ) {

	// Send the post date to JavaScript.
	$args['post_date'] = get_the_time( 'm/d/Y', $args['post_id'] );
	
	return $args;
} );

apply_filters( 'gathercontent_settings_view_capability', 'publish_pages' );

This filter allows you to change the capability that a user must have in order to view the GatherContent settings page. The default is 'publish_pages'.

Example

// Change so that only users with the 'manage_options' capability
// can view the GatherContent settings pages, instead of any users
// with the 'publish_pages' capability, the default.
add_filter( 'gathercontent_settings_view_capability', function( $general ) {
    return 'manage_options';
} );

--

Clone this wiki locally