I thought Wordpress supports creating multiple widget instances in the same location but it looks like it does not in my code. I have created a plugin that shows recent posts. And in it I have created a widget that I want to be able to display multiple times in the same location.
class My_Recent_Posts_Widget extends WP_Widget {
function __construct() {
parent::__construct(
'recent_posts', // Base ID
esc_html__( 'Recent posts', 'text_domain' ), // Name
array( 'description' => esc_html__( 'Display posts via widgets', 'text_domain' ), ) // Args
);
}
And I register the widget like this;
function register_my_recent_posts_widget() {
register_widget( 'My_Recent_Posts_Widget' );
}
add_action( 'widgets_init', 'register_my_recent_posts_widget' );
The problem is if I try to place 2 instances of the same widget in the same location on the Widgets page in the admin the second widget does not show up.
Try this code
class My_Recent_Posts_Widget extends WP_Widget {
public function __construct() {
$widget_ops = array('classname' => 'my_widget_recent_entries', 'description' => esc_html__( "Your most recent Posts.",'text_domain') );
parent::__construct('my-recent-posts', esc_html__('My Recent Posts Widget','text_domain'), $widget_ops);
$this->alt_option_name = 'my_widget_recent_entries';
}
Related
I am working on a plugin and I am creating a meta box on my page using the below code but it's not displaying anything.
Any idea where is the issue with my code?
class bt_dashboard {
function __construct() {
add_meta_box( 'metaboxes-sidebox-1', 'Sidebox 1 Title', array( $this, 'welcome_bt' ), 'welcomebt', 'advanced', 'default' );
}
function setup() {
// setup class, maybe add hooks
}
function welcome_bt() {
?>
<h2>Wellcome to metabox</h2>
<?php
}
}
Meta box not displaying on the plugin page
I'm using the Wordpress Plugin Boilerplate as foundation for my own plugin. In the admin area I intend to display data using the WP_List_Table class of Wordpress. I know I have to create my own child class to access it. Doing so is not the issue, however I get the following error:
Fatal error: Uncaught Error: Call to a member function render_screen_reader_content() on
During my research I discovered a few cases with the same issue (1, 2), but none of the solutions worked in my case.
Using the structure of the boilerplate, I created the child class in a file inside the includes folder:
if ( !class_exists( 'WP_List_Table' ) ) {
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}
if ( !class_exists( 'Hedwig_tables' ) ) {
class Hedwig_tables extends WP_List_Table {
private array $hd_columns;
private array $hd_data;
private array $hd_hidden;
private array $hd_sortable;
private array $hd_column_names;
public function __construct() {
//parent::__construct();
}
public function set_column_names(array $column_names) {
$this->hd_column_names = $column_names;
}
public function set_columns(array $columns) {
$this->hd_columns = $columns;
}
public function set_data(array $data) {
$this->hd_data = $data;
}
public function set_hidden(array $hidden) {
$this->hd_hidden = $hidden;
}
public function set_sortable(array $sortable) {
$this->hd_sortable = $sortable;
}
public function prepare_items() {
$this->_column_headers = array($this->hd_columns, $this->hd_hidden, $this->hd_sortable);
$this->items = $this->hd_data;
}
public function column_default( $item, $column_name ): mixed {
if (in_array($column_name, $this->hd_column_names)) {
return $item[ $column_name ];
}
return print_r($item, true);
}
}
}
The file is then loaded in the boilerplate's load_dependencies() function in class-plugin-name.php inside the includes folder.
In the boilerplate's class-plugin-name-admin.php (inside the admin folder) I created a function which generates the admin menu entry.
public function add_hedwig_page() {
$this->plugin_screen_hook_suffix = add_menu_page(
__( 'Hedwig Settings', 'Hedwig' ),
__( 'Hedwig Settings', 'Hedwig' ),
'manage_options',
$this->plugin_name,
array( $this, 'hedwig_admin_display_page' ),
'dashicons-buddicons-activity'
);
$this->plugin_screen_hook_suffix = add_submenu_page(
$this->plugin_name,
__( 'Hedwig Settings', 'Hedwig' ),
__( 'Hedwig Settings', 'Hedwig' ),
'manage_options',
$this->plugin_name,
array( $this, 'hedwig_admin_display_page' )
);
public function hedwig_admin_display_page() {
include_once 'partials/hedwig-admin-display.php';
}
Inside the display.php a function is called which I created inside the class-plugin-name-admin.php which creates the object for the child class of WP_List_Table.
public function get_data() {
$hedwig_list_table = new Hedwig_tables();
$sql = "SELECT id, value FROM y";
$results = $this->wpdb->get_results($sql, ARRAY_A);
if (count($results)<=0) {
?>
<div class="hedwig-msg-error"><?php _e('No data found.','Hedwig');?></div>
<?php
return false;
}
$hedwig_list_table->set_columns(
array(
'id' => __('ID','Hedwig'),
'value' => __('Art','Hedwig')
)
);
$hedwig_list_table->set_column_names(
array(
'id',
'value'
)
);
$hedwig_list_table->set_data($results);
$hedwig_list_table->set_hidden(array());
$hedwig_list_table->set_sortable(array());
$hedwig_list_table->prepare_items();
$hedwig_list_table->display();
return true;
}
Based on my aforementioned research the issue must be somewhere along the line of when the object for the child class is created (see this answer). I tried using add_actions() at different places (on __construct of the admin class, inside the run() function of the plugin-name.php trying to either load it after the menu items are generated or loading the class as a $GLOBALS. Everything I came up with failed. I used to create some smaller plugins without a boilerplate, but in this project I actually want to do the switch to this OOP and get new plugins kickstarted this way.
Update #1
Still got no solution, but I stumbled upon another solution which looked promising. However, using a function when creating the menu item for initialising the child class doesn't work either.
public function add_hedwig_page() {
$this->plugin_screen_hook_suffix = add_menu_page(
__( 'Hedwig Settings', 'Hedwig' ),
__( 'Hedwig Settings', 'Hedwig' ),
'manage_options',
$this->plugin_name,
function() {
$this->hedwig_list_table = new Hedwig_tables();
$this->hedwig_admin_display_page();
},
'dashicons-buddicons-activity'
);
$this->plugin_screen_hook_suffix = add_submenu_page(
$this->plugin_name,
__( 'Hedwig Settings', 'Hedwig' ),
__( 'Hedwig Settings', 'Hedwig' ),
'manage_options',
$this->plugin_name,
function() {
$this->hedwig_list_table = new Hedwig_tables();
$this->hedwig_admin_display_page();
}
);
public function hedwig_admin_display_page() {
include_once 'partials/hedwig-admin-display.php';
}
You shouldn't load this class like your custom classes since this is an extension of a core class and it has many more dependencies to rely on. Don't use add_action or $GLOBALS to initialize this class at all.
If you load it in boilerplate's load_dependencies() function in class-plugin-name.php inside the includes folder it will be instantiated too early and it will not function properly.
Instead, call it only when needed, inside your partials/hedwig-admin-display.php that you will use to output your markup for that page.
Something like this should work in your example:
<?php $table = new Hedwig_tables(); ?>
<h1>Hedwig_tables</h1>
<div class="wrap">
<div id="poststuff">
<div id="post-body" class="metabox-holder">
<div id="post-body-content">
<div class="meta-box-sortables ui-sortable">
<?php $table->prepare_items();?>
<form method="get">
<?php $table->display(); ?>
</form>
</div>
</div>
</div>
<br class="clear">
</div>
</div>
I have created a custom module in divi builder. Below given is the code:
function ex_divi_child_theme_setup() {
if ( class_exists('ET_Builder_Module')) {
class ET_Builder_Module_Image2 extends ET_Builder_Module {
function init() {
$this->name = __( 'Image_1', 'et_builder' );
$this->slug = 'et_pb_image2';
// a whole bunch of php code that defines how the class functions
}
}
$et_builder_module_image2 = new ET_Builder_Module_Image2();
add_shortcode( 'et_pb_image2', array($et_builder_module_image2, '_shortcode_callback') );
}
}
add_action('et_builder_ready', 'ex_divi_child_theme_setup');
I need to add fields to this custom module. How could i achieve this.
If you want to add your custom field in your custom module, you have to use "$this->whitelisted_fields" property and get_fields() function. ill give you some example that, how to add text field.
class ET_Builder_Module_Image2 extends ET_Builder_Module {
function init() {
$this->name = __( 'Image_1', 'et_builder' );
$this->slug = 'et_pb_image2';
// a whole bunch of php code that defines how the class functions
}
$this->whitelisted_fields = array(
'my_title',
);
function get_fields () {
$fields = array(
'my_title' => array(
'label' => __( 'My Title', 'wb' ),
'type' => 'text',
),
);
return $fields;
}
add your custom filed slug in whitelisted_fields propertys then add details in get_fields() function. i hope it will solve your problem.
I'm using this tutorial (http://projects.tareq.co/wp-generator/index.php) and its creator to generate a WordPress CRUD administration. The problem, however, already arises at the point where I'm adding the new menu button. The code says
add_action('init', 'init_conference');
function init_conference () {
include(dirname(__FILE__).'/includes/class-conference-events-admin-menu.php');
$menu_dgvs = new Conference_Events_Admin_Menu();
}
Which seems to call the corresponant __construct in that class:
class Conference_Events_Admin_Menu {
public function __construct() {
add_action( 'admin_menu', array( $this, 'admin_menu' ) );
}
public function admin_menu() {
// menu that does work
add_menu_page(__('Watu PRO', 'watupro'), __('Watu PRO', 'watupro'), WATUPRO_MANAGE_CAPS, "watupro_exams", 'watupro_exams');
// menu that does not work
add_menu_page( __( 'Konferenz', '' ), __( 'Konferenz', '' ), '', 'conference', array( $this, 'plugin_page' ), 'dashicons-groups', null );
add_submenu_page( 'conference', __( 'Konferenz', '' ), __( 'Konferenz', '' ), '', 'conference', array( $this, 'plugin_page' ) );
}
// here's some more code that has nothing to do with the menu
}
The first add_menu_page() is copied over from another plugin, it is shown as it should. The second is copied from the generator. It shows nothing, as if these calls weren't present.
What am I getting wrong here? I can't find a difference between the add_menu call from the other plugin and the generated one from the generator.
Thanks in advance.
Work on a problem for 5 hours, no solution, post to stackoverflow => solution found: it was the capabilities field. 'manage_options' in parameter 3 and everything works.
I am looking for a snippet function to replace the default "Edit Page" text that shows in the Wordpress toolbar.
I have disabled it on the backend altogether, because I am using a frontend builder for Editing pages and I want clients to understand which button does what. On the frontend I only have two options for an admin in the Toolbar > "Edit Page", "Edit Frontend". I want to change "Edit Page" to Edit Backend.
The "Edit Backend" text I think will suffice in the concept for where "Edit Page" would be "Edit Post", "Edit Product", etc. since the Frontend Builder handles all post types.
I would like a function snippet so I can leave the Wordpress core alone and updates are seamless.
I'm new here too, so thanks for listening and the help!
You have already helped me learn a lot from other searches, but I now officially have an account.
UPDATE:
I wanted this snippet to just reflect when viewing the frontend of the site while logged in. The official code I've used to achieve this is below.
(I just wrapped Dylan's code in the is_admin)
The reason for this was frontend editors. I want it to be simple on the frontend saying "Edit Frontend" or "Edit Backend".
// Change The Edit Toolbar Text "Edit" to "Edit Backend"
add_action('wp_before_admin_bar_render', 'change_admin_bar',999);
function change_admin_bar() {
if ( ! is_admin() ) {
global $wp_admin_bar;
$wp_admin_bar->remove_node('edit');
$args = array(
'id' => 'edit',
'title' => 'Edit Backend',
'href' => get_edit_post_link(),
);
$wp_admin_bar->add_node($args);
}
}
I'm not sure if I misunderstood the question, but from what I gathered, you actually wanted to change the text of the WordPress admin bar so I've written up some code that can be placed in your functions.php file to do just that.
add_action('wp_before_admin_bar_render', 'change_admin_bar',999);
function change_admin_bar() {
global $wp_admin_bar;
$wp_admin_bar->remove_node('edit');
$args = array(
'id' => 'edit',
'title' => 'Edit Backend',
'href' => get_edit_post_link(),
);
$wp_admin_bar->add_node($args);
}
Here are some sources for further research:
http://sumtips.com/2011/03/customize-wordpress-admin-bar.html
http://codex.wordpress.org/Plugin_API/Action_Reference/wp_before_admin_bar_render
http://codex.wordpress.org/Class_Reference/WP_Admin_Bar/add_node
This text is stored in post type labels. reference to available labels.
If you want to change labels of default post types you'll need to redeclare this post type with smth like this (example for changing posts label to "News"):
function yourprefix_change_post_label() {
global $menu;
global $submenu;
$menu[5][0] = 'Articles';
$submenu['edit.php'][5][0] = 'Articles';
$submenu['edit.php'][10][0] = 'Add Article';
$submenu['edit.php'][16][0] = 'Articles Tags';
echo '';
}
function yourprefix_change_post_object() {
global $wp_post_types;
$labels = &$wp_post_types['post']->labels;
$labels->name = 'Articles';
$labels->singular_name = 'Article';
$labels->add_new = 'Add Article';
$labels->add_new_item = 'Add Article';
$labels->edit_item = 'Edit Article';
$labels->new_item = 'New Article';
$labels->view_item = 'View Article';
$labels->search_items = 'Search Articles';
$labels->not_found = 'No Articles found';
$labels->not_found_in_trash = 'No Articles found in Trash';
$labels->all_items = 'All Articles';
$labels->menu_name = 'Articles';
$labels->name_admin_bar = 'Articles';
}
add_action( 'admin_menu', 'yourprefix_change_post_label' );
add_action( 'init', 'yourprefix_change_post_object' );
you can refer to this article for more details.