| 1 |
<?php |
| 2 |
/* |
| 3 |
Plugin Name: Content Blocks (Custom Post Widget) |
| 4 |
Plugin URI: https://vanderwijk.com/wordpress/wordpress-custom-post-widget/?utm_source=wordpress&utm_medium=plugin&utm_campaign=custom_post_widget |
| 5 |
Description: Show the content of a custom post of the type 'content_block' in a widget or with a shortcode. |
| 6 |
Version: 3.4.3 |
| 7 |
Author: Johan van der Wijk |
| 8 |
Author URI: https://vanderwijk.nl |
| 9 |
Text Domain: custom-post-widget |
| 10 |
Domain Path: /languages |
| 11 |
License: GPL2 |
| 12 |
|
| 13 |
Release notes: Fixed PHP 8+ fatal errors when a widget references a deleted content block or a shortcode references a missing template. Missing templates now fall back to the standard shortcode output. |
| 14 |
|
| 15 |
Copyright 2026 Johan van der Wijk |
| 16 |
|
| 17 |
This program is free software; you can redistribute it and/or modify |
| 18 |
it under the terms of the GNU General Public License, version 2, as |
| 19 |
published by the Free Software Foundation. |
| 20 |
|
| 21 |
This program is distributed in the hope that it will be useful, |
| 22 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 23 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 24 |
GNU General Public License for more details. |
| 25 |
|
| 26 |
You should have received a copy of the GNU General Public License |
| 27 |
along with this program; if not, write to the Free Software |
| 28 |
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 29 |
*/ |
| 30 |
|
| 31 |
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly |
| 32 |
|
| 33 |
// Launch the plugin |
| 34 |
function custom_post_widget_plugin_init() { |
| 35 |
add_action( 'widgets_init', 'custom_post_widget_load_widgets' );; |
| 36 |
} |
| 37 |
add_action( 'plugins_loaded', 'custom_post_widget_plugin_init' ); |
| 38 |
|
| 39 |
// Loads the widgets packaged with the plugin |
| 40 |
function custom_post_widget_load_widgets() { |
| 41 |
require_once( 'post-type.php' ); |
| 42 |
require_once( 'shortcode.php' ); |
| 43 |
require_once( 'widget.php' ); |
| 44 |
register_widget( 'custom_post_widget' ); |
| 45 |
} |
| 46 |
|
| 47 |
// Include Elementor widget after Elementor is initialized |
| 48 |
function cpw_load_elementor_widget() { |
| 49 |
// Check if Elementor is active and loaded |
| 50 |
if ( did_action( 'elementor/loaded' ) ) { |
| 51 |
// Include the Elementor widget file |
| 52 |
require_once( 'elementor-widget.php' ); |
| 53 |
} |
| 54 |
} |
| 55 |
add_action( 'init', 'cpw_load_elementor_widget' ); |
| 56 |
|
| 57 |
// Load plugin textdomain |
| 58 |
function custom_post_widget_load_textdomain() { |
| 59 |
load_plugin_textdomain( 'custom-post-widget', false, dirname( plugin_basename( __FILE__ ) ) . '/languages' ); |
| 60 |
} |
| 61 |
add_action( 'plugins_loaded', 'custom_post_widget_load_textdomain' ); |
| 62 |
|
| 63 |
// Add featured image support |
| 64 |
if ( function_exists( 'add_theme_support' ) ) { |
| 65 |
add_theme_support( 'post-thumbnails' ); |
| 66 |
} |
| 67 |
|
| 68 |
// Admin-only functions |
| 69 |
if ( is_admin() ) { |
| 70 |
|
| 71 |
// Add donation and review links to plugin description |
| 72 |
if ( ! function_exists ( 'cpw_plugin_links' ) ) { |
| 73 |
function cpw_plugin_links( $links, $file ) { |
| 74 |
$base = plugin_basename( __FILE__ ); |
| 75 |
if ( $file == $base ) { |
| 76 |
$links[] = '<a href="https://wordpress.org/support/plugin/custom-post-widget/reviews/" target="_blank">' . __( 'Review', 'custom-post-widget' ) . ' <span class="dashicons dashicons-thumbs-up"></span></a> | <a href="https://paypal.me/vanderwijk">' . __( 'Donate', 'custom-post-widget' ) . ' <span class="dashicons dashicons-money"></span></a>'; |
| 77 |
} |
| 78 |
return $links; |
| 79 |
} |
| 80 |
} |
| 81 |
add_filter( 'plugin_row_meta', 'cpw_plugin_links', 10, 2 ); |
| 82 |
|
| 83 |
require_once( 'meta-box.php' ); |
| 84 |
require_once( 'popup.php' ); |
| 85 |
|
| 86 |
// Enqueue styles and scripts on content_block edit page |
| 87 |
function cpw_enqueue() { |
| 88 |
$screen = get_current_screen(); |
| 89 |
// Check screen base and current post type |
| 90 |
if ( 'post' === $screen -> base && 'content_block' === $screen -> post_type ) { |
| 91 |
wp_enqueue_style( 'cpw-style', plugins_url( '/assets/css/custom-post-widget.css', __FILE__ ), array(), esc_attr( get_plugin_data( __FILE__ )['Version'] ), 'all' ); |
| 92 |
wp_enqueue_script( 'clipboard' ); |
| 93 |
wp_enqueue_script( 'clipboard-init', plugins_url( '/assets/js/clipboard-init.js', __FILE__ ), array( 'clipboard' ), esc_attr( get_plugin_data( __FILE__ )['Version'] ), true ); |
| 94 |
} |
| 95 |
} |
| 96 |
add_action( 'admin_enqueue_scripts', 'cpw_enqueue' ); |
| 97 |
|
| 98 |
// Only add content_block icon above posts and pages |
| 99 |
function cpw_add_content_block_button() { |
| 100 |
global $current_screen; |
| 101 |
if ( ( 'content_block' != $current_screen -> post_type ) && ( 'toplevel_page_revslider' != $current_screen -> id ) ) { |
| 102 |
add_action( 'media_buttons', 'add_content_block_icon' ); |
| 103 |
add_action( 'admin_footer', 'add_content_block_popup' ); |
| 104 |
} |
| 105 |
} |
| 106 |
add_action( 'admin_head', 'cpw_add_content_block_button' ); |
| 107 |
|
| 108 |
} |
| 109 |
|
| 110 |
// Register the shortcode |
| 111 |
function cpw_content_block_shortcode( $atts ) { |
| 112 |
$atts = shortcode_atts( array( |
| 113 |
'id' => '', |
| 114 |
), $atts, 'cpw_content_block' ); |
| 115 |
|
| 116 |
if ( ! empty( $atts['id'] ) ) { |
| 117 |
$post = get_post( $atts['id'] ); |
| 118 |
if ( $post ) { |
| 119 |
$content = apply_filters( 'the_content', $post->post_content ); |
| 120 |
return $content; |
| 121 |
} |
| 122 |
} |
| 123 |
return ''; |
| 124 |
} |
| 125 |
add_shortcode( 'cpw_content_block', 'cpw_content_block_shortcode' ); |
| 126 |
|
| 127 |
// Map the shortcode to WPBakery Page Builder |
| 128 |
function cpw_vc_content_block_mapping() { |
| 129 |
// Check if WPBakery Page Builder is installed |
| 130 |
if ( ! defined( 'WPB_VC_VERSION' ) ) { |
| 131 |
return; |
| 132 |
} |
| 133 |
|
| 134 |
// Get all content blocks |
| 135 |
$content_blocks = get_posts( array( |
| 136 |
'post_type' => 'content_block', |
| 137 |
'posts_per_page' => -1, |
| 138 |
) ); |
| 139 |
|
| 140 |
$options = array(); |
| 141 |
if ( $content_blocks ) { |
| 142 |
foreach ( $content_blocks as $content_block ) { |
| 143 |
$options[ $content_block->post_title ] = $content_block->ID; |
| 144 |
} |
| 145 |
} else { |
| 146 |
$options[ __( 'No content blocks found', 'custom-post-widget' ) ] = ''; |
| 147 |
} |
| 148 |
|
| 149 |
vc_map( array( |
| 150 |
'name' => __( 'Content Block', 'custom-post-widget' ), |
| 151 |
'base' => 'cpw_content_block', |
| 152 |
'description' => __( 'Display a content block', 'custom-post-widget' ), |
| 153 |
'category' => __( 'Content', 'custom-post-widget' ), |
| 154 |
'params' => array( |
| 155 |
array( |
| 156 |
'type' => 'dropdown', |
| 157 |
'heading' => __( 'Select Content Block', 'custom-post-widget' ), |
| 158 |
'param_name' => 'id', |
| 159 |
'value' => $options, |
| 160 |
'admin_label' => true, |
| 161 |
'description' => __( 'Choose which content block to display.', 'custom-post-widget' ), |
| 162 |
), |
| 163 |
), |
| 164 |
) ); |
| 165 |
} |
| 166 |
add_action( 'vc_before_init', 'cpw_vc_content_block_mapping' ); |
| 167 |
|
| 168 |
|