wpmu New Blog Template action hooks for Edit Blog Template admin menu form

Hi, I am trying to add additional copy options to the New Blog Template plugin, in the Edit Blog Template form (see attached screenshot), so that I can copy custom post types, taxonomies, etc. In a custom plugin that would add the additional inputs via javascript. This way it would be safe to update the New Blog Template plugin.

I am currently trying to add the new options as checkbox inputs below your current copy options using javascript.

Is there a hook that fires after the Edit Blog Template form is rendered so that I can enqueue the javascript to print out my additional options below the current options?

for example, I was thinking of doing this:

File: yourScript.js
(function($) {
    $(document).ready(function() {
      $('<table>').append(
      $('<tr class="form-field form-required"></tr>').append(
            $('<th scope="row">New field</th>')
        ).append(
            $('<td></td>').append(
                $('<input class="regular-text" type="checkbox" title="New Field" name="new_field_name">')
            ).append(
                $('<p>Explanation about your new field</p>')
            ).append( $('</table>')
        ).insertAfter('LAST TABLE ELEMENT');
    });
})(jQuery);
//NOTE THIS CODE PROBABLY HAS Syntax errors, just trying to show you what i might do

My Custom Plugin File to enqueue the js:
// Only add the script for the page site-new.php (the page hook).
add_action( "NEW_BLOG_TEMPLATE_HOOK_HERE", 'my_scripts' );

function my_scripts() {
    wp_register_script('yourScript', plugins_url('js/yourScript.js', __FILE__));
    wp_enqueue_script('yourScript');
}

Is there a better approach that you can suggest if there is no hook such as the one i am asking?

Thank you,

Tin

  • Jose

    Hi there hoangker,

    Your approach looks correct to me, since there is no easy way to do it from php (without touching the core). You could remove the action listener for the 'network_admin_menu' hook and add your own admin menu, but in that case you would be overriding a good part of the plugin.

    So, using javascript is a good workaround here.

    There are no specific hooks triggered by the plugin because it can be done using the built in hook 'admin_enqueue_scripts' and checking for the current page.

    Something like this should work:

    function add_custom_javascript(){
        if ( get_current_screen()->id == 'toplevel_page_blog_templates_main-network' ) {
            wp_register_script('yourScript', plugins_url('js/yourScript.js', __FILE__));
            wp_enqueue_script('yourScript');
        }
    }
    add_action( 'admin_enqueue_scripts', 'add_custom_javascript' );

    Hope this helps!

    Don't hesitate to ask if you have further questions.

    Cheers!
    Jose

  • hoangker

    Hi @Vaughan and @Jose,

    I finished implementing the method I took to add additional options to the new blog template plugin (see attached screenshot). Its still not pretty but it gets the job done for now.

    Actually, copying the new option (i.e. custom post types and taxonomies still needs to be done) still has to be implemented, however, I wanted to share what I did in case someone wanted to do the same thing.

    The below code adds an additional checkbox to also copy "custom post types and taxonomies".
    requires two files:
    1. yourScript.js
    2.new_blog_option.php (threw this in my mu-plugins folder)

    1. yourScript.js

    (function($) {
        $(document).ready(function() {
    
    		var yourScriptObject;
    
    		var checked = "checked";
    		if ( php_vars.msp_nbt_custom_posttypes == 0 )
    		    checked = "";
    
    		$('#options table:last').append("<label><input type='checkbox' name='msp_nbt_custom_posttypes' id='' value='' " + checked +">Custom Post Types, Taxonomies, Etc</label><br/>");
    
        });
    })(jQuery);

    2.new_blog_option.php

    /**
     * Plugin Name: new blog option
     * Plugin URI: STUFF
     * Description: STUFF
     * Version: 1.0.0
     * Author: Tin Hoang
     * Author URI: http://URI_Of_The_Plugin_Author
     * Text Domain: STUFF
     * Domain Path: Optional.
     * Network:
     * License: A short license name. Example: GPL2
     */
    
    include(dirname(__FILE__) . '\..\plugins\blogtemplates\blogtemplates.php'); 
    
    if ( is_network_admin() ){
    	function add_custom_javascript(){
    
    		if ( get_current_screen()->id == 'toplevel_page_blog_templates_main-network' ) {
    			$t = isset( $_GET['t'] ) ? (string) $_GET['t'] : '';
    			//echo 'template id:' . $t;
    			//echo 'enqueuing!!!';
    			$model = nbt_get_model();
    			$template = $model->get_template( $t );
    			$msp_nbt_custom_posttypes = $template['msp_nbt_custom_posttypes'];
    			//echo 'copy posttype:' .$msp_nbt_custom_posttypes;
    
    			wp_register_script('yourScript', plugins_url('new_blog_options/js/yourScript.js', __FILE__));
    			wp_enqueue_script('yourScript');
    
    			//pass the value of the new option to the javascript
    			$dataToBePassed = array(
    				'msp_nbt_custom_posttypes' => isset( $msp_nbt_custom_posttypes ) && $msp_nbt_custom_posttypes == true ? 1 : 0
    			);
    			wp_localize_script( 'yourScript', 'php_vars', $dataToBePassed );
    		}
    	}
    	add_action( 'admin_enqueue_scripts', 'add_custom_javascript' );
    
    	//action to get called when we are saving a template hook onto that to save this new option
    	function save_new_blog_options(){
    		global $blogtemplate;
    		$model = nbt_get_model();
    		if ( ! isset( $_GET['page'] ) /*|| $_GET['page'] !== $this->menu_slug*/ )
                    return;
    
                $model = nbt_get_model();
    
                $t = isset( $_GET['t'] ) ? (string) $_GET['t'] : '';
    
                $save_template = ( ! empty( $_POST['reset-screenshot'] ) || ! empty( $_POST['save_updated_template'] ) );
                if( $save_template ) {
    
    				// SAVE the MSP custom options into the database
    				// START COPY FROM newblogtemplates->main_menu.php->admin_options_page_posted()
    				 $args = array(
    	                'name' => stripslashes($_POST['template_name'] ),
    	                'description' => stripslashes( preg_replace('~<\s*\bscript\b[^>]*>(.*?)<\s*\/\s*script\s*>~is', '', $_POST['template_description'] ) ),
    	                'to_copy' => isset( $_POST['to_copy'] ) ? (array)$_POST['to_copy'] : array(),
    	                'additional_tables' => isset( $_POST['additional_template_tables'] ) ? $_POST['additional_template_tables'] : array(),
    	                'copy_status' => isset( $_POST['copy_status'] ) ? true : false,
    	                'block_posts_pages' => isset( $_POST['block_posts_pages'] ) ? true : false,
    	                'update_dates' => isset( $_POST['update_dates'] ) ? true: false,
    					'msp_nbt_custom_posttypes' => isset( $_POST['msp_nbt_custom_posttypes'] ) ? true: false //MSP OPTION ADD HERE
    	            );
    	            if ( ! empty( $_FILES['screenshot']['tmp_name'] ) ) {
                    	$uploaded_file = $_FILES['screenshot'];
                    	$wp_filetype = wp_check_filetype_and_ext( $uploaded_file['tmp_name'], $uploaded_file['name'], false );
    					if ( ! wp_match_mime_types( 'image', $wp_filetype['type'] ) )
    						wp_die( '<div class="error"><p>' . __( 'The uploaded file is not a valid image. Please try again.' ) . '</p></div>' );
    
    					$movefile = wp_handle_upload( $uploaded_file, array( 'test_form' => false ) );
    
    					if ( $movefile ) {
    					    $args['screenshot'] = $movefile['url'];
    					}
                    }
                    else {
                    	$template = $model->get_template( absint( $_POST['template_id'] ) );
                    	$args['screenshot'] = ! empty( $template['screenshot'] ) ? $template['screenshot'] : false;
                    }
    
                    if ( ! empty( $_POST['reset-screenshot'] ) ) {
                		$args['screenshot'] = false;
                	}
    
                	// POST CATEGORIES
                    $post_category = array( 'all-categories' );
                    if ( isset( $_POST['post_category'] ) ) {
                    	$categories = $_POST['post_category'];
    
                    	if ( in_array( 'all-categories', $categories ) ) {
                    		$post_category = array( 'all-categories' );
                    	}
                    	else {
    
                    		$post_category = array();
                    		foreach( $categories as $category ) {
                    			if ( ! is_numeric( $category ) )
                    				continue;
    
                    			$post_category[] = absint( $category );
                    		}
                    	}
                    }
                    $args['post_category'] = $post_category;
    
                    // PAGES IDs
                    $pages_ids = array( 'all-pages' );
    
                    if ( isset( $_POST['pages_ids'] ) && is_array( $_POST['pages_ids'] ) ) {
                    	if ( in_array( 'all-pages', $_POST['pages_ids'] ) ) {
                    		$pages_ids = array( 'all-pages' );
                    	}
                    	else {
                    		$pages_ids = array();
                    		foreach( $_POST['pages_ids'] as $page_id ) {
                    			if ( ! is_numeric( $page_id ) )
                    				continue;
    
                    			$pages_ids[] = absint( $page_id );
                    		}
                    	}
                    }
                    $args['pages_ids'] = $pages_ids;
    				// END COPY
    
                    new_option_update_template( $t, $args);
    
                } elseif( !empty( $_POST['save_new_template'] ) ) {
    
    				/*TODO*/
                }
    
    	}
    	add_action( 'admin_init', 'save_new_blog_options');
    
    	/**
    	 * copied from newblogtemplates->model.php
    	 */
    	function new_option_update_template( $id, $args ){
    		global $wpdb;
    
    		extract( $args );
    
    		$options = maybe_serialize( array(
    			'to_copy' => $to_copy,
    			'additional_tables' => $additional_tables,
    			'copy_status' => $copy_status,
    			'block_posts_pages' => $block_posts_pages,
    			'post_category' => $post_category,
    			'screenshot' => ! empty( $screenshot ) ? $screenshot : false,
    			'pages_ids' => $pages_ids,
    			'update_dates' => $update_dates,
    			'msp_nbt_custom_posttypes' => $msp_nbt_custom_posttypes
    		) );
    
    		$wpdb->update(
    			$wpdb->prefix . 'nbt_templates',
    			array(
    				'name' => $name,
    				'description' => $description,
    				'options' => $options
    			),
    			array( 'ID' => $id ),
    			array( '%s', '%s', '%s' ),
    			array( '%d' )
    		);
    	}
    }

    Thanks guys,

    Tin

  • Jose

    Thanks for sharing!

    At a first glance, I noticed a few things that can be improved:
    1- The javascript part is not too big. So, in this case, instead of including an external .js file you can simply include it in your mu-plugins. That way it is much easier to port and install since you don't need to worry about where to put your scripts files.
    You can use this snippet to inject the javascript:

    function custom_admin_js() {
        ?>
    <script type="text/javascript">
    (function($) {
        $(document).ready(function() {
    
    		var yourScriptObject;
    
    		var checked = "checked";
    		if ( php_vars.msp_nbt_custom_posttypes == 0 )
    		    checked = "";
    
    		$('#options table:last').append("<label><input type='checkbox' name='msp_nbt_custom_posttypes' id='' value='' " + checked +">Custom Post Types, Taxonomies, Etc</label><br/>");
    
        });
    })(jQuery);
    </script>
    <?php
    }
    add_action('admin_footer', 'custom_admin_js');

    2- Your approach with the include statement is a bit dangerous, since you are forcing the main plugin file to load before the plugin itself is loaded. As a result, you will have the same code executing twice. Also, you need to reference the file location statically, which is prone to error.
    If your code depends on blogtemplates.php file to be loaded, the right approach is to run your custom code after the NBT plugin is loaded. (without including the file from your code)
    In order to do so, you can hook into the action 'plugins_loaded': http://codex.wordpress.org/Plugin_API/Action_Reference/plugins_loaded

    3- Finally, you don't want your code to run if the New Blog Templates plugin is deactivated.
    You can know if a plugin is activated simply by checking if a function defined by the plugin in the global scope exists.
    This would do the trick in this case:

    if( !function_exists('nbt_load_text_domain') ){
        return; // Plugin is not active. Abort the execution.
    }
    // If you are here, plugin is active. Do your stuff.

    Overall, your code looks good, but you are using more a PHP approach instead of a WP approach. :slight_smile:

    Hope this tips are useful for you.

    Cheers!,
    Jose

  • hoangker

    I've been racking my brain all day with regard to your point 2. (above)

    2- Your approach with the include statement is a bit dangerous, since you are forcing the main plugin file to load before the plugin itself is loaded. As a result, you will have the same code executing twice. Also, you need to reference the file location statically, which is prone to error.
    If your code depends on blogtemplates.php file to be loaded, the right approach is to run your custom code after the NBT plugin is loaded. (without including the file from your code)
    In order to do so, you can hook into the action 'plugins_loaded': http://codex.wordpress.org/Plugin_API/Action_Reference/plugins_loaded

    I needed access to the blog_template_model class from new blog templates plugin. That is why I originally included the file:

    "\..\plugins\blogtemplates\blogtemplates.php"

    I am not too sure how to use the action "plugins_loaded" to load the model that I need now. I understand now that I need WordPress to load all the plugins first before I can make a call to
    nbt_get_model() (defined in blogtemplate/blogtemplatesfiles/model.php). But, how do I make a call to nbt_get_model() now that I am using the action "plugins_loaded" vs include??

    here is my modified code to try and use "plugins_loaded". Failed. It doesn't spit out the new options anymore =(

    ... plugin definition
            if( !function_exists('nbt_load_text_domain') ){
    	 	return; // Plugin is not active. Abort the execution.
    	}
    
    	add_action( 'plugins_loaded', 'add_new_blog_options' );
    
    	function add_new_blog_options()
    	{
    
    	 	add_action( 'admin_enqueue_scripts', 'add_custom_javascript' );
    	}
    
             ... code here to add the javascript to blog template page like above

    Thank you,

    Tin

  • Jose

    Hey Tim,

    The problem is that your are checking if the function exists before the plugins loaded. It will always return false. (remember that mu-plugins will load before standard plugins).

    This should work:
    `add_action( 'plugins_loaded', 'add_new_blog_options' );

    function add_new_blog_options()
    {
    if( !function_exists('nbt_load_text_domain') ){
    return; // Plugin is not active. Abort the execution.
    }

    add_action( 'admin_enqueue_scripts', 'add_custom_javascript' );
    }`

    A simple way to debug and detect which part of the code is not working is to use var_dump() and die()/exit() methods.

    Hope it helps! Let me know if you have further questions.

    Cheers,
    Jose

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.