Best Practices

Best Practices

1. Follow an Object-Oriented design pattern.

You should use a singleton to ensure that your add-on works properly with WP All Import's WP-CLI integration. A singleton is a class that is limited to a single instance.

Example - ensuring a class has only a single instance

static public function get_instance() {
if ( self::$instance == NULL ) {
self::$instance = new self();
}
return self::$instance;
}

Be sure to instantiate the Rapid Add-On when the class is constructed:

$this->add_on = new RapidAddon( 'Yoast SEO Add-On', 'yoast_seo_add_on' );

Here's an overview showing how it all fits together:

/*
Plugin Name: WP All Import Yoast SEO Add-On
Description: A complete example add-on for importing data to certain Yoast SEO fields.
Version: 1.0
Author: WP All Import
*/

include "rapid-addon.php";

final class Yoast_SEO_Add_On {

protected static $instance;

protected $add_on;

static public function get_instance() {
if ( self::$instance == NULL ) {
self::$instance = new self();
}
return self::$instance;
}

protected function __construct() {

// Define the add-on
$this->add_on = new RapidAddon( 'Yoast SEO Add-On', 'yoast_seo_add_on' );

// Add UI elements to the import template
$this->add_on->add_field( 'yoast_wpseo_title', 'SEO Title', 'text' );

// This tells the add-on API which method to call
// for processing imported data.
$this->add_on->set_import_function( [ $this, 'import' ] );

// This registers the method that will be called
// to run the add-on.
add_action( 'init', [ $this, 'init' ] );
}

// Tell the add-on to run, add conditional statements as needed.
public function init() {

$this->add_on->run();

}

// Add the code that will actually save the imported data here.
public function import( $post_id, $data, $import_options ) {

}
}

Yoast_SEO_Add_On::get_instance();

2. Make the add-on run only when necessary.

Your add-on should only run when the user is importing to the theme or post types supported by your add-on.

Otherwise, your add-on』s import function would save data in the database when the user is doing an import that isn』t making use of your add-on.

Specify when your add-on runs using the run function.

This code is placed in the 'init' method as shown in section 1 above.

Example A – only when certain plugins are active

// This approach is needed when you need one OR another plugin active.
if ( function_exists('is_plugin_active') ) {
// Only run this add-on if the free or pro version of the Yoast plugin is active.
if ( is_plugin_active( 'wordpress-seo/wp-seo.php' ) || is_plugin_active( 'wordpress-seo-premium/wp-seo-premium.php' ) ) {
$this->add_on->run();
}
}

// This approach works when you need one or more plugins active at the same time.
// Only run this add-on if BOTH the premium version of the Yoast plugin and WP All Export are active.
$this->add_on->run(array(
'plugins' => array(
'wordpress-seo-premium/wp-seo-premium.php',
'wp-all-export/wp-all-export.php'
)
));

}

Example B – only when importing to 「listing」 Custom Post Type

$this->add_on->run(
array(
"post_types" => array( "listing" ),
)
);

Example C – only when 「Twenty Fourteen」 OR 「Twenty Fifteen」 themes are activated

$this->add_on->run(
array(
"themes" => array( "Twenty Fourteen", "Twenty Fifteen" )
)
);

Example D – only when importing to 「post」 OR 「page」 Custom Post Type AND when 「Max Estate」 theme is activated AND when the "Max Estate Helper" plugin is activated

$this->add_on->run(
array(
"themes" => array( "Max Estate" ),
"post_types" => array( "post", "page" ),
"plugins" => array( "Max Estate Helper" )
)
);

Example E – run the add-on always

$this->add_on->run();

3. Make the add-on respect the user』s 「Choose which data to update…」 Import Settings.

On future runs of the same import, users can choose to not update Custom Fields, Images, and more.

Choose which data to update Add-On

The rapid add-on API supports checking if Custom Fields or images should be updated.

To do that, use the following methods. They should be placed in the 'import' method as shown in section 1 above.

Use can_update_meta to see if a Custom Field should be updated:

if ( $this->add_on->can_update_meta( '_yoast_wpseo_title', $import_options ) ) {
// Update the field if the user has allowed it in the import settings.
update_post_meta( $post_id, '_yoast_wpseo_title', $data['yoast_wpseo_title'] );
}

Use can_update_image to check of the 「Images」 box is checked:

if ( $this->add_on->can_update_image( $import_options ) ) {
// Retrieve the imported image's URL if images are set to be updated.
$image_url = wp_get_attachment_url( $data['yoast_wpseo_opengraph-image']['attachment_id'] );

// Save that image URL to our custom field.
update_post_meta( $post_id, '_yoast_wpseo_opengraph-image', $image_url );
}

There are more options in the Choose which data to update section, but they are rarely used by add-ons. These options are stored in the $import_options variable, which is passed to the registered import function. If your add-on does advanced things like changing parent posts, menu orders, etc. and you want to support these options, the settings you need to check are stored inside $import_options.

Please note can_update_image only tells you if the Images box is checked, it doesn』t tell you the settings. If you care, read it from $import_options.

4. Warn the user to install WP All Import.

You can display a dismissible notice warning the user to install WP All Import to use your add-on.

$this->add_on->admin_notice();

Customize the notice text by passing a string to admin_notice(), i.e.

$this->add_on->admin_notice(
'The Yoast WordPress SEO Add-On requires WP All Import Free and the Yoast WordPress SEO plugin.'
);

Add conditions for displaying the admin notice:

$this->add_on->admin_notice(
// Provide the notice text here.
"This Add-On requires WP All Import, the WP All Export Plugin and Twenty Fifteen theme.",
// This array should contain all of your conditions.
array(
// Multiple themes and plugins can be required.
"themes" => array( "Twenty Fifteen" ),
"plugins" => array( "wp-all-export/wp-all-export.php" )
)
);

5. Use tooltips when necessary to explain fields to users.

The fifth parameter of the add_field() function can take a string that will be used as a tooltip for the field. This will work for any of the field types.

$this->add_on->add_field(
// Field slug.
'property_price',
// Field display name.
'Price',
// Field type.
'text',
// Used for nested fields.
null,
// Set your tooltip text here.
'Numbers only, no symbols'
);

6. Add entries to the import log.

The log() function must be placed within the import function.

// Ensure it's either a new record or the settings allow updating images.
if ( empty( $article['ID'] ) || $this->add_on->can_update_image( $import_options ) ) {

// Retrieve the URL for our image.
$image_url = wp_get_attachment_url( $data['yoast_wpseo_opengraph-image']['attachment_id'] );

// Save our image URL as required by Yoast.
update_post_meta( $post_id, '_yoast_wpseo_opengraph-image', $image_url );

}

7. Disable the default images section if it』s not being used.

This should be placed within the add-on's constructor.

$this->add_on->disable_default_images();

Related

Overview

A Complete Add-On

A Complete Add-On To Use As A Starting Point

A Complete Add-On To Use As A Starting Point

Use this add-on for importing to Yoast as a starting point for your own add-on. It provides a real-world example of how all of the add-on fields work together with WP All Import. No need to start from scratch, fork this example and modify it to your needs.

Here』s the complete add-on: https://github.com/soflyy/wp-all-import-example-addon

Here's the direct link to the .zip archive that you can install in WordPress: https://github.com/soflyy/wp-all-import-example-addon/archive/master.zip

Once you activate the add-on, you』ll be prompted to install WP All Import if it's not already installed and active on your site.

The add-on is for importing to various fields in Yoast WordPress SEO, so to see the result of what the add-on does you』ll need that plugin installed as well.

Do a new import with WP All Import Import (Download example-yoast-data.csv) – you』ll see the add-on show up in Step 3 of WP All Import Import.

Related

Overview

Best Practices

Image Fields

Image Fields

Importing Single Images

Image fields allow the user to specify a single image URL or file path.

Rapid Add-On will automatically place the specified image in the Media Library and pass the ID of the media to the registered import function.

These fields should all be defined in your add-on's constructor.

$this->add_on->add_field( 'property_featured_img', 'Property Featured Image', 'image' );

Add-On Single Image Field

Your add-on』s import method will be passed the image data as an array. The ID of the image will be passed as the 「attachment_id」 array key.

Here』s how to set the Featured Image/Post Thumbnail to the specified image.

This example assumes the field slug specified in add_field is 「property_featured_img」.

public function import( $post_id, $data, $import_options ) {
$attachment_id = $data['property_featured_img']['attachment_id'];
set_post_thumbnail( $post_id, $attachment_id );
}

Importing Multiple Images

You can add entire image sections, with all of the settings and features that the default image section has, using the import_images() function.

$this->add_on->import_images( 'property_images', 'Property Images', 'images', [ $this, 'property_images' ]);

Add-On Multiple Images

This will call the property_images() method every time an image is imported. There you can process the image references as needed.

public function property_images( $post_id, $attachment_id, $image_filepath, $import_options ) {

// Retrieve previously stored image references.
$urls = get_post_meta($post_id, 'property_gallery', true);

// Add the attachment ID to the list as our example requires.
$urls[] = $attachment_id;

// Create a comma delimited list for our example field.
$new_urls = implode(',', $urls);

// Save the updated list of attachment IDs.
update_post_meta( $post_id, 'property_gallery', $new_urls );

}

Some themes allow users to upload files like PDFs. You can enable another section, identical to the default image section, except that it will allow any file type to be imported and attached to the post.

$this->add_on->import_files( 'property_attachments', 'Property Attachments', [ $this, 'property_attachments' ] );

Related

Add-On Structure

Text Fields

Radio Fields

Nested Fields

Nested Fields

Nested Fields

There are some settings that you add to your plugin that not all users need. To keep the user interface clean and organized for the majority of users you can nest and organized fields in a variety of ways.

The simplest method is to add an options panel. Here we will add an options panel to nest the price postfix in an expandable accordion.

$this->add_on->add_field( 'property_price', 'Property Price', 'text', null, 'Only digits, example: 435000' );

$this->add_on->add_options(
null,
'Price Settings',
array(
$this->add_on->add_field( 'property_price_postfix', 'Price Postfix', 'text', null, 'Example: Per Month' )
)
);

You can choose to add such an options panel attached to the price field.

$this->add_on->add_options(
$this->add_on->add_field( 'property_price', 'Property Price', 'text', null, 'Only digits, example: 435000' ),
'Price Settings',
array(
$this->add_on->add_field( 'property_price_postfix', 'Price Postfix', 'text', null, 'Example: Per Month' ),
$this->add_on->add_field( 'property_price_currency', 'Currency Symbol', 'text', null, 'Example: $, or €' )
)
);

Nested Radio Fields

You can also nest fields within the radio field. You can add as many fields as you like to the radio field』s options array.

$this->add_on->add_field(
'property_location',
'Property Location',
'radio',
array(
'enter_address' => array(
'Enter Address',
$this->add_on->add_field( 'property_address', 'Property Address', 'text' )
),
'enter_coordinates' => array(
'Enter Coordinates',
$this->add_on->add_field( 'property_coordinates', 'Property Coordinates', 'text' )
),
)
);

No Limits

You can even get a little crazy. There is no limit to how you can combine options panels and nested radio fields.

$this->add_on->add_field(
'location_settings',
'Property Location',
'radio',
array(
'search_by_address' => array(
'Search by Address',
$this->add_on->add_options(
$this->add_on->add_field( 'property_address','Property Address','text' ),
'Google Geocode API Settings',
array(
$this->add_on->add_field(
'geocode_method',
'Request Method',
'radio',
array(
'key_false' => array(
'No API Key',
'Limited number of requests.'
),
'key_true' => array(
'Google Developers API Key',
$this->add_on->add_field( 'api_key', 'API Key', 'text' ),
'Up to 2,500 requests per day and 5 requests per second.'
)
)
)
) // end Google Geocode API Settings fields
)
), // end Search by Address radio field
'enter_coordinates' => array(
'Enter Coordinates',
$this->add_on->add_field( 'property_latitude', 'Latitude', 'text' ),
$this->add_on->add_field( 'property_longitude', 'Longitude', 'text' )
)
)
);

Related

Add-On Structure

Text Fields

Radio Fields

Image Fields

Adding Support For Your Theme or Plugin

Adding Support For Your Theme or Plugin

WP All Import can be extended using our Add-On API to fully support any plugin or theme. Does your plugin or theme use custom database tables, inter-related post types, or some other unique setup? No problem, as you can write custom code to accommodate any situation.

Are you a plugin or theme developer?

Creating a WP All Import add-on will give your users an easy and free way to import their data to your plugin or theme.

An add-on can make things MUCH easier for your users if your plugin/theme doesn』t store data in the 「normal」 places in WordPress.

For example, many plugins and themes use nested serialized arrays and custom gallery fields to store data, but WP All Import doesn』t provide a simple way to import to those.

Note: Add-ons can be used with both the free and paid versions of WP All Import. This means all of your users will have an easy way to make use of the add-on you create.

Best of all, coding add-ons is extremely easy using our Rapid Add-On API.

An add-on is just a normal WordPress plugin, and a simple add-on can be done with less than 20 lines of code.

Continue to Add-On Structure to learn how to code an add-on.

What's Next?

Add-On Structure

Best Practices

A Complete Add-On

Related

Text Fields

Radio Fields

Image Fields

Nested Fields

Radio Fields

Radio Fields

Radio fields allow the user to specify one of multiple, predefined values. These fields should all be defined in your add-on's constructor.

$this->add_on->add_field(
'property_type',
'Property Type',
'radio',
array(
'rent' => 'For Rent/Lease',
'buy' => 'For Sale'
)
);

The keys in the options array are the actual values that will be passed to the import function. The values are the labels that will be shown to the user in the interface:

Radio Field

If the values in the user』s XML/CSV file are different than the values required by your radio field, the user can use the built-in mapping interface to translate them:

Radio Field Mapping

Related

Add-On Structure

Text Fields

Image Fields

Nested Fields

The Structure of an Import Add-On

The Structure of an Import Add-On

WP All Import Add-Ons are WordPress plugins that make use of WP All Import's Rapid Add-On API. A few simple lines of code is all it takes to add UI elements to WP All Import and then determine how that data gets imported.

There are four main parts to an add-on. First, you need to register your code as a plugin to WordPress and then as an add-on to WP All Import. Next, you add UI elements for your user to drag and drop data into. Then you tell WP All Import how to import this new data. Finally, you under which circumstances the add-on should run.

Now we'll go through each part of a simple add-on for WP All Import.

1. Create a new WordPress plugin and include the rapid-addon.php file.

To get started, you need to tell WordPress that this is a plugin and then set the groundwork for our import add-on. Start with the WordPress plugin header and then instantiate a class for your add-on.

/*
Plugin Name: My First Add-On
Description: A super awesome add-on for WP All Import!
Version: 1.0
Author: WP All Import
*/
include "rapid-addon.php";

final class my_first_add_on {

protected static $instance;

protected $add_on;

static public function get_instance() {
if ( self::$instance == NULL ) {
self::$instance = new self();
}
return self::$instance;
}

2. Initialize the add-on.

Next, create a new instance of the RapidAddon class in the add-on's constructor. Pass the add-on』s name and slug to the RapidAddon's class constructor. The slug should be unique to the add-on and different than the add-on's class name.

protected function __construct() {

// Define the add-on
$this->add_on = new RapidAddon( 'My First Add-On', 'my_first_addon' );

3. Add UI fields to the import template.

When setting up an import the user will drag and drop their data into WP All Import. The code below will add two text fields to the add-on – one for Property Location, and one for Property Price.

$this->add_on->add_field('property_location', 'Property Location', 'text');
$this->add_on->add_field('property_address', 'Property Address', 'text');

After all of the UI fields are set up, define the import method for your add-on with the snippet below. Each time a post is imported or updated, WP All Import will call this method and pass the post ID and the imported data. You'll also need to initialize the add-on with init.

$this->add_on->set_import_function([ $this, 'import' ]);
add_action( 'init', [ $this, 'init' ] );

4. Tell WP All Import how to import data to your theme or plugin.

Here we will get the values of the two fields we created earlier and import them as custom fields.

public function import( $post_id, $data, $import_options, $article ) {

$fields = array(
'property_location',
'property_address'
);

foreach ( $fields as $field ) {
// Make sure the user has allowed this field to be updated.
if ( empty( $article['ID'] ) || $this->add_on->can_update_meta( $field, $import_options ) ) {

// Update the custom field with the imported data.
update_post_meta( $post_id, $field, $data[ $field ] );
}
}
}

5. Specify when your add-on runs.

Earlier we initialized our add-on with init. By default, add-ons will always run. You probably want to check to make sure a theme or plugin is active, or limit your add-on to specific custom post types.

public function init() {

$this->add_on->run( array( "themes" => array("Twenty Fourteen", "Twenty Fifteen") ) );

}

The above code will only allow the add-on to run if the Twenty Fourteen or Twenty Fifteen theme is active.

6. Close out the add-on.

Finally, we need to call the get_instance() method at the end of the file, outside of the class definition:

my_first_add_on::get_instance();

7. That』s all, you are done coding!

To see the add-on in action, install and activate this plugin, and do an import with WP All Import.

The add-on will appear in Step 3 of WP All Import as a box titled My First Add-On:

My First Add-On

Related

Text Fields

Radio Fields

Image Fields

Nested Fields

Text Fields

Text Fields

If you need users to be able to input text so they can import a string, use a text input field. This is useful when the possible values for the field aren』t constrained to a predefined list. These fields should all be defined in your add-on's constructor.

$this->add_on->add_field( 'property_address', 'Property Address', 'text', null, 'Tooltip', false, 'Default Text' );

Here』s what a text input field looks like:

Add-On Text Field

You can also add a textarea field:

$this->add_on->( 'field_name', 'Field Name', 'textarea', null, 'Tooltip', false, 'Default Text');

And, it will look like this:

Text Area Field

Display Text & Titles

Other times you might want to include title or text to explain things to users. You can use the following functions to add titles and text to the UI of your add-on.

$this->add_on->add_title( 'Title Text', 'Text that will appear as a tooltip next to the title.' );
$this->add_on->add_text( 'This is text that will appear as a normal paragraph.' );

Related

Add-On Structure

Radio Fields

Image Fields

Nested Fields