forked from fusillicode/amr-shortcode-any-widget
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathamr-shortcode-any-widget.php
More file actions
326 lines (255 loc) · 12.9 KB
/
amr-shortcode-any-widget.php
File metadata and controls
326 lines (255 loc) · 12.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
<?php
/*
Plugin Name: amr shortcode any widget
Plugin URI: http://webdesign.anmari.com/shortcode-any-widget/
Description: Include any widget in a page for any theme. [do_widget widgetname ] or [do_widget "widget name" ] or include a whole widget area [do_widget_area]. If upgrading see changelog. Can be very powerful eg: with queryposts widget it can become a templater.
Author: anmari
Version: 2.2
Author URI: http://webdesign.anmari.com
*/
function amr_remove_widget_class($params) { // remove the widget classes
if (!empty($params[0]['before_widget'])) {
$params[0]['before_widget'] =
str_replace ('"widget ','"',$params[0]['before_widget']);
}
if (!empty($params[0]['before_title'])) {
$params[0]['before_title'] =
$params[0]['before_title'] = str_replace ('widget-title','',$params[0]['before_title']);
}
return ($params);
}
/*-----------------------------------*/
function do_widget_area($atts) {
global $wp_registered_widgets, $_wp_sidebars_widgets, $wp_registered_sidebars;
extract(shortcode_atts(array(
'widget_area' => 'widgets_for_shortcodes',
'class' => 'amr_widget_area', /* the widget class is picked up automatically. If we want to add an additional class at the wrap level to try to match a theme, use this */
'widget_area_class' => '', /* option to disassociate from themes widget styling use =none*/
'widget_classes' => '' /* option to disassociate from themes widget styling */
), $atts));
$class = "class=\"amr-widget-area {$class}";
if (empty($widget_area_class) or !($widget_area_class=='none'))
$class .= ' widget-area"';
$output = PHP_EOL.'<div id="'.$widget_area.'" '.$class. '>';
if (!empty($widget_classes) and ($widget_classes=='none'))
add_filter('dynamic_sidebar_params','amr_remove_widget_class');
ob_start(); /* catch the echo output, so we can control where it appears in the text */
dynamic_sidebar($widget_area);
$output .= ob_get_clean();
remove_filter('dynamic_sidebar_params','amr_remove_widget_class');
$output .= '</div>'.PHP_EOL;
return ($output);
}
/*-----------------------------------*/
function do_widget($atts) {
global $wp_registered_widgets, $_wp_sidebars_widgets, $wp_registered_sidebars;
/* check if the widget is in the shortcode x sidebar if not , just use generic,
if it is in, then get the instance data and use that */
if (isset($_wp_sidebars_widgets) ) {
amr_show_widget_debug('which one'); //check for debug prompt and show widgets in shortcode sidebar if requested and logged in etc
}
else {
echo '<br />No widgets defined at all in any sidebar!';
return (false);
}
extract(shortcode_atts(array(
'sidebar' => 'Widgets for Shortcodes',
'id' => '',
'name' => '', /* MKM added explicit 'name' attribute. For existing users we still need to allow prev method, else too many support queries will happen */
'title' => '', /* do the default title unless they ask us not to - use string here not boolean */
'class' => 'amr_widget', /* the widget class is picked up automatically. If we want to add an additional class at the wrap level to try to match a theme, use this */
'wrap' => '', /* wrap the whole thing - title plus widget in a div - maybe the themes use a div, maybe not, maybe we want that styling, maybe not */
'widget_classes' => '' /* option to disassociate from themes widget styling */
), $atts));
/* compatibility check - if the name is not entered, then the first parameter is the name */
if (empty($name) and !empty($atts[0]))
$name = $atts[0];
/* the widget need not be specified, [do_widget widgetname] is adequate */
if (!empty($name)) { // we have a name
$widget = $name;
foreach ($wp_registered_widgets as $i => $w) { /* get the official internal name or id that the widget was registered with */
if (strtolower($w['name']) === strtolower($widget)) $widget_ids[] = $i;
//if ($debug) {echo '<br /> Check: '.$w['name'];}
}
}
else { /* check for id if we do not have a name */
if (!empty($id)) { /* if a specific id has been specified */
foreach ($wp_registered_widgets as $i => $w) { /* get the official internal name or id that the widget was registered with */
if ($w['id'] === $id) $widget_ids[] = $id;
}
//if ($debug) { echo '<h2>We have an id: '.$id.'</h2>'; if (!empty($widget_ids)) var_dump($widget_ids); }
}
else {
echo '<br />No valid widget name or id given in shortcode parameters';
return (false);
}
}
if (empty ($widget_ids)) {
echo '<br /><a href="" title="Error: Your Requested widget '.$widget.' '.$id.' is not in the widget list. Typo maybe?">!</a><br />';
amr_show_widget_debug('empty', $atts);
return (false) ;
}
if (!($sidebarid = get_sidebar_id ($sidebar)))
$sidebarid=$sidebar; /* get the official sidebar id for this widget area - will take the first one */
if (empty($widget))
$widget = '';
$content = '';
/* if the widget is in our chosen sidebar, then use the options stored for that */
if ((!isset ($_wp_sidebars_widgets[$sidebarid])) or (empty ($_wp_sidebars_widgets[$sidebarid]))) { // try upgrade
amr_upgrade_sidebar();
}
if ((isset ($_wp_sidebars_widgets[$sidebarid])) and (!empty ($_wp_sidebars_widgets[$sidebarid]))) {
/* if ($debug) {
echo '<br />Widget ids in sidebar: "'.$sidebar.'" with id: '.$sidebarid .'<br />';
sort ($_wp_sidebars_widgets[$sidebarid]);
foreach ($_wp_sidebars_widgets[$sidebarid] as $i=> $w) {
echo $i.' '.$w.'<br />';
};
}
*/
/* get the intersect of the 2 widget setups so we just get the widget we want */
$wid = array_intersect ($_wp_sidebars_widgets[$sidebarid], $widget_ids );
/* if ($debug) { echo '<br />Will use widget ids'.'<br />';
foreach ($widget_ids as $i=> $w) {
echo ' '.$w.'<br />';
};
}
*/
}
else { /* the sidebar is not defined */
//if ($debug) {
echo '<br /><a href="" title="Error: Sidebar '.$sidebar.' with sidebarid '.$sidebarid.' is empty (no widgets) or is not defined.">!</a><br />';
//}
}
$output = '';
if (empty ($wid) or (!is_array($wid)) or (count($wid) < 1)) {
//if ($debug) {
echo '<br /><a href="" title="Error: Your requested Widget '.$widget.' is not in the '.$sidebar.' sidebar ">!</a><br />';
amr_show_widget_debug('empty', $atts);
//}
unset($sidebar);
unset($sidebarid);
}
else {
/* There may only be one but if we have two in our chosen widget then it will do both */
$output = '';
foreach ($wid as $i=>$widget_instance) {
ob_start(); /* catch the echo output, so we can control where it appears in the text */
shortcode_sidebar($widget_instance, $sidebar, $title, $class, $wrap, $widget_classes);
$output .= ob_get_clean();
}
}
return ($output);
}
/* -------------------------------------------------------------------------*/
function shortcode_sidebar( $widget_id, $name="widgets_for_shortcode", $title=true, $class='', $wrap='', $widget_classes='') { /* This is basically the wordpress code, slightly modified */
global $wp_registered_sidebars, $wp_registered_widgets;
$debug = amr_check_if_widget_debug();
$sidebarid = get_sidebar_id ($name);
$sidebars_widgets = wp_get_sidebars_widgets();
$sidebar = $wp_registered_sidebars[$sidebarid]; // has the params etc
$did_one = false;
/* lifted from wordpress code, keep as similar as possible for now */
if ( !isset($wp_registered_widgets[$widget_id]) ) continue;
$params = array_merge(
array(
array_merge( $sidebar,
array('widget_id' => $widget_id,
'widget_name' => $wp_registered_widgets[$widget_id]['name']) ) ),
(array) $wp_registered_widgets[$widget_id]['params']
);
$validtitletags = array ('h1','h2','h3','h4','h5','header','strong','em');
$validwraptags = array ('div','p','main','aside','section');
if (!empty($wrap)) { /* then folks want to 'wrap' with their own html tag, or wrap = yes */
if ((!in_array( $wrap, $validwraptags)))
$wrap = '';
/* To match a variety of themes, allow for a variety of html tags. */
/* May not need if our sidebar match attempt has worked */
}
if (!empty ($wrap)) {
$params[0]['before_widget'] = '<'.$wrap.' id="%1$s" class="%2$s">';
$params[0]['after_widget'] = '</'.$wrap.'>';
}
// wp code to get classname
$classname_ = '';
//foreach ( (array) $wp_registered_widgets[$widget_id]['classname'] as $cn ) {
$cn = $wp_registered_widgets[$widget_id]['classname'];
if ( is_string($cn) )
$classname_ .= '_' . $cn;
elseif ( is_object($cn) )
$classname_ .= '_' . get_class($cn);
//}
$classname_ = ltrim($classname_, '_');
// add MKM and others requested class in to the wp classname string
// if no class specfied, then class will = amrwidget. These classes are so can reverse out unwanted widget styling.
// $classname_ .= ' widget '; // wordpress seems to almost always adds the widget class
$classname_ .= ' '.$class;
// we are picking up the defaults from the thems sidebar ad they have registered heir sidebar to issue widget classes?
// Substitute HTML id and class attributes into before_widget
if (!empty($params[0]['before_widget']))
$params[0]['before_widget'] = sprintf($params[0]['before_widget'], $widget_id, $classname_);
else
$params[0]['before_widget'] = '';
if (empty($params[0]['before_widget']))
$params[0]['after_widget'] = '';
$params = apply_filters( 'dynamic_sidebar_params', $params );
// allow, any pne usingmust ensure they apply to the correct sidebars
if (!empty($title)) {
if ($title=='false') { /* amr switch off the title html, still need to get rid of title separately */
$params[0]['before_title'] = '<span style="display: none">';
$params[0]['after_title'] = '</span>';
}
else {
if (in_array( $title, $validtitletags)) {
$class = ' class="widget-title" ';
$params[0]['before_title'] = '<'.$title.' '.$class.' >';
$params[0]['after_title'] = '</'.$title.'>';
}
}
}
if (!empty($widget_classes) and ($widget_classes == 'none') ) {
$params = amr_remove_widget_class($params); // also called in widget area shortcode
}
$callback = $wp_registered_widgets[$widget_id]['callback'];
if ( is_callable($callback) ) {
call_user_func_array($callback, $params);
$did_one = true;
}
// }
return $did_one;
}
/* -------------------------------------------------------------------------------------------------------------*/
function amr_reg_sidebar() { // this is fired late, so hopefully any theme sidebars will have been registered already.
global $wp_registered_widgets, $_wp_sidebars_widgets, $wp_registered_sidebars;
if ( function_exists('register_sidebar') ) { // maybe later, get the first main sidebar and copy it's before/after etc
$args = array(
'name' =>'Widgets for Shortcodes',
'id' => 'widgets_for_shortcodes', // hope to avoid losing widgets
'description' => 'Sidebar to hold widgets and their settings. These widgets will be used in a shortcode. This sidebars widgets should be saved with your theme settings now.',
'before_widget' => '<aside'.' id="%1$s" class="%2$s ">', // 201402 to match twentyfourteen theme
'after_widget' => '</aside>',
'before_title' => '<h1 class="widget-title" >', // 201402 maybe dont use widget class - we are in content here not in a widget area but others want the widget styling. ?
'after_title' => '</h1>' );
if (!empty($wp_registered_sidebars)) { // we got some sidebars already.
$main_sidebar = reset($wp_registered_sidebars); // Grab the first sidebar and use that as defaults for the widgets
$args['before_widget'] = $main_sidebar['before_widget'];
$args['after_widget'] = $main_sidebar['after_widget'];
$args['before_title'] = $main_sidebar['before_title'];
$args['after_title'] = $main_sidebar['after_title'];
}
register_sidebar($args);
}
//else { echo '<h1>CANNOT REGISTER widgets_for_shortcodes SIDEBAR</h1>';}
}
/*-----------------------------------*/
include ('amr-admin-form-html.php');
include ('amr-utilities.php');
if (is_admin() ) $amr_saw_plugin_admin = new amr_saw_plugin_admin();
add_action('widgets_init', 'amr_reg_sidebar',98); // register late so it appears last
//add_action('widgets_init', 'amr_upgrade_sidebar',99); // copy old shortcodes sidebar to new one if necessary
//add_action('switch_theme', 'amr_save_shortcodes_sidebar');
//add_action('after_switch_theme','amr_restore_shortcodes_sidebar');
add_shortcode('do_widget', 'do_widget');
add_shortcode('do_widget_area', 'do_widget_area'); // just dump the whole widget area - to get same styling
//require_once(ABSPATH . 'wp-includes/widgets.php'); // *** do we really need this here?
?>