I'm trying to implement a custom widget in wordpress 5.2.1, but the widget is not actually added to the sidebar and lost again after reload.
This is my widget code:
class DW_Center_Address_Widget extends WP_Widget {
const ID = 'dw-center-address';
var $formDefinition;
function __construct() {
parent::__construct(
self::ID,
// name of the widget
Connector::get_translation('DW Center Address'),
// widget options
array (
'description' => Connector::get_translation( 'Displays the address of a Center stored in the SSO.' )
)
);
$this->formDefinition = [
[
'type' => 'info',
'label' => Connector::get_translation("Change Center data at the:") . '<br/>' . '<a target="_blank" class="button" style="margin-top: 10px;" href="the.sso">' . Connector::get_translation('SSO') . '</a>'
],
[
'type' => 'text',
'key' => Shortcodes::ATTR_SLUG,
'id' => $this->get_field_id(Shortcodes::ATTR_SLUG),
'name' => $this->get_field_name(Shortcodes::ATTR_SLUG),
'label' => Connector::get_translation('Center Slug or Id'),
'value' => '' // the default value
]
];
}
function form( $instance ) {
for ($i = 0; $i < count($this->formDefinition); $i++) {
if (array_key_exists('key', $this->formDefinition[$i])) {
$key = $this->formDefinition[$i]['key'];
if (array_key_exists($key, $instance)) {
$this->formDefinition[$i]['value'] = $instance[$this->formDefinition[$i]['key']];
}
}
}
// generates the form html
echo Template::render('admin/forms/widget_form.html.twig', [
'form' => $this->formDefinition
]);
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
foreach ($this->formDefinition as $def) {
if (array_key_exists('key', $def)) {
$instance[ $def['key'] ] = trim($new_instance[ $def['key']]);
}
}
return $instance;
}
function widget( $args, $instance ) {
echo Shortcodes::dw_center($args);
}
}
By everything I could see in other places, it should work, but it does not...
I'm trying to implement a custom widget in wordpress 5.2.1, but the widget is not actually added to the sidebar and lost again after reload.
This is my widget code:
class DW_Center_Address_Widget extends WP_Widget {
const ID = 'dw-center-address';
var $formDefinition;
function __construct() {
parent::__construct(
self::ID,
// name of the widget
Connector::get_translation('DW Center Address'),
// widget options
array (
'description' => Connector::get_translation( 'Displays the address of a Center stored in the SSO.' )
)
);
$this->formDefinition = [
[
'type' => 'info',
'label' => Connector::get_translation("Change Center data at the:") . '<br/>' . '<a target="_blank" class="button" style="margin-top: 10px;" href="the.sso">' . Connector::get_translation('SSO') . '</a>'
],
[
'type' => 'text',
'key' => Shortcodes::ATTR_SLUG,
'id' => $this->get_field_id(Shortcodes::ATTR_SLUG),
'name' => $this->get_field_name(Shortcodes::ATTR_SLUG),
'label' => Connector::get_translation('Center Slug or Id'),
'value' => '' // the default value
]
];
}
function form( $instance ) {
for ($i = 0; $i < count($this->formDefinition); $i++) {
if (array_key_exists('key', $this->formDefinition[$i])) {
$key = $this->formDefinition[$i]['key'];
if (array_key_exists($key, $instance)) {
$this->formDefinition[$i]['value'] = $instance[$this->formDefinition[$i]['key']];
}
}
}
// generates the form html
echo Template::render('admin/forms/widget_form.html.twig', [
'form' => $this->formDefinition
]);
}
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
foreach ($this->formDefinition as $def) {
if (array_key_exists('key', $def)) {
$instance[ $def['key'] ] = trim($new_instance[ $def['key']]);
}
}
return $instance;
}
function widget( $args, $instance ) {
echo Shortcodes::dw_center($args);
}
}
By everything I could see in other places, it should work, but it does not...
Share Improve this question asked May 28, 2019 at 11:01 AndreasAndreas 2412 silver badges5 bronze badges 2 |1 Answer
Reset to default 0Alright, so I found it after some sleepless hours:
- The call to
$this->get_field_id($key)
in the Widget constructor was a mistake. It has to happen during thefunction form()
(probably due to some usage of global variables* ) - Most of the pain came from the fact, that it did not save the widget in the sidebar. The reason for this was, that it was all getting messed up during development in the database. Wordpress seems to expect a certain order between the
id_base
and the actual created instances in the database. If you want a clear picture, try to change theid_base
to something fresh.
The working code in the end:
class DW_Center_Address_Widget extends WP_Widget {
// I changed the id_base a couple of times
const ID = 'dwbn-center-address-3';
var $formDefinition;
var $widgetArguments = [];
function __construct() {
//Constructor
$widget_ops = array('classname' => self::ID, 'description' => Connector::get_translation( 'Displays the address of a Center stored in the SSO.' ) );
parent::__construct( self::ID, Connector::get_translation('DW Center Address'), $widget_ops );
$this->formDefinition = [
// a title field makes the wordpress widget definetly more usefull, it will display this value in gray
[
'type' => 'text',
'key' => Shortcodes::ATTR_TITLE,
'label' => __('Title'), // just take the standard translation
'value' => '' // the default value
],
[
'type' => 'info',
'label' => Connector::get_translation("Change Center data at the:") . '<br/>' . '<a target="_blank" class="button" style="margin-top: 10px;" href="the.sso">' . Connector::get_translation('SSO') . '</a>'
],
[
'type' => 'text',
'key' => Shortcodes::ATTR_SLUG,
'label' => Connector::get_translation('Center Slug or Id'),
'value' => '' // the default value
]
];
foreach ($this->formDefinition as $def) {
if (array_key_exists('key', $def)) {
$this->widgetArguments[$def['key']] = array_key_exists('value', $def) ? $def['value'] : '';
}
}
}
/**
* @param array $args - holds context information
* @param array $instance - the actual parameters
*/
function widget($args, $instance) {
echo Shortcodes::dw_center($instance);
}
function update($new_instance, $old_instance) {
$instance = [];
foreach ($this->widgetArguments as $key => $val) {
$instance[ $key ] = trim(strip_tags($new_instance[ $key ]));
}
return $instance;
}
function form( $instance ) {
$instance = wp_parse_args( (array) $instance, $this->widgetArguments );
$form = [];
for ($i = 0; $i < count($this->formDefinition); $i++) {
$form[] = $this->formDefinition[$i];
if (array_key_exists('key', $form[$i])) {
$key = $form[$i]['key'];
if (array_key_exists($key, $instance)) {
$form[$i]['value'] = $instance[$key];
}
// it is important, that this functions are called during runtime, otherwise the widget ids will not be correct
$form[$i]['id'] = $this->get_field_id($key);
$form[$i]['name'] = $this->get_field_name($key);
}
}
echo Template::render('admin/forms/widget_form.html.twig', [
'form' => $form
]);
}
}
* this is jet one more example why not to rely on a global namespace - wordpress will not change, but if you ever build a new system that millions of people will use, please try to avoid it ;).
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745454551a4628424.html
/wp-admin/admin-ajax.php
returns a 200. – Andreas Commented May 28, 2019 at 23:46