├── README.md ├── cmb2-related-links.php ├── composer.json └── lib ├── init.php ├── script.js └── style.css /README.md: -------------------------------------------------------------------------------- 1 | # CMB2 Related Links 2 | 3 | Special CMB2 Field that allows users to add a related links repeating field group. This is not a standard field type, but instead a function you use in combination with `CMB2::add_field()`. Each link can be populated with existing WordPress content by clicking on the search button. 4 | 5 | The only required parameter is the `'id'` parameter, though you can override almost all of the arguments by passing them in. 6 | 7 | This field requires the [CMB2 Post Search field](https://github.com/WebDevStudios/CMB2-Post-Search-field). 8 | 9 | ### Example 10 | ```php 11 | // Add a related links field. 12 | $cmb->add_field( cmb2_related_links_field( array( 'id' => 'yourprefix_related_links' ) ) ); 13 | ``` 14 | 15 | If you are looking to bundle this field in your plugin or theme, you will need to pass the second parameter which is an array of all the translateable strings: 16 | ```php 17 | $translateable = array( 18 | 'description' => __( 'Add links, or select from related content by clicking the search icon.', 'yourtextdomain' ), 19 | 'group_title' => __( 'Link {#}', 'yourtextdomain' ), 20 | 'link_title' => __( 'Title', 'yourtextdomain' ), 21 | 'link_url' => __( 'URL', 'yourtextdomain' ), 22 | 'find_text' => __( 'Find/Select related content', 'yourtextdomain' ), 23 | ); 24 | $cmb->add_field( cmb2_related_links_field( 25 | array( 'id' => 'yourprefix_related_links' ), 26 | $translateable 27 | ) ); 28 | ``` 29 | -------------------------------------------------------------------------------- /cmb2-related-links.php: -------------------------------------------------------------------------------- 1 | 20 | * @copyright 2016 Justin Sternberg 21 | * @license GPL-2.0+ 22 | * @version 0.1.1 23 | * @link https://github.com/jtsternberg/CMB2-Related-Links 24 | * @since 0.1.0 25 | */ 26 | 27 | /** 28 | * Copyright (c) 2016 Justin Sternberg (email : justin@dsgnwrks.pro) 29 | * 30 | * This program is free software; you can redistribute it and/or modify 31 | * it under the terms of the GNU General Public License, version 2 or, at 32 | * your discretion, any later version, as published by the Free 33 | * Software Foundation. 34 | * 35 | * This program is distributed in the hope that it will be useful, 36 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 37 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 38 | * GNU General Public License for more details. 39 | * 40 | * You should have received a copy of the GNU General Public License 41 | * along with this program; if not, write to the Free Software 42 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 43 | */ 44 | 45 | /** 46 | * Loader versioning: http://jtsternberg.github.io/wp-lib-loader/ 47 | */ 48 | 49 | if ( ! class_exists( 'CMB2_Related_Links_011', false ) ) { 50 | 51 | /** 52 | * Versioned loader class-name 53 | * 54 | * This ensures each version is loaded/checked. 55 | * 56 | * @category WordPressLibrary 57 | * @package CMB2_Related_Links 58 | * @author Justin Sternberg 59 | * @license GPL-2.0+ 60 | * @version 0.1.1 61 | * @link https://github.com/jtsternberg/CMB2-Related-Links 62 | * @since 0.1.0 63 | */ 64 | class CMB2_Related_Links_011 { 65 | 66 | /** 67 | * CMB2_Related_Links version number 68 | * @var string 69 | * @since 0.1.0 70 | */ 71 | const VERSION = '0.1.1'; 72 | 73 | /** 74 | * Current version hook priority. 75 | * Will decrement with each release 76 | * 77 | * @var int 78 | * @since 0.1.0 79 | */ 80 | const PRIORITY = 9998; 81 | 82 | /** 83 | * Starts the version checking process. 84 | * Creates CMB2_RELATED_LINKS_LOADED definition for early detection by 85 | * other scripts. 86 | * 87 | * Hooks CMB2_Related_Links inclusion to the cmb2_related_links_load hook 88 | * on a high priority which decrements (increasing the priority) with 89 | * each version release. 90 | * 91 | * @since 0.1.0 92 | */ 93 | public function __construct() { 94 | if ( ! defined( 'CMB2_RELATED_LINKS_LOADED' ) ) { 95 | /** 96 | * A constant you can use to check if CMB2_Related_Links is loaded 97 | * for your plugins/themes with CMB2_Related_Links dependency. 98 | * 99 | * Can also be used to determine the priority of the hook 100 | * in use for the currently loaded version. 101 | */ 102 | define( 'CMB2_RELATED_LINKS_LOADED', self::PRIORITY ); 103 | } 104 | 105 | // Use the hook system to ensure only the newest version is loaded. 106 | add_action( 'cmb2_related_links_load', array( $this, 'include_lib' ), self::PRIORITY ); 107 | 108 | /* 109 | * Hook in to the first hook we have available and 110 | * fire our `cmb2_related_links_load' hook. 111 | */ 112 | add_action( 'muplugins_loaded', array( __CLASS__, 'fire_hook' ), 9 ); 113 | add_action( 'plugins_loaded', array( __CLASS__, 'fire_hook' ), 9 ); 114 | add_action( 'after_setup_theme', array( __CLASS__, 'fire_hook' ), 9 ); 115 | } 116 | 117 | /** 118 | * Fires the cmb2_related_links_load action hook. 119 | * 120 | * @since 0.1.0 121 | */ 122 | public static function fire_hook() { 123 | if ( ! did_action( 'cmb2_related_links_load' ) ) { 124 | // Then fire our hook. 125 | do_action( 'cmb2_related_links_load' ); 126 | } 127 | } 128 | 129 | /** 130 | * A final check if CMB2_Related_Links exists before kicking off 131 | * our CMB2_Related_Links loading. 132 | * 133 | * CMB2_RELATED_LINKS_VERSION and CMB2_RELATED_LINKS_DIR constants are 134 | * set at this point. 135 | * 136 | * @since 0.1.0 137 | */ 138 | public function include_lib() { 139 | if ( class_exists( 'CMB2_Related_Links', false ) ) { 140 | return; 141 | } 142 | 143 | if ( ! defined( 'CMB2_RELATED_LINKS_VERSION' ) ) { 144 | /** 145 | * Defines the currently loaded version of CMB2_Related_Links. 146 | */ 147 | define( 'CMB2_RELATED_LINKS_VERSION', self::VERSION ); 148 | } 149 | 150 | if ( ! defined( 'CMB2_RELATED_LINKS_DIR' ) ) { 151 | /** 152 | * Defines the directory of the currently loaded version of CMB2_Related_Links. 153 | */ 154 | define( 'CMB2_RELATED_LINKS_DIR', dirname( __FILE__ ) . '/' ); 155 | } 156 | 157 | // Include and initiate CMB2_Related_Links. 158 | require_once CMB2_RELATED_LINKS_DIR . 'lib/init.php'; 159 | } 160 | 161 | } 162 | 163 | // Kick it off. 164 | new CMB2_Related_Links_011; 165 | } 166 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jtsternberg/cmb2-related-links", 3 | "description": "Custom field for CMB2 which adds a releated links repeatable group field.", 4 | "license": "GPL-2.0+", 5 | "authors": [ 6 | { 7 | "name": "jtsternberg", 8 | "email": "justin@dsgnwrks.pro", 9 | "homepage": "http://dsgnwrks.pro/", 10 | "role": "Developer" 11 | } 12 | ], 13 | "keywords": ["wordpress", "cmb2", "meta"], 14 | "homepage": "https://github.com/jtsternberg/CMB2-Related-Links", 15 | "support": { 16 | "issues": "https://github.com/jtsternberg/CMB2-Related-Links/issues", 17 | "source": "https://github.com/jtsternberg/CMB2-Related-Links" 18 | }, 19 | "require": { 20 | "php": ">=5.2" 21 | }, 22 | "autoload": { 23 | "files": ["cmb2-related-links.php"] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /lib/init.php: -------------------------------------------------------------------------------- 1 | 10 | * @license GPL-2.0+ 11 | * @version 0.1.1 12 | * @link https://github.com/jtsternberg/CMB2-Related-Links 13 | * @since 0.1.0 14 | */ 15 | class CMB2_Related_Links { 16 | 17 | protected static $single_instance = null; 18 | protected static $script_add = false; 19 | protected $l10n_strings = array( 20 | 'description' => 'Add links, or select from related content by clicking the search icon.', 21 | 'group_title' => 'Link {#}', 22 | 'link_title' => 'Title', 23 | 'link_url' => 'URL', 24 | 'find_text' => 'Find/Select related content', 25 | ); 26 | 27 | /** 28 | * Creates or returns an instance of this class. 29 | * @since 0.1.0 30 | * @return CMB2_Related_Links A single instance of this class. 31 | */ 32 | public static function get_instance() { 33 | if ( null === self::$single_instance ) { 34 | self::$single_instance = new self(); 35 | } 36 | 37 | return self::$single_instance; 38 | } 39 | 40 | /** 41 | * Constructor (setup our hooks) 42 | */ 43 | protected function __construct() { 44 | add_action( is_admin() ? 'admin_footer' : 'wp_footer', array( __CLASS__, 'footer_js' ) ); 45 | add_action( 'wp_ajax_cmb2_related_links_get_post_data', array( __CLASS__, 'get_post_data' ) ); 46 | } 47 | 48 | public function field( $args = array(), $l10n_strings = array() ) { 49 | if ( ! isset( $args['id'] ) || ! $args['id'] ) { 50 | wp_die( "CMB2_Related_Links field requires an 'id' parameter." ); 51 | } 52 | 53 | $l10n_strings = wp_parse_args( $l10n_strings, $this->l10n_strings ); 54 | 55 | $options = array( 56 | 'group_title' => $l10n_strings['group_title'], 57 | 'add_button' => '', 58 | 'remove_button' => '', 59 | 'sortable' => true, 60 | ); 61 | 62 | if ( isset( $args['options'] ) && is_array( $args['options'] ) ) { 63 | $options = wp_parse_args( $args['options'], $options ); 64 | } 65 | 66 | $fields = array( 67 | 'title' => array( 68 | 'name' => $l10n_strings['link_title'], 69 | 'id' => 'title', 70 | 'type' => 'text', 71 | 'attributes' => array( 72 | 'placeholder' => $l10n_strings['link_title'], 73 | ), 74 | ), 75 | 'url' => array( 76 | 'name' => $l10n_strings['link_url'], 77 | 'id' => 'url', 78 | 'type' => 'post_search_text', 79 | 'post_type' => $this->post_types(), 80 | 'select_type' => 'radio', 81 | 'options' => array( 82 | 'find_text' => $l10n_strings['find_text'], 83 | ), 84 | 'attributes' => array( 85 | 'class'=> 'regular-text post-search-data', 86 | 'placeholder' => $l10n_strings['link_url'], 87 | ), 88 | ), 89 | ); 90 | 91 | if ( isset( $args['fields'] ) && is_array( $args['fields'] ) ) { 92 | if ( isset( $args['fields']['title'] ) && is_array( $args['fields']['title'] ) ) { 93 | $fields['title'] = wp_parse_args( $args['fields']['title'], $fields['title'] ); 94 | unset( $args['fields']['title'] ); 95 | } 96 | 97 | if ( isset( $args['fields']['url'] ) && is_array( $args['fields']['url'] ) ) { 98 | $fields['url'] = wp_parse_args( $args['fields']['url'], $fields['url'] ); 99 | unset( $args['fields']['url'] ); 100 | } 101 | 102 | $fields = array_merge( array_values( $args['fields'] ), array_values( $fields ) ); 103 | } else { 104 | $fields = array_values( $fields ); 105 | } 106 | 107 | $args = wp_parse_args( $args, array( 108 | 'id' => '', 109 | 'desc' => $l10n_strings['description'], 110 | 'before_group' => array( $this, 'before_group' ), 111 | 'after_group' => '', 112 | 'show_names' => false, 113 | ) ); 114 | 115 | $args['type'] = 'group'; 116 | $args['options'] = $options; 117 | $args['fields'] = $fields; 118 | 119 | // wp_die( '$args: '. print_r( $args, true ) .'' ); 120 | return $args; 121 | } 122 | 123 | public function before_group() { 124 | self::$script_add = true; 125 | $css = $this->get_css(); 126 | return $css . '