Version Description
- Mai 17th 2019 =
- 'Load more' button / Ajax API
- Data range filter
- Text, if there is no post
- Excerpt length in lines (line-clamp)
- Image crop with CSS (object-fit)
- Fluid images (max-width in %).
- One thumb dimension can be left empty
- Admin UI: Button to easy add post details placeholder
- Admin UI: Set / find thumbnail size buttons: +, , , 2x, -, ratio and Media sizes
Download this release
Release Info
Developer | Kometschuh |
Plugin | Category Posts Widget |
Version | 4.9.1 |
Comparing to | |
See all releases |
Code changes from version 4.8.5 to 4.9.1
- cat-posts.php +176 -2253
- class-shortcode-control.php +62 -0
- class-virtual-widget.php +412 -0
- class-virtual-widgets-repository.php +89 -0
- class-widget.php +1685 -0
- gulpfile.js +16 -0
- js/admin/category-posts-widget.js +219 -9
- js/admin/category-posts-widget.min.js +1 -0
- js/admin/tinymce.min.js +1 -0
- js/frontend/category-posts-frontend.min.js +1 -0
- js/frontend/date.js +49 -0
- js/frontend/date.min.js +1 -0
- js/frontend/loadmore.js +50 -0
- js/frontend/loadmore.min.js +1 -0
- loadmore.php +90 -0
- localizeddate.php +30 -0
- readme.txt +55 -70
- styles/admin/category-posts-widget.css +190 -0
cat-posts.php
CHANGED
@@ -12,7 +12,7 @@ Plugin Name: Category Posts Widget
|
|
12 |
Plugin URI: https://wordpress.org/plugins/category-posts/
|
13 |
Description: Adds a widget that shows the most recent posts from a single category.
|
14 |
Author: TipTopPress
|
15 |
-
Version: 4.
|
16 |
Author URI: http://tiptoppress.com
|
17 |
Text Domain: category-posts
|
18 |
Domain Path: /languages
|
@@ -25,14 +25,20 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
25 |
exit;
|
26 |
}
|
27 |
|
28 |
-
const VERSION = '4.
|
29 |
-
const DOC_URL = 'http://tiptoppress.com/category-posts-widget/documentation-4-
|
30 |
-
const PRO_URL = 'http://tiptoppress.com/term-and-category-based-posts-widget
|
31 |
-
const SUPPORT_URL = 'https://wordpress.org/support/plugin/category-posts';
|
32 |
const SHORTCODE_NAME = 'catposts';
|
33 |
const SHORTCODE_META = 'categoryPosts-shorcode';
|
34 |
const WIDGET_BASE_ID = 'category-posts';
|
35 |
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
/**
|
37 |
* Adds the "Customize" link to the Toolbar on edit mode.
|
38 |
*
|
@@ -79,7 +85,7 @@ add_action( 'admin_bar_menu', __NAMESPACE__ . '\wp_admin_bar_customize_menu', 35
|
|
79 |
*/
|
80 |
function wp_head() {
|
81 |
|
82 |
-
$widget_repository = new
|
83 |
|
84 |
$styles = array();
|
85 |
|
@@ -93,7 +99,7 @@ function wp_head() {
|
|
93 |
|
94 |
if ( ! empty( $styles ) ) {
|
95 |
?>
|
96 |
-
<style
|
97 |
<?php
|
98 |
foreach ( $styles as $rules ) {
|
99 |
foreach ( $rules as $rule ) {
|
@@ -119,20 +125,20 @@ function register_virtual_widgets() {
|
|
119 |
global $post;
|
120 |
global $wp_registered_widgets;
|
121 |
|
122 |
-
$repository = new
|
123 |
|
124 |
// check first for shortcode settings.
|
125 |
if ( is_singular() ) {
|
126 |
$names = shortcode_names( SHORTCODE_NAME, $post->post_content );
|
127 |
|
128 |
foreach ( $names as $name ) {
|
129 |
-
$meta = shortcode_settings( $name );
|
130 |
if ( is_array( $meta ) ) {
|
131 |
$id = WIDGET_BASE_ID . '-shortcode-' . get_the_ID(); // needed to make a unique id for the widget html element.
|
132 |
if ( '' !== $name ) { // if not default name append to the id.
|
133 |
$id .= '-' . sanitize_title( $name ); // sanitize to be on the safe side, not sure where when and how this will be used.
|
134 |
}
|
135 |
-
$repository->addShortcode( $name, new
|
136 |
}
|
137 |
}
|
138 |
}
|
@@ -153,7 +159,7 @@ function register_virtual_widgets() {
|
|
153 |
$widgetclass = new $class();
|
154 |
$allsettings = $widgetclass->get_settings();
|
155 |
$settings = isset( $allsettings[ str_replace( $widget_base . '-', '', $widget ) ] ) ? $allsettings[ str_replace( $widget_base . '-', '', $widget ) ] : false;
|
156 |
-
$repository->addWidget( $widget, new
|
157 |
}
|
158 |
}
|
159 |
}
|
@@ -163,6 +169,34 @@ function register_virtual_widgets() {
|
|
163 |
|
164 |
add_action( 'wp_head', __NAMESPACE__ . '\wp_head' );
|
165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
/**
|
167 |
* Enqueue widget related scripts for the widget admin page and customizer.
|
168 |
*
|
@@ -170,10 +204,18 @@ add_action( 'wp_head', __NAMESPACE__ . '\wp_head' );
|
|
170 |
*/
|
171 |
function admin_scripts( $hook ) {
|
172 |
|
173 |
-
if ( 'widgets.php' === $hook || 'post.php' === $hook
|
174 |
|
175 |
-
|
176 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
wp_enqueue_script( 'category-posts-widget-admin-js' );
|
178 |
|
179 |
$js_data = array( 'accordion' => false );
|
@@ -209,125 +251,19 @@ function load_textdomain() {
|
|
209 |
load_plugin_textdomain( 'category-posts', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );
|
210 |
}
|
211 |
|
212 |
-
/*
|
213 |
-
* Add styles for widget sections
|
214 |
-
*/
|
215 |
-
|
216 |
-
add_action( 'admin_print_styles-widgets.php', __NAMESPACE__ . '\admin_styles' );
|
217 |
-
|
218 |
-
// fix make widget SiteOrigin Page Builder plugin, GH issue #181
|
219 |
-
add_action('siteorigin_panel_enqueue_admin_scripts', __NAMESPACE__ . '\admin_styles' );
|
220 |
-
|
221 |
/**
|
222 |
-
* Add
|
223 |
*
|
224 |
* @since 4.1
|
225 |
**/
|
226 |
function admin_styles() {
|
227 |
-
|
228 |
-
<style>
|
229 |
-
.category-widget-cont h4 {
|
230 |
-
padding: 12px 15px;
|
231 |
-
cursor: pointer;
|
232 |
-
margin: 5px 0;
|
233 |
-
border: 1px solid #E5E5E5;
|
234 |
-
}
|
235 |
-
.category-widget-cont h4:first-child {
|
236 |
-
margin-top: 10px;
|
237 |
-
}
|
238 |
-
.category-widget-cont h4:last-of-type {
|
239 |
-
margin-bottom: 10px;
|
240 |
-
}
|
241 |
-
.category-widget-cont h4:after {
|
242 |
-
float:right;
|
243 |
-
font-family: "dashicons";
|
244 |
-
content: '\f140';
|
245 |
-
-ms-transform: translate(-1px,1px);
|
246 |
-
-webkit-transform: translate(-1px,1px);
|
247 |
-
-moz-transform: translate(-1px,1px);
|
248 |
-
transform: translate(-1px,1px);
|
249 |
-
-ms-transition: all 600ms;
|
250 |
-
-webkit-transition: all 600ms;
|
251 |
-
-moz-transition: all 600ms;
|
252 |
-
transition: all 600ms;
|
253 |
-
}
|
254 |
-
.category-widget-cont h4.open:after {
|
255 |
-
-ms-transition: all 600ms;
|
256 |
-
-webkit-transition: all 600ms;
|
257 |
-
-moz-transition: all 600ms;
|
258 |
-
transition: all 600ms;
|
259 |
-
-ms-transform: rotate(180deg);
|
260 |
-
-webkit-transform: rotate(180deg);
|
261 |
-
-moz-transform: rotate(180deg);
|
262 |
-
transform: rotate(180deg);
|
263 |
-
}
|
264 |
-
.category-widget-cont > div {
|
265 |
-
display:none;
|
266 |
-
}
|
267 |
-
.category-widget-cont > div.open {
|
268 |
-
display:block;
|
269 |
-
}
|
270 |
-
.category-widget-cont th,
|
271 |
-
.category-widget-cont tr {
|
272 |
-
vertical-align: baseline;
|
273 |
-
text-align:start;
|
274 |
-
}
|
275 |
-
|
276 |
-
.cat-post-template-help {display:none;}
|
277 |
-
|
278 |
-
.categoryPosts-template textarea {width:100%}
|
279 |
-
|
280 |
-
.category-widget-cont .open-template-help {
|
281 |
-
border:0;
|
282 |
-
padding:0;
|
283 |
-
cursor: pointer;
|
284 |
}
|
285 |
|
286 |
-
|
287 |
-
<?php
|
288 |
-
}
|
289 |
-
|
290 |
-
/**
|
291 |
-
* Get image size
|
292 |
-
*
|
293 |
-
* @param int $thumb_w The width of the thumbnail in the widget settings.
|
294 |
-
* @param int $thumb_h The height of the thumbnail in the widget settings.
|
295 |
-
* @param int $image_w The width of the actual image being displayed.
|
296 |
-
* @param int $image_h The height of the actual image being displayed.
|
297 |
-
*
|
298 |
-
* @return array An array with the width and height of the element containing the image
|
299 |
-
*/
|
300 |
-
function get_image_size( $thumb_w, $thumb_h, $image_w, $image_h ) {
|
301 |
-
|
302 |
-
$image_size = array(
|
303 |
-
'image_h' => $thumb_h,
|
304 |
-
'image_w' => $thumb_w,
|
305 |
-
'marginAttr' => '',
|
306 |
-
'marginVal' => '',
|
307 |
-
);
|
308 |
-
$relation_thumbnail = $thumb_w / $thumb_h;
|
309 |
-
$relation_cropped = $image_w / $image_h;
|
310 |
-
|
311 |
-
if ( $relation_thumbnail < $relation_cropped ) {
|
312 |
-
// crop left and right site
|
313 |
-
// thumbnail width/height ration is smaller, need to inflate the height of the image to thumb height
|
314 |
-
// and adjust width to keep aspect ration of image.
|
315 |
-
$image_size['image_h'] = $thumb_h;
|
316 |
-
$image_size['image_w'] = $thumb_h / $image_h * $image_w;
|
317 |
-
$image_size['marginAttr'] = 'margin-left';
|
318 |
-
$image_size['marginVal'] = ( $image_size['image_w'] - $thumb_w ) / 2;
|
319 |
-
} else {
|
320 |
-
// crop top and bottom
|
321 |
-
// thumbnail width/height ration is bigger, need to inflate the width of the image to thumb width
|
322 |
-
// and adjust height to keep aspect ration of image.
|
323 |
-
$image_size['image_w'] = $thumb_w;
|
324 |
-
$image_size['image_h'] = $thumb_w / $image_w * $image_h;
|
325 |
-
$image_size['marginAttr'] = 'margin-top';
|
326 |
-
$image_size['marginVal'] = ( $image_size['image_h'] - $thumb_h ) / 2;
|
327 |
-
}
|
328 |
|
329 |
-
|
330 |
-
|
331 |
|
332 |
/**
|
333 |
* Get the tags which might be used in the template.
|
@@ -363,6 +299,45 @@ function get_template_regex() {
|
|
363 |
return $regexp;
|
364 |
}
|
365 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
366 |
/**
|
367 |
* Convert pre 4.8 settings into template
|
368 |
*
|
@@ -410,1537 +385,6 @@ function convert_settings_to_template( $instance ) {
|
|
410 |
return $template;
|
411 |
}
|
412 |
|
413 |
-
/**
|
414 |
-
* Category Posts Widget Class
|
415 |
-
*
|
416 |
-
* Shows the single category posts with some configurable options
|
417 |
-
*/
|
418 |
-
class Widget extends \WP_Widget {
|
419 |
-
|
420 |
-
/**
|
421 |
-
* Widget constructor.
|
422 |
-
*/
|
423 |
-
public function __construct() {
|
424 |
-
$widget_ops = array(
|
425 |
-
'classname' => 'cat-post-widget',
|
426 |
-
'description' => __( 'List single category posts', 'category-posts' ),
|
427 |
-
);
|
428 |
-
parent::__construct( WIDGET_BASE_ID, __( 'Category Posts', 'category-posts' ), $widget_ops );
|
429 |
-
}
|
430 |
-
|
431 |
-
/**
|
432 |
-
* Calculate the HTML for showing the thumb of a post item.
|
433 |
-
*
|
434 |
-
* Used as a filter for the thumb wordpress API to add css based stretching and cropping
|
435 |
-
* when the image is not at the requested dimensions
|
436 |
-
*
|
437 |
-
* @param string $html The original HTML generated by the core APIS.
|
438 |
-
* @param int $post_id the ID of the post of which the thumb is a featured image.
|
439 |
-
* @param int $post_thumbnail_id The id of the featured image attachment.
|
440 |
-
* @param string|array $size The requested size identified by name or (width, height) array.
|
441 |
-
* @param mixed $attr ignored in this context.
|
442 |
-
* @return string The HTML for the thumb related to the post
|
443 |
-
*
|
444 |
-
* @since 4.1
|
445 |
-
*/
|
446 |
-
public function post_thumbnail_html( $html, $post_id, $post_thumbnail_id, $size, $attr ) {
|
447 |
-
|
448 |
-
$use_css_cropping = isset( $this->instance['use_css_cropping'] ) && $this->instance['use_css_cropping'];
|
449 |
-
$empty_dimensions = empty( $this->instance['thumb_w'] ) || empty( $this->instance['thumb_h'] );
|
450 |
-
$thumb = isset( $this->instance['template'] ) && preg_match( '/%thumb%/', $this->instance['template'] );
|
451 |
-
|
452 |
-
if ( ! ( $use_css_cropping && ! $empty_dimensions && $thumb ) ) {
|
453 |
-
return $html; // If no full dimensions defined, just do not cropping for that image
|
454 |
-
}
|
455 |
-
$meta = image_get_intermediate_size( $post_thumbnail_id, $size );
|
456 |
-
|
457 |
-
if ( empty( $meta ) ) {
|
458 |
-
$post_img = wp_get_attachment_metadata( $post_thumbnail_id, $size );
|
459 |
-
$meta['file'] = basename( $post_img['file'] );
|
460 |
-
}
|
461 |
-
|
462 |
-
$origfile = get_attached_file( $post_thumbnail_id, true ); // the location of the full file.
|
463 |
-
$file = dirname( $origfile ) . '/' . $meta['file']; // the location of the file displayed as thumb.
|
464 |
-
if ( file_exists( $file ) ) {
|
465 |
-
list( $width, $height ) = getimagesize( $file ); // get actual size of the thumb file.
|
466 |
-
|
467 |
-
if ( isset( $this->instance['use_css_cropping'] ) && $this->instance['use_css_cropping'] ) {
|
468 |
-
$image = get_image_size( $this->instance['thumb_w'], $this->instance['thumb_h'], $width, $height );
|
469 |
-
|
470 |
-
// replace srcset.
|
471 |
-
$array = array();
|
472 |
-
preg_match( '/width="([^"]*)"/i', $html, $array );
|
473 |
-
$pattern = '/' . $array[1] . 'w/';
|
474 |
-
$html = preg_replace( $pattern, $image['image_w'] . 'w', $html );
|
475 |
-
// replace size.
|
476 |
-
$pattern = '/' . $array[1] . 'px/';
|
477 |
-
$html = preg_replace( $pattern, $image['image_w'] . 'px', $html );
|
478 |
-
// replace width.
|
479 |
-
$pattern = '/width="[0-9]*"/';
|
480 |
-
$html = preg_replace( $pattern, "width='" . $image['image_w'] . "'", $html );
|
481 |
-
// replace height.
|
482 |
-
$pattern = '/height="[0-9]*"/';
|
483 |
-
$html = preg_replace( $pattern, "height='" . $image['image_h'] . "'", $html );
|
484 |
-
// set margin.
|
485 |
-
$html = str_replace( '<img ', '<img style="' . $image['marginAttr'] . ':-' . $image['marginVal'] . 'px;height:' . $image['image_h']
|
486 |
-
. 'px;clip:rect(auto,' . ( $this->instance['thumb_w'] + $image['marginVal'] ) . 'px,auto,' . $image['marginVal']
|
487 |
-
. 'px);width:auto;max-width:initial;" ', $html );
|
488 |
-
// wrap span with post format.
|
489 |
-
$show_post_format = isset( $this->instance['show_post_format'] ) && ( 'none' !== $this->instance['show_post_format'] );
|
490 |
-
if ( $show_post_format || $this->instance['thumb_hover'] ) {
|
491 |
-
$format = get_post_format() ? : 'standard';
|
492 |
-
$post_format_class = 'cat-post-format cat-post-format-' . $format;
|
493 |
-
}
|
494 |
-
$html = '<span class="cat-post-crop ' . $post_format_class . '" style="width:' . $this->instance['thumb_w'] . 'px;height:' . $this->instance['thumb_h'] . 'px;">'
|
495 |
-
. $html . '</span>';
|
496 |
-
} else {
|
497 |
-
// use_css_cropping is not used.
|
498 |
-
// wrap span.
|
499 |
-
$html = '<span>' . $html . '</span>';
|
500 |
-
}
|
501 |
-
}
|
502 |
-
return $html;
|
503 |
-
}
|
504 |
-
|
505 |
-
/*
|
506 |
-
* wrapper to execute the the_post_thumbnail with filters.
|
507 |
-
*/
|
508 |
-
/**
|
509 |
-
* Calculate the HTML for showing the thumb of a post item.
|
510 |
-
*
|
511 |
-
* It is a wrapper to execute the the_post_thumbnail with filters
|
512 |
-
*
|
513 |
-
* @param string|array $size The requested size identified by name or (width, height) array.
|
514 |
-
*
|
515 |
-
* @return string The HTML for the thumb related to the post and empty string if it can not be calculated
|
516 |
-
*
|
517 |
-
* @since 4.1
|
518 |
-
*/
|
519 |
-
public function the_post_thumbnail( $size = 'post-thumbnail' ) {
|
520 |
-
if ( empty( $size ) ) { // if junk value, make it a normal thumb.
|
521 |
-
$size = 'post-thumbnail';
|
522 |
-
} elseif ( is_array( $size ) && ( 2 === count( $size ) ) ) { // good format at least.
|
523 |
-
// normalize to ints first.
|
524 |
-
$size[0] = (int) $size[0];
|
525 |
-
$size[1] = (int) $size[1];
|
526 |
-
if ( ( 0 === $size[0] ) && ( 0 === $size[1] ) ) { // Both values zero then revert to thumbnail.
|
527 |
-
$size = array( get_option( 'thumbnail_size_w', 150 ), get_option( 'thumbnail_size_h', 150 ) );
|
528 |
-
} elseif ( ( 0 === $size[0] ) && ( 0 !== $size[1] ) ) {
|
529 |
-
// if one value is zero make a square using the other value.
|
530 |
-
$size[0] = $size[1];
|
531 |
-
} elseif ( ( 0 !== $size[0] ) && ( 0 === $size[1] ) ) {
|
532 |
-
$size[1] = $size[0];
|
533 |
-
}
|
534 |
-
} else {
|
535 |
-
$size = array( get_option( 'thumbnail_size_w', 150 ), get_option( 'thumbnail_size_h', 150 ) ); // yet another form of junk.
|
536 |
-
}
|
537 |
-
|
538 |
-
$post_thumbnail_id = get_post_thumbnail_id( get_the_ID() );
|
539 |
-
if ( ! $post_thumbnail_id && $this->instance['default_thunmbnail'] ) {
|
540 |
-
$post_thumbnail_id = $this->instance['default_thunmbnail'];
|
541 |
-
}
|
542 |
-
|
543 |
-
do_action( 'begin_fetch_post_thumbnail_html', get_the_ID(), $post_thumbnail_id, $size );
|
544 |
-
$html = wp_get_attachment_image( $post_thumbnail_id, $size, false, '' );
|
545 |
-
if ( ! $html ) {
|
546 |
-
$ret = '';
|
547 |
-
} else {
|
548 |
-
$ret = $this->post_thumbnail_html( $html, get_the_ID(), $post_thumbnail_id, $size, '' );
|
549 |
-
}
|
550 |
-
do_action( 'end_fetch_post_thumbnail_html', get_the_ID(), $post_thumbnail_id, $size );
|
551 |
-
|
552 |
-
return $ret;
|
553 |
-
}
|
554 |
-
|
555 |
-
/**
|
556 |
-
* Excerpt more link filter
|
557 |
-
*
|
558 |
-
* @param string $more The "more" text passed by the filter.
|
559 |
-
*
|
560 |
-
* @return string The link to the post with the "more" text configured in the widget.
|
561 |
-
*/
|
562 |
-
public function excerpt_more_filter( $more ) {
|
563 |
-
return ' <a class="cat-post-excerpt-more more-link" href="' . get_permalink() . '">' . esc_html( $this->instance['excerpt_more_text'] ) . '</a>';
|
564 |
-
}
|
565 |
-
|
566 |
-
/**
|
567 |
-
* Apply the_content filter for excerpt
|
568 |
-
* This should show sharing buttons which comes with other widgets in the widget output in the same way as on the main content
|
569 |
-
*
|
570 |
-
* @param string $text The HTML with other applied excerpt filters.
|
571 |
-
*
|
572 |
-
* @return string If option hide_social_buttons is unchecked applay the_content filter.
|
573 |
-
*
|
574 |
-
* @since 4.6
|
575 |
-
*/
|
576 |
-
public function apply_the_excerpt( $text ) {
|
577 |
-
$ret = '';
|
578 |
-
if ( isset( $this->instance['hide_social_buttons'] ) && $this->instance['hide_social_buttons'] ) {
|
579 |
-
$ret = $text;
|
580 |
-
} else {
|
581 |
-
$ret = apply_filters( 'the_content', $text );
|
582 |
-
}
|
583 |
-
return $ret;
|
584 |
-
}
|
585 |
-
|
586 |
-
/**
|
587 |
-
* Excerpt allow HTML
|
588 |
-
*
|
589 |
-
* @param string $text The HTML with other applied excerpt filters.
|
590 |
-
*/
|
591 |
-
public function allow_html_excerpt( $text ) {
|
592 |
-
global $post, $wp_filter;
|
593 |
-
$new_excerpt_length = ( isset( $this->instance['excerpt_length'] ) && $this->instance['excerpt_length'] > 0 ) ? $this->instance['excerpt_length'] : 55;
|
594 |
-
if ( '' === $text ) {
|
595 |
-
$text = get_the_content( '' );
|
596 |
-
$text = strip_shortcodes( $text );
|
597 |
-
$text = apply_filters( 'the_content', $text );
|
598 |
-
$text = str_replace( '\]\]\>', ']]>', $text );
|
599 |
-
$text = preg_replace( '@<script[^>]*?>.*?</script>@si', '', $text );
|
600 |
-
$cphtml = array(
|
601 |
-
'<a>',
|
602 |
-
'<br>',
|
603 |
-
'<em>',
|
604 |
-
'<i>',
|
605 |
-
'<ul>',
|
606 |
-
'<ol>',
|
607 |
-
'<li>',
|
608 |
-
'<p>',
|
609 |
-
'<img>',
|
610 |
-
'<script>',
|
611 |
-
'<style>',
|
612 |
-
'<video>',
|
613 |
-
'<audio>',
|
614 |
-
);
|
615 |
-
$allowed_HTML = '';
|
616 |
-
foreach ( $cphtml as $index => $name ) {
|
617 |
-
if ( in_array( (string) ( $index ), $this->instance['excerpt_allowed_elements'], true ) ) {
|
618 |
-
$allowed_HTML .= $cphtml[ $index ];
|
619 |
-
}
|
620 |
-
}
|
621 |
-
$text = strip_tags( $text, htmlspecialchars_decode( $allowed_HTML ) );
|
622 |
-
$excerpt_length = $new_excerpt_length;
|
623 |
-
|
624 |
-
if ( ! empty( $this->instance['excerpt_more_text'] ) ) {
|
625 |
-
$excerpt_more = $this->excerpt_more_filter( $this->instance['excerpt_more_text'] );
|
626 |
-
} elseif ( $filterName = key( $wp_filter['excerpt_more'][10] ) ) {
|
627 |
-
$excerpt_more = $wp_filter['excerpt_more'][10][ $filterName ]['function']( 0 );
|
628 |
-
} else {
|
629 |
-
$excerpt_more = '[...]';
|
630 |
-
}
|
631 |
-
|
632 |
-
$words = explode( ' ', $text, $excerpt_length + 1 );
|
633 |
-
if ( count( $words ) > $excerpt_length ) {
|
634 |
-
array_pop( $words );
|
635 |
-
array_push( $words, $excerpt_more );
|
636 |
-
$text = implode( ' ', $words );
|
637 |
-
}
|
638 |
-
}
|
639 |
-
|
640 |
-
return '<p>' . $text . '</p>';
|
641 |
-
}
|
642 |
-
|
643 |
-
/**
|
644 |
-
* Calculate the wp-query arguments matching the filter settings of the widget
|
645 |
-
*
|
646 |
-
* @param array $instance Array which contains the various settings.
|
647 |
-
* @return array The array that can be fed to wp_Query to get the relevant posts
|
648 |
-
*
|
649 |
-
* @since 4.6
|
650 |
-
*/
|
651 |
-
public function queryArgs( $instance ) {
|
652 |
-
|
653 |
-
$valid_sort_orders = array( 'date', 'title', 'comment_count', 'rand' );
|
654 |
-
if ( isset( $instance['sort_by'] ) && in_array( $instance['sort_by'], $valid_sort_orders, true ) ) {
|
655 |
-
$sort_by = $instance['sort_by'];
|
656 |
-
} else {
|
657 |
-
$sort_by = 'date';
|
658 |
-
}
|
659 |
-
$sort_order = ( isset( $instance['asc_sort_order'] ) && $instance['asc_sort_order'] ) ? 'ASC' : 'DESC';
|
660 |
-
|
661 |
-
// Get array of post info.
|
662 |
-
$args = array(
|
663 |
-
'orderby' => $sort_by,
|
664 |
-
'order' => $sort_order,
|
665 |
-
'ignore_sticky_posts' => 1, // Make sure we do not get stickies out of order.
|
666 |
-
);
|
667 |
-
|
668 |
-
$non_default_valid_status = array(
|
669 |
-
'publish',
|
670 |
-
'future',
|
671 |
-
'publish,future',
|
672 |
-
'private',
|
673 |
-
'private,publish',
|
674 |
-
'private,publish,future',
|
675 |
-
);
|
676 |
-
if ( isset( $instance['status'] ) && in_array( $instance['status'], $non_default_valid_status, true ) ) {
|
677 |
-
$args['post_status'] = $instance['status'];
|
678 |
-
}
|
679 |
-
|
680 |
-
if ( isset( $instance['num'] ) ) {
|
681 |
-
$args['showposts'] = (int) $instance['num'];
|
682 |
-
}
|
683 |
-
|
684 |
-
if ( isset( $instance['offset'] ) && ( (int) $instance['offset'] > 1 ) ) {
|
685 |
-
$args['offset'] = (int) $instance['offset'] - 1;
|
686 |
-
}
|
687 |
-
if ( isset( $instance['cat'] ) ) {
|
688 |
-
if ( isset( $instance['no_cat_childs'] ) && $instance['no_cat_childs'] ) {
|
689 |
-
$args['category__in'] = (int) $instance['cat'];
|
690 |
-
} else {
|
691 |
-
$args['cat'] = (int) $instance['cat'];
|
692 |
-
}
|
693 |
-
}
|
694 |
-
|
695 |
-
if ( is_singular() && isset( $instance['exclude_current_post'] ) && $instance['exclude_current_post'] ) {
|
696 |
-
$args['post__not_in'] = array( get_the_ID() );
|
697 |
-
}
|
698 |
-
|
699 |
-
if ( isset( $instance['hideNoThumb'] ) && $instance['hideNoThumb'] ) {
|
700 |
-
$args = array_merge( $args, array(
|
701 |
-
'meta_query' => array(
|
702 |
-
array(
|
703 |
-
'key' => '_thumbnail_id',
|
704 |
-
'compare' => 'EXISTS',
|
705 |
-
),
|
706 |
-
),
|
707 |
-
) );
|
708 |
-
}
|
709 |
-
|
710 |
-
return $args;
|
711 |
-
}
|
712 |
-
|
713 |
-
/**
|
714 |
-
* Calculate the HTML of the title based on the widget settings
|
715 |
-
*
|
716 |
-
* @param string $before_title The sidebar configured HTML that should come
|
717 |
-
* before the title itself.
|
718 |
-
* @param string $after_title The sidebar configured HTML that should come
|
719 |
-
* after the title itself.
|
720 |
-
* @param array $instance Array which contains the various settings.
|
721 |
-
* @return string The HTML for the title area
|
722 |
-
*
|
723 |
-
* @since 4.6
|
724 |
-
*/
|
725 |
-
public function titleHTML( $before_title, $after_title, $instance ) {
|
726 |
-
$ret = '';
|
727 |
-
|
728 |
-
if ( ! isset( $instance['cat'] ) ) {
|
729 |
-
$instance['cat'] = 0;
|
730 |
-
}
|
731 |
-
|
732 |
-
// If no title, use the name of the category.
|
733 |
-
if ( ! isset( $instance['title'] ) || ! $instance['title'] ) {
|
734 |
-
$instance['title'] = '';
|
735 |
-
if ( 0 !== $instance['cat'] ) {
|
736 |
-
$category_info = get_category( $instance['cat'] );
|
737 |
-
if ( $category_info && ! is_wp_error( $category_info ) ) {
|
738 |
-
$instance['title'] = $category_info->name;
|
739 |
-
} else {
|
740 |
-
$instance['cat'] = 0; // For further processing treat it like "all categories".
|
741 |
-
$instance['title'] = __( 'Recent Posts', 'category-posts' );
|
742 |
-
}
|
743 |
-
} else {
|
744 |
-
$instance['title'] = __( 'Recent Posts', 'category-posts' );
|
745 |
-
}
|
746 |
-
}
|
747 |
-
|
748 |
-
if ( ! ( isset( $instance['hide_title'] ) && $instance['hide_title'] ) ) {
|
749 |
-
$ret = $before_title;
|
750 |
-
if ( isset( $instance['is_shortcode'] ) ) {
|
751 |
-
$title = esc_html( $instance['title'] );
|
752 |
-
} else {
|
753 |
-
$title = apply_filters( 'widget_title', $instance['title'] );
|
754 |
-
}
|
755 |
-
|
756 |
-
if ( isset( $instance['title_link'] ) && $instance['title_link'] ) {
|
757 |
-
if ( 0 !== $instance['cat'] ) {
|
758 |
-
$ret .= '<a href="' . get_category_link( $instance['cat'] ) . '">' . $title . '</a>';
|
759 |
-
} elseif ( isset( $instance['title_link_url'] ) && $instance['title_link_url'] ) {
|
760 |
-
$ret .= '<a href="' . esc_url( $instance['title_link_url'] ) . '">' . $title . '</a>';
|
761 |
-
} else {
|
762 |
-
$ret .= '<a href="' . esc_url( $this->blog_page_url() ) . '">' . $title . '</a>';
|
763 |
-
}
|
764 |
-
} else {
|
765 |
-
$ret .= $title;
|
766 |
-
}
|
767 |
-
|
768 |
-
$ret .= $after_title;
|
769 |
-
}
|
770 |
-
|
771 |
-
return $ret;
|
772 |
-
}
|
773 |
-
|
774 |
-
/**
|
775 |
-
* Get the URL of the blog page or home page if no explicit blog page is defined.
|
776 |
-
*
|
777 |
-
* @return string The URL of the blog page
|
778 |
-
*
|
779 |
-
* @since 4.8
|
780 |
-
*/
|
781 |
-
private function blog_page_url() {
|
782 |
-
|
783 |
-
$blog_page = get_option( 'page_for_posts' );
|
784 |
-
if ( $blog_page ) {
|
785 |
-
$url = get_permalink( $blog_page );
|
786 |
-
} else {
|
787 |
-
$url = home_url();
|
788 |
-
}
|
789 |
-
|
790 |
-
return $url;
|
791 |
-
}
|
792 |
-
|
793 |
-
/**
|
794 |
-
* Calculate the HTML of the footer based on the widget settings
|
795 |
-
*
|
796 |
-
* @param array $instance Array which contains the various settings.
|
797 |
-
* @return string The HTML for the footer area
|
798 |
-
*
|
799 |
-
* @since 4.6
|
800 |
-
*/
|
801 |
-
public function footerHTML( $instance ) {
|
802 |
-
|
803 |
-
$ret = '';
|
804 |
-
$url = '';
|
805 |
-
$text = '';
|
806 |
-
|
807 |
-
if ( isset( $instance['footer_link'] ) ) {
|
808 |
-
$url = $instance['footer_link'];
|
809 |
-
}
|
810 |
-
|
811 |
-
if ( isset( $instance['footer_link_text'] ) ) {
|
812 |
-
$text = $instance['footer_link_text'];
|
813 |
-
}
|
814 |
-
|
815 |
-
// if url is set, but no text, just use the url as text.
|
816 |
-
if ( empty( $text ) && ! empty( $url ) ) {
|
817 |
-
$text = $url;
|
818 |
-
}
|
819 |
-
|
820 |
-
// if no url is set but just text, assume the url should be to the relevant archive page
|
821 |
-
// category archive for categories filter and home page or blog page when "all categories"
|
822 |
-
// is used.
|
823 |
-
if ( ! empty( $text ) && empty( $url ) ) {
|
824 |
-
if ( isset( $instance['cat'] ) && ( 0 !== $instance['cat'] ) && ( null !== get_category( $instance['cat'] ) ) ) {
|
825 |
-
$url = get_category_link( $instance['cat'] );
|
826 |
-
} else {
|
827 |
-
$url = $this->blog_page_url();
|
828 |
-
}
|
829 |
-
}
|
830 |
-
|
831 |
-
if ( ! empty( $url ) ) {
|
832 |
-
$ret .= '<a class="cat-post-footer-link" href="' . esc_url( $url ) . '">' . esc_html( $text ) . '</a>';
|
833 |
-
}
|
834 |
-
|
835 |
-
return $ret;
|
836 |
-
}
|
837 |
-
|
838 |
-
/**
|
839 |
-
* Current post item date string based on the format requested in the settings
|
840 |
-
*
|
841 |
-
* @param array $instance Array which contains the various settings.
|
842 |
-
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
843 |
-
*
|
844 |
-
* @since 4.8
|
845 |
-
*/
|
846 |
-
public function itemDate( $instance, $everything_is_link ) {
|
847 |
-
$ret = '';
|
848 |
-
|
849 |
-
if ( ! isset( $instance['preset_date_format'] ) ) {
|
850 |
-
$preset_date_format = 'other';
|
851 |
-
} else {
|
852 |
-
$preset_date_format = $instance['preset_date_format'];
|
853 |
-
}
|
854 |
-
|
855 |
-
switch ( $preset_date_format ) {
|
856 |
-
case 'sitedateandtime':
|
857 |
-
$date = get_the_time( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
|
858 |
-
break;
|
859 |
-
case 'sitedate':
|
860 |
-
$date = get_the_time( get_option( 'date_format' ) );
|
861 |
-
break;
|
862 |
-
case 'sincepublished':
|
863 |
-
$date = human_time_diff( get_the_time( 'U' ), current_time( 'timestamp' ) );
|
864 |
-
break;
|
865 |
-
default:
|
866 |
-
if ( isset( $instance['date_format'] ) && strlen( trim( $instance['date_format'] ) ) > 0 ) {
|
867 |
-
$date_format = $instance['date_format'];
|
868 |
-
} else {
|
869 |
-
$date_format = 'j M Y';
|
870 |
-
}
|
871 |
-
$date = get_the_time( $date_format );
|
872 |
-
break;
|
873 |
-
}
|
874 |
-
$ret .= '<span class="cat-post-date">';
|
875 |
-
if ( isset( $instance['date_link'] ) && $instance['date_link'] && ! $everything_is_link ) {
|
876 |
-
$ret .= '<a href="' . \get_the_permalink() . '">';
|
877 |
-
}
|
878 |
-
$ret .= $date;
|
879 |
-
|
880 |
-
if ( isset( $instance['date_link'] ) && $instance['date_link'] && ! $everything_is_link ) {
|
881 |
-
$ret .= '</a>';
|
882 |
-
}
|
883 |
-
$ret .= '</span>';
|
884 |
-
return $ret;
|
885 |
-
}
|
886 |
-
|
887 |
-
|
888 |
-
/**
|
889 |
-
* Calculate the HTML for showing the thumb of a post item.
|
890 |
-
* Expected to be called from a loop with globals properly set.
|
891 |
-
*
|
892 |
-
* @param array $instance Array which contains the various settings.
|
893 |
-
* @param bool $no_link indicates whether the thumb should be wrapped in a link or a span.
|
894 |
-
* @return string The HTML for the thumb related to the post
|
895 |
-
*
|
896 |
-
* @since 4.6
|
897 |
-
*/
|
898 |
-
public function itemThumb( $instance, $no_link ) {
|
899 |
-
$ret = '';
|
900 |
-
|
901 |
-
if ( ( isset( $instance['default_thunmbnail'] ) && ( 0 !== $instance['default_thunmbnail'] ) ) || has_post_thumbnail() ) {
|
902 |
-
$class = '';
|
903 |
-
$use_css_cropping = isset( $this->instance['use_css_cropping'] ) && $this->instance['use_css_cropping'];
|
904 |
-
$disable_css = isset( $instance['disable_css'] ) && $instance['disable_css'];
|
905 |
-
|
906 |
-
if ( isset( $this->instance['thumb_hover'] ) && ! $disable_css ) {
|
907 |
-
$class = 'class="cat-post-thumbnail cat-post-' . $instance['thumb_hover'] . '"';
|
908 |
-
} else {
|
909 |
-
$class = 'class="cat-post-thumbnail"';
|
910 |
-
}
|
911 |
-
|
912 |
-
$title_args = array( 'echo' => false );
|
913 |
-
|
914 |
-
if ( $no_link ) {
|
915 |
-
$ret .= '<span ' . $class . '>';
|
916 |
-
} else {
|
917 |
-
$ret .= '<a ' . $class . ' href="' . get_the_permalink() . '" title="' . the_title_attribute( $title_args ) . '">';
|
918 |
-
}
|
919 |
-
|
920 |
-
$ret .= $this->the_post_thumbnail( array( $this->instance['thumb_w'], $this->instance['thumb_h'] ) );
|
921 |
-
|
922 |
-
if ( $no_link ) {
|
923 |
-
$ret .= '</span>';
|
924 |
-
} else {
|
925 |
-
$ret .= '</a>';
|
926 |
-
}
|
927 |
-
}
|
928 |
-
|
929 |
-
return $ret;
|
930 |
-
}
|
931 |
-
|
932 |
-
/**
|
933 |
-
* Current post item categories string
|
934 |
-
*
|
935 |
-
* @param array $instance Array which contains the various settings.
|
936 |
-
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
937 |
-
*
|
938 |
-
* @since 4.8
|
939 |
-
*/
|
940 |
-
public function itemCategories( $instance, $everything_is_link ) {
|
941 |
-
|
942 |
-
$ret = '<span class="cat-post-tax-category">';
|
943 |
-
$cat_ids = wp_get_post_categories( get_the_ID(), array( 'number' => 0 ) );
|
944 |
-
foreach ( $cat_ids as $cat_id ) {
|
945 |
-
if ( $everything_is_link ) {
|
946 |
-
$ret .= ' ' . get_cat_name( $cat_id );
|
947 |
-
} else {
|
948 |
-
$ret .= " <a href='" . get_category_link( $cat_id ) . "'>" . get_cat_name( $cat_id ) . '</a>';
|
949 |
-
}
|
950 |
-
}
|
951 |
-
$ret .= '</span>';
|
952 |
-
return $ret;
|
953 |
-
}
|
954 |
-
|
955 |
-
/**
|
956 |
-
* Current post item tags string
|
957 |
-
*
|
958 |
-
* @param array $instance Array which contains the various settings.
|
959 |
-
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
960 |
-
*
|
961 |
-
* @since 4.8
|
962 |
-
*/
|
963 |
-
public function itemTags( $instance, $everything_is_link ) {
|
964 |
-
|
965 |
-
$ret = '<span class="cat-post-tax-post_tag">';
|
966 |
-
$tag_ids = wp_get_post_tags( get_the_ID(), array( 'number' => 0 ) );
|
967 |
-
foreach ( $tag_ids as $tag_id ) {
|
968 |
-
if ( $everything_is_link ) {
|
969 |
-
$ret .= ' ' . $tag_id->name;
|
970 |
-
} else {
|
971 |
-
$ret .= " <a href='" . get_tag_link( $tag_id->term_id ) . "'>" . $tag_id->name . '</a>';
|
972 |
-
}
|
973 |
-
}
|
974 |
-
$ret .= '</span>';
|
975 |
-
return $ret;
|
976 |
-
}
|
977 |
-
|
978 |
-
/**
|
979 |
-
* Current post item comment number string
|
980 |
-
*
|
981 |
-
* @param array $instance Array which contains the various settings.
|
982 |
-
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
983 |
-
*
|
984 |
-
* @since 4.8
|
985 |
-
*/
|
986 |
-
public function itemCommentNum( $instance, $everything_is_link ) {
|
987 |
-
global $post;
|
988 |
-
|
989 |
-
$ret = '<span class="cat-post-comment-num">';
|
990 |
-
|
991 |
-
if ( $everything_is_link ) {
|
992 |
-
$ret .= '(' . \get_comments_number() . ')';
|
993 |
-
} else {
|
994 |
-
$link = sprintf(
|
995 |
-
'<a href="%1$s" title="%2$s">(%3$d)</a>',
|
996 |
-
esc_url( get_comments_link( $post->ID ) ),
|
997 |
-
esc_attr( sprintf( __( '(%d) comments to this post' ), get_comments_number() ) ),
|
998 |
-
get_comments_number()
|
999 |
-
);
|
1000 |
-
$ret .= $link;
|
1001 |
-
}
|
1002 |
-
|
1003 |
-
$ret .= '</span>';
|
1004 |
-
return $ret;
|
1005 |
-
}
|
1006 |
-
|
1007 |
-
/**
|
1008 |
-
* Current post item author string
|
1009 |
-
*
|
1010 |
-
* @param array $instance Array which contains the various settings.
|
1011 |
-
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
1012 |
-
*
|
1013 |
-
* @since 4.8
|
1014 |
-
*/
|
1015 |
-
public function itemAuthor( $instance, $everything_is_link ) {
|
1016 |
-
|
1017 |
-
$ret = '<span class="cat-post-author">';
|
1018 |
-
|
1019 |
-
if ( $everything_is_link ) {
|
1020 |
-
$ret .= get_the_author();
|
1021 |
-
} else {
|
1022 |
-
$link = get_the_author_posts_link();
|
1023 |
-
$ret .= $link;
|
1024 |
-
}
|
1025 |
-
$ret .= '</span>';
|
1026 |
-
return $ret;
|
1027 |
-
}
|
1028 |
-
|
1029 |
-
/**
|
1030 |
-
* Current post item excerpt string
|
1031 |
-
*
|
1032 |
-
* @param array $instance Array which contains the various settings.
|
1033 |
-
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
1034 |
-
*
|
1035 |
-
* @since 4.8
|
1036 |
-
*/
|
1037 |
-
public function itemExcerpt( $instance, $everything_is_link ) {
|
1038 |
-
global $post;
|
1039 |
-
|
1040 |
-
// use the_excerpt filter to get the "normal" excerpt of the post
|
1041 |
-
// then apply our filter to let users customize excerpts in their own way.
|
1042 |
-
if ( isset( $instance['excerpt_length'] ) && ( $instance['excerpt_length'] > 0 ) ) {
|
1043 |
-
$length = (int) $instance['excerpt_length'];
|
1044 |
-
} else {
|
1045 |
-
$length = 55; // Use the wordpress default.
|
1046 |
-
}
|
1047 |
-
|
1048 |
-
if ( ! isset( $instance['excerpt_filters'] ) || $instance['excerpt_filters'] ) { // pre 4.7 widgets has filters on.
|
1049 |
-
$excerpt = apply_filters( 'the_excerpt', \get_the_excerpt() );
|
1050 |
-
} else { // if filters off replicate functionality of core generating excerpt.
|
1051 |
-
$more_text = '[…]';
|
1052 |
-
if ( isset( $instance['excerpt_more_text'] ) && $instance['excerpt_more_text'] ) {
|
1053 |
-
$more_text = ltrim( $instance['excerpt_more_text'] );
|
1054 |
-
}
|
1055 |
-
|
1056 |
-
if ( $everything_is_link ) {
|
1057 |
-
$excerpt_more_text = ' <span class="cat-post-excerpt-more">' . $more_text . '</span>';
|
1058 |
-
} else {
|
1059 |
-
$excerpt_more_text = ' <a class="cat-post-excerpt-more" href="' . get_permalink() . '" title="' . sprintf( __( 'Continue reading %s' ), get_the_title() ) . '">' . $more_text . '</a>';
|
1060 |
-
}
|
1061 |
-
if ( '' === $post->post_excerpt ) {
|
1062 |
-
$text = get_the_content( '' );
|
1063 |
-
$text = strip_shortcodes( $text );
|
1064 |
-
$excerpt = \wp_trim_words( $text, $length, $excerpt_more_text );
|
1065 |
-
// adjust html output same way as for the normal excerpt,
|
1066 |
-
// just force all functions depending on the_excerpt hook.
|
1067 |
-
$excerpt = shortcode_unautop( wpautop( convert_chars( convert_smilies( wptexturize( $excerpt ) ) ) ) );
|
1068 |
-
} else {
|
1069 |
-
$excerpt = $post->post_excerpt . $excerpt_more_text;
|
1070 |
-
$excerpt = shortcode_unautop( wpautop( convert_chars( convert_smilies( wptexturize( $excerpt ) ) ) ) );
|
1071 |
-
}
|
1072 |
-
}
|
1073 |
-
$ret = apply_filters( 'cpw_excerpt', $excerpt, $this );
|
1074 |
-
return $ret;
|
1075 |
-
}
|
1076 |
-
|
1077 |
-
/**
|
1078 |
-
* Current post item title string
|
1079 |
-
*
|
1080 |
-
* @param array $instance Array which contains the various settings.
|
1081 |
-
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
1082 |
-
*
|
1083 |
-
* @since 4.8
|
1084 |
-
*/
|
1085 |
-
public function itemTitle( $instance, $everything_is_link ) {
|
1086 |
-
|
1087 |
-
$ret = '';
|
1088 |
-
|
1089 |
-
if ( $everything_is_link ) {
|
1090 |
-
$ret .= '<span class="cat-post-title">' . get_the_title() . '</span>';
|
1091 |
-
} else {
|
1092 |
-
$ret .= '<a class="cat-post-title"';
|
1093 |
-
$ret .= ' href="' . get_the_permalink() . '" rel="bookmark">' . get_the_title();
|
1094 |
-
$ret .= '</a>';
|
1095 |
-
}
|
1096 |
-
return $ret;
|
1097 |
-
}
|
1098 |
-
|
1099 |
-
/**
|
1100 |
-
* Calculate the HTML for a post item based on the widget settings and post.
|
1101 |
-
* Expected to be called in an active loop with all the globals set.
|
1102 |
-
*
|
1103 |
-
* @param array $instance Array which contains the various settings.
|
1104 |
-
* @param null|integer $current_post_id If on singular page specifies the id of
|
1105 |
-
* the post, otherwise null.
|
1106 |
-
* @return string The HTML for item related to the post
|
1107 |
-
*
|
1108 |
-
* @since 4.6
|
1109 |
-
*/
|
1110 |
-
public function itemHTML( $instance, $current_post_id ) {
|
1111 |
-
global $post;
|
1112 |
-
|
1113 |
-
$everything_is_link = isset( $instance['everything_is_link'] ) && $instance['everything_is_link'];
|
1114 |
-
$wrap = isset( $instance['text_do_not_wrap_thumb'] ) && $instance['text_do_not_wrap_thumb'];
|
1115 |
-
|
1116 |
-
$template = '';
|
1117 |
-
if ( isset( $instance['template'] ) ) {
|
1118 |
-
$template = $instance['template'];
|
1119 |
-
} else {
|
1120 |
-
$template = convert_settings_to_template( $instance );
|
1121 |
-
}
|
1122 |
-
$ret = '<li ';
|
1123 |
-
|
1124 |
-
// Current post.
|
1125 |
-
if ( $current_post_id === $post->ID ) {
|
1126 |
-
$ret .= "class='cat-post-item cat-post-current'";
|
1127 |
-
} else {
|
1128 |
-
$ret .= "class='cat-post-item'";
|
1129 |
-
}
|
1130 |
-
$ret .= '>'; // close the li opening tag.
|
1131 |
-
|
1132 |
-
if ( $everything_is_link ) {
|
1133 |
-
$ret .= '<a class="cat-post-everything-is-link" href="' . get_the_permalink() . '" title="">';
|
1134 |
-
}
|
1135 |
-
|
1136 |
-
// Try to do smart formatting for floating thumb based on its location.
|
1137 |
-
if ( $wrap ) {
|
1138 |
-
if( preg_match( '#(\%thumb\%)#', $template ) && ! preg_match( '#(\%thumb\%$)#', $template ) ) {
|
1139 |
-
$thumb_flex = explode( '%thumb%', $template );
|
1140 |
-
if( count( $thumb_flex ) == 1) {
|
1141 |
-
$template = '<div class="cat-post-do-not-wrap-thumbnail">%thumb%<div>' . $thumb_flex[0] . '</div></div>';
|
1142 |
-
}
|
1143 |
-
if( count( $thumb_flex ) == 2) {
|
1144 |
-
$template = $thumb_flex[0] . '<div class="cat-post-do-not-wrap-thumbnail">%thumb%<div>' . $thumb_flex[1] . '</div></div>';
|
1145 |
-
}
|
1146 |
-
}
|
1147 |
-
}
|
1148 |
-
|
1149 |
-
// Post details (Template).
|
1150 |
-
$widget = $this;
|
1151 |
-
$template_res = preg_replace_callback( get_template_regex(), function ( $matches ) use ( $widget, $instance, $everything_is_link ) {
|
1152 |
-
switch ( $matches[0] ) {
|
1153 |
-
case '%title%':
|
1154 |
-
return $widget->itemTitle( $instance, $everything_is_link );
|
1155 |
-
case '%author%':
|
1156 |
-
return $widget->itemAuthor( $instance, $everything_is_link );
|
1157 |
-
case '%commentnum%':
|
1158 |
-
return $widget->itemCommentNum( $instance, $everything_is_link );
|
1159 |
-
case '%date%':
|
1160 |
-
return $widget->itemDate( $instance, $everything_is_link );
|
1161 |
-
case '%thumb%':
|
1162 |
-
return $widget->itemThumb( $instance, $everything_is_link );
|
1163 |
-
case '%post_tag%':
|
1164 |
-
return $widget->itemTags( $instance, $everything_is_link );
|
1165 |
-
case '%category%':
|
1166 |
-
return $widget->itemCategories( $instance, $everything_is_link );
|
1167 |
-
case '%excerpt%':
|
1168 |
-
return $widget->itemExcerpt( $instance, $everything_is_link );
|
1169 |
-
default:
|
1170 |
-
return $matches[0];
|
1171 |
-
}
|
1172 |
-
}, $template );
|
1173 |
-
|
1174 |
-
// Replace empty line with closing and opening DIV.
|
1175 |
-
$template_res = trim( $template_res );
|
1176 |
-
$template_res = str_replace( "\n\r", '</div><div>', $template_res ); // in widget areas
|
1177 |
-
$template_res = str_replace( "\n\n", '</div><div>', $template_res ); // as shortcode
|
1178 |
-
$template_res = '<div>' . $template_res . '</div>';
|
1179 |
-
|
1180 |
-
// replace new lines with spaces.
|
1181 |
-
$template_res = str_replace( "\n\r", ' ', $template_res ); // in widget areas
|
1182 |
-
$template_res = str_replace( "\n\n", ' ', $template_res ); // as shortcode
|
1183 |
-
|
1184 |
-
$ret .= $template_res;
|
1185 |
-
|
1186 |
-
if ( $everything_is_link ) {
|
1187 |
-
$ret .= '</a>';
|
1188 |
-
}
|
1189 |
-
|
1190 |
-
$ret .= '</li>';
|
1191 |
-
return $ret;
|
1192 |
-
}
|
1193 |
-
|
1194 |
-
/**
|
1195 |
-
* Filter to set the number of words in an excerpt
|
1196 |
-
*
|
1197 |
-
* @param int $length The number of words as configured by wordpress core or set by previous filters.
|
1198 |
-
* @return int The number of words configured for the widget,
|
1199 |
-
* or the $length parameter if it is not configured or garbage value.
|
1200 |
-
*
|
1201 |
-
* @since 4.6
|
1202 |
-
*/
|
1203 |
-
public function excerpt_length_filter( $length ) {
|
1204 |
-
if ( isset( $this->instance['excerpt_length'] ) && $this->instance['excerpt_length'] > 0 ) {
|
1205 |
-
$length = $this->instance['excerpt_length'];
|
1206 |
-
}
|
1207 |
-
return $length;
|
1208 |
-
}
|
1209 |
-
|
1210 |
-
/**
|
1211 |
-
* Set the proper excerpt filters based on the settings
|
1212 |
-
*
|
1213 |
-
* @param array $instance widget settings.
|
1214 |
-
* @return void
|
1215 |
-
*
|
1216 |
-
* @since 4.6
|
1217 |
-
*/
|
1218 |
-
public function setExcerpFilters( $instance ) {
|
1219 |
-
|
1220 |
-
if ( isset( $instance['excerpt'] ) && $instance['excerpt'] ) {
|
1221 |
-
|
1222 |
-
// Excerpt length filter.
|
1223 |
-
if ( isset( $instance['excerpt_length'] ) && ( (int) $instance['excerpt_length'] ) > 0 ) {
|
1224 |
-
add_filter( 'excerpt_length', array( $this, 'excerpt_length_filter' ) );
|
1225 |
-
}
|
1226 |
-
|
1227 |
-
if ( isset( $instance['excerpt_more_text'] ) && ( '' !== ltrim( $instance['excerpt_more_text'] ) ) ) {
|
1228 |
-
add_filter( 'excerpt_more', array( $this, 'excerpt_more_filter' ) );
|
1229 |
-
}
|
1230 |
-
|
1231 |
-
if ( isset( $instance['excerpt_allow_html'] ) ) {
|
1232 |
-
remove_filter( 'get_the_excerpt', 'wp_trim_excerpt' );
|
1233 |
-
add_filter( 'the_excerpt', array( $this, 'allow_html_excerpt' ) );
|
1234 |
-
} else {
|
1235 |
-
add_filter( 'the_excerpt', array( $this, 'apply_the_excerpt' ) );
|
1236 |
-
}
|
1237 |
-
}
|
1238 |
-
}
|
1239 |
-
|
1240 |
-
/**
|
1241 |
-
* Remove the excerpt filter
|
1242 |
-
*
|
1243 |
-
* @param array $instance widget settings.
|
1244 |
-
* @return void
|
1245 |
-
*
|
1246 |
-
* @since 4.6
|
1247 |
-
*/
|
1248 |
-
public function removeExcerpFilters( $instance ) {
|
1249 |
-
remove_filter( 'excerpt_length', array( $this, 'excerpt_length_filter' ) );
|
1250 |
-
remove_filter( 'excerpt_more', array( $this, 'excerpt_more_filter' ) );
|
1251 |
-
add_filter( 'get_the_excerpt', 'wp_trim_excerpt' );
|
1252 |
-
remove_filter( 'the_excerpt', array( $this, 'allow_html_excerpt' ) );
|
1253 |
-
remove_filter( 'the_excerpt', array( $this, 'apply_the_excerpt' ) );
|
1254 |
-
}
|
1255 |
-
|
1256 |
-
/**
|
1257 |
-
* The main widget display controller
|
1258 |
-
*
|
1259 |
-
* Called by the sidebar processing core logic to display the widget.
|
1260 |
-
*
|
1261 |
-
* @param array $args An array containing the "environment" setting for the widget,
|
1262 |
-
* namely, the enclosing tags for the widget and its title.
|
1263 |
-
* @param array $instance The settings associate with the widget.
|
1264 |
-
*
|
1265 |
-
* @since 4.1
|
1266 |
-
*/
|
1267 |
-
public function widget( $args, $instance ) {
|
1268 |
-
|
1269 |
-
if ( 0 === count( $instance ) ) {
|
1270 |
-
$instance = default_settings();
|
1271 |
-
}
|
1272 |
-
|
1273 |
-
extract( $args );
|
1274 |
-
$this->instance = $instance;
|
1275 |
-
|
1276 |
-
$args = $this->queryArgs( $instance );
|
1277 |
-
$cat_posts = new \WP_Query( $args );
|
1278 |
-
|
1279 |
-
if ( ! isset( $instance['hide_if_empty'] ) || ! $instance['hide_if_empty'] || $cat_posts->have_posts() ) {
|
1280 |
-
echo $before_widget; // Xss ok. This is how widget actually expected to behave.
|
1281 |
-
echo $this->titleHTML( $before_title, $after_title, $instance );
|
1282 |
-
|
1283 |
-
$current_post_id = null;
|
1284 |
-
if ( is_singular() ) {
|
1285 |
-
$current_post_id = get_the_ID();
|
1286 |
-
}
|
1287 |
-
|
1288 |
-
if ( ! ( isset( $instance['is_shortcode'] ) && $instance['is_shortcode'] ) ) { // the internal id is needed only for widgets.
|
1289 |
-
echo '<ul id="' . esc_attr( WIDGET_BASE_ID ) . '-' . esc_attr( $this->number ) . '-internal" class="' . esc_attr( WIDGET_BASE_ID ) . '-internal' . "\">\n";
|
1290 |
-
} else {
|
1291 |
-
echo '<ul>';
|
1292 |
-
}
|
1293 |
-
|
1294 |
-
// set widget filters.
|
1295 |
-
if ( ! isset( $instance['excerpt_filters'] ) || $instance['excerpt_filters'] ) { // pre 4.7 widgets has filters on.
|
1296 |
-
$this->setExcerpFilters( $instance );
|
1297 |
-
}
|
1298 |
-
|
1299 |
-
while ( $cat_posts->have_posts() ) {
|
1300 |
-
$cat_posts->the_post();
|
1301 |
-
echo $this->itemHTML( $instance, $current_post_id );
|
1302 |
-
}
|
1303 |
-
echo "</ul>\n";
|
1304 |
-
|
1305 |
-
echo $this->footerHTML( $instance );
|
1306 |
-
echo $after_widget; // Xss ok. This is how widget actually expected to behave.
|
1307 |
-
|
1308 |
-
// remove widget filters.
|
1309 |
-
if ( ! isset( $instance['excerpt_filters'] ) || $instance['excerpt_filters'] ) { // pre 4.7 widgets has filters on.
|
1310 |
-
$this->removeExcerpFilters( $instance );
|
1311 |
-
}
|
1312 |
-
|
1313 |
-
wp_reset_postdata();
|
1314 |
-
|
1315 |
-
$use_css_cropping = isset( $this->instance['use_css_cropping'] ) && $this->instance['use_css_cropping'];
|
1316 |
-
$empty_dimensions = empty( $this->instance['thumb_w'] ) || empty( $this->instance['thumb_h'] );
|
1317 |
-
$thumb = isset( $this->instance['template'] ) && preg_match( '/%thumb%/', $this->instance['template'] );
|
1318 |
-
|
1319 |
-
if ( $use_css_cropping && ! $empty_dimensions && $thumb ) {
|
1320 |
-
// enqueue relevant scripts and parameters to perform cropping
|
1321 |
-
// once we support only 4.5+ it can be refactored to use wp_add_inline_script.
|
1322 |
-
$number = $this->number;
|
1323 |
-
// a temporary hack to handle difference in the number in a true widget
|
1324 |
-
// and the number format expected at the rest of the places.
|
1325 |
-
if ( is_numeric( $number ) ) {
|
1326 |
-
$number = WIDGET_BASE_ID . '-' . $number;
|
1327 |
-
}
|
1328 |
-
|
1329 |
-
// add Javascript to change change cropped image dimensions on load and window resize.
|
1330 |
-
$thumb_w = $this->instance['thumb_w'];
|
1331 |
-
$thumb_h = $this->instance['thumb_h'];
|
1332 |
-
add_filter( 'cpw_crop_widgets',
|
1333 |
-
function ( $a ) use ( $number, $thumb_w, $thumb_h ) {
|
1334 |
-
$a[ $number ] = $thumb_w / $thumb_h;
|
1335 |
-
return $a;
|
1336 |
-
}
|
1337 |
-
);
|
1338 |
-
wp_enqueue_script( 'jquery' ); // just in case the theme or other plugins didn't enqueue it.
|
1339 |
-
add_action('wp_footer',function () use ($number,$instance) { __NAMESPACE__ . '\\' . change_cropped_image_dimensions($number,$instance);},100);
|
1340 |
-
}
|
1341 |
-
}
|
1342 |
-
}
|
1343 |
-
|
1344 |
-
/**
|
1345 |
-
* Update the options.
|
1346 |
-
*
|
1347 |
-
* @param array $new_instance The new settings of the widget.
|
1348 |
-
* @param array $old_instance The current settings of the widget.
|
1349 |
-
* @return array
|
1350 |
-
*/
|
1351 |
-
public function update( $new_instance, $old_instance ) {
|
1352 |
-
|
1353 |
-
$new_instance['title'] = sanitize_text_field( $new_instance['title'] ); // sanitize the title like core widgets do.
|
1354 |
-
if ( ! isset( $new_instance['excerpt_filters'] ) ) {
|
1355 |
-
$new_instance['excerpt_filters'] = '';
|
1356 |
-
}
|
1357 |
-
if ( current_user_can( 'unfiltered_html' ) ) {
|
1358 |
-
$instance['text'] = $new_instance['template'];
|
1359 |
-
} else {
|
1360 |
-
$instance['text'] = wp_kses_post( $new_instance['template'] );
|
1361 |
-
}
|
1362 |
-
return $new_instance;
|
1363 |
-
}
|
1364 |
-
|
1365 |
-
/**
|
1366 |
-
* Output the title panel of the widget configuration form.
|
1367 |
-
*
|
1368 |
-
* @param array $instance The widget's settings.
|
1369 |
-
* @return void
|
1370 |
-
*
|
1371 |
-
* @since 4.6
|
1372 |
-
*/
|
1373 |
-
public function formTitlePanel( $instance ) {
|
1374 |
-
if ( isset( $instance['cat'] ) ) {
|
1375 |
-
$cat = $instance['cat'];
|
1376 |
-
} else {
|
1377 |
-
$cat = 0;
|
1378 |
-
}
|
1379 |
-
|
1380 |
-
$hide_title = false;
|
1381 |
-
if ( isset( $instance['hide_title'] ) && $instance['hide_title'] ) {
|
1382 |
-
$hide_title = true;
|
1383 |
-
}
|
1384 |
-
?>
|
1385 |
-
<h4 data-panel="title"><?php esc_html_e( 'Title', 'category-posts' ); ?></h4>
|
1386 |
-
<div>
|
1387 |
-
<?php echo $this->get_checkbox_block_html( $instance, 'hide_title', esc_html__( 'Hide title', 'category-posts' ), false, true ); ?>
|
1388 |
-
<div class="cpwp_ident categoryposts-data-panel-title-settings" <?php if ( $hide_title ) { echo 'style="display:none"'; } ?>>
|
1389 |
-
<?php echo $this->get_text_input_block_html( $instance, 'title', esc_html__( 'Title', 'category-posts' ), '', __( 'Recent Posts', 'category-posts' ), true ); ?>
|
1390 |
-
<?php echo $this->get_checkbox_block_html( $instance, 'title_link', esc_html__( 'Make widget title link', 'category-posts' ), false, 0 !== $cat ); ?>
|
1391 |
-
<?php echo $this->get_text_input_block_html( $instance, 'title_link_url', esc_html__( 'Title link URL', 'category-posts' ), '', '', 0 === $cat ); ?>
|
1392 |
-
</div>
|
1393 |
-
</div>
|
1394 |
-
<?php
|
1395 |
-
}
|
1396 |
-
|
1397 |
-
/**
|
1398 |
-
* Output the filter panel of the widget configuration form.
|
1399 |
-
*
|
1400 |
-
* @param array $instance The parameters configured for the widget.
|
1401 |
-
* @return void
|
1402 |
-
*
|
1403 |
-
* @since 4.6
|
1404 |
-
*/
|
1405 |
-
public function formFilterPanel( $instance ) {
|
1406 |
-
$instance = wp_parse_args( (array) $instance, array( 'cat' => 0 ) );
|
1407 |
-
$cat = $instance['cat'];
|
1408 |
-
?>
|
1409 |
-
<h4 data-panel="filter"><?php esc_html_e( 'Filter', 'category-posts' ); ?></h4>
|
1410 |
-
<div>
|
1411 |
-
<p>
|
1412 |
-
<label>
|
1413 |
-
<?php esc_html_e( 'Category', 'category-posts' ); ?>:
|
1414 |
-
<?php
|
1415 |
-
wp_dropdown_categories( array(
|
1416 |
-
'show_option_all' => __( 'All categories', 'category-posts' ),
|
1417 |
-
'hide_empty' => 0,
|
1418 |
-
'name' => $this->get_field_name( 'cat' ),
|
1419 |
-
'selected' => $instance['cat'],
|
1420 |
-
'class' => 'categoryposts-data-panel-filter-cat',
|
1421 |
-
) );
|
1422 |
-
?>
|
1423 |
-
</label>
|
1424 |
-
</p>
|
1425 |
-
<?php
|
1426 |
-
echo $this->get_checkbox_block_html( $instance, 'no_cat_childs', esc_html__( 'Exclude child categories', 'category-posts' ), false, ! empty( $instance['cat'] ) );
|
1427 |
-
echo $this->get_select_block_html( $instance, 'status', esc_html__( 'Status', 'category-posts' ), array(
|
1428 |
-
'default' => esc_html__( 'WordPress Default', 'category-posts' ),
|
1429 |
-
'publish' => esc_html__( 'Published', 'category-posts' ),
|
1430 |
-
'future' => esc_html__( 'Scheduled', 'category-posts' ),
|
1431 |
-
'private' => esc_html__( 'Private', 'category-posts' ),
|
1432 |
-
'publish,future' => esc_html__( 'Published or Scheduled', 'category-posts' ),
|
1433 |
-
'private,publish' => esc_html__( 'Published or Private', 'category-posts' ),
|
1434 |
-
'private,future' => esc_html__( 'Private or Scheduled', 'category-posts' ),
|
1435 |
-
'private,publish,future' => esc_html__( 'Published, Private or Scheduled', 'category-posts' ),
|
1436 |
-
), 'default', true );
|
1437 |
-
echo $this->get_number_input_block_html( $instance, 'num', esc_html__( 'Number of posts to show', 'category-posts' ), get_option( 'posts_per_page' ), 1, '', '', true );
|
1438 |
-
echo $this->get_number_input_block_html( $instance, 'offset', esc_html__( 'Start with post', 'category-posts' ), 1, 1, '', '', true );
|
1439 |
-
echo $this->get_select_block_html( $instance, 'sort_by', esc_html__( 'Sort by', 'category-posts' ), array(
|
1440 |
-
'date' => esc_html__( 'Date', 'category-posts' ),
|
1441 |
-
'title' => esc_html__( 'Title', 'category-posts' ),
|
1442 |
-
'comment_count' => esc_html__( 'Number of comments', 'category-posts' ),
|
1443 |
-
'rand' => esc_html__( 'Random', 'category-posts' ),
|
1444 |
-
), 'date', true );
|
1445 |
-
echo $this->get_checkbox_block_html( $instance, 'asc_sort_order', esc_html__( 'Reverse sort order (ascending)', 'category-posts' ), false, true );
|
1446 |
-
echo $this->get_checkbox_block_html( $instance, 'exclude_current_post', esc_html__( 'Exclude current post', 'category-posts' ), false, true );
|
1447 |
-
echo $this->get_checkbox_block_html( $instance, 'hideNoThumb', esc_html__( 'Exclude posts which have no thumbnail', 'category-posts' ), false, true );
|
1448 |
-
?>
|
1449 |
-
</div>
|
1450 |
-
<?php
|
1451 |
-
}
|
1452 |
-
|
1453 |
-
/**
|
1454 |
-
* Generate the wrapper P around a form input element
|
1455 |
-
*
|
1456 |
-
* @since 4.8
|
1457 |
-
* @param string $html The HTML to wrap.
|
1458 |
-
* @param string $key The key to use as the prefix to the class.
|
1459 |
-
* @param bool $visible Indicates if the element should be visible when rendered.
|
1460 |
-
*
|
1461 |
-
* @return string HTML with P element contaning the html being passed with class based on the key
|
1462 |
-
* and style set to display:none if visibility is off.
|
1463 |
-
*/
|
1464 |
-
private function get_wrap_block_html( $html, $key, $visible ) {
|
1465 |
-
|
1466 |
-
$cl = ' class="' . __NAMESPACE__ . '-' . esc_attr( $key ) . '"';
|
1467 |
-
|
1468 |
-
$style = '';
|
1469 |
-
if ( ! $visible ) {
|
1470 |
-
$style = ' style="display:none"';
|
1471 |
-
}
|
1472 |
-
$ret = '<p' . $cl . $style . ">\n" . $html . "</p>\n";
|
1473 |
-
|
1474 |
-
return $ret;
|
1475 |
-
}
|
1476 |
-
|
1477 |
-
/**
|
1478 |
-
* Generate a form P element containing a select element
|
1479 |
-
*
|
1480 |
-
* @since 4.8
|
1481 |
-
* @param array $instance The instance.
|
1482 |
-
* @param string $key The key in the instance array.
|
1483 |
-
* @param string $label The label to display and associate with the input.
|
1484 |
-
* @param array $list An array of pairs value (index) => label to be used for the options.
|
1485 |
-
* The labels are expected to be html escaped.
|
1486 |
-
* @param int $default The value to use if the key is not set in the instance.
|
1487 |
-
* @param bool $visible Indicates if the element should be visible when rendered.
|
1488 |
-
*
|
1489 |
-
* @return string HTML a P element contaning the select, its label, class based on the key
|
1490 |
-
* and style set to display:none if visibility is off.
|
1491 |
-
*/
|
1492 |
-
private function get_select_block_html( $instance, $key, $label, $list, $default, $visible ) {
|
1493 |
-
$value = $default;
|
1494 |
-
|
1495 |
-
if ( isset( $instance[ $key ] ) ) {
|
1496 |
-
$value = $instance[ $key ];
|
1497 |
-
}
|
1498 |
-
|
1499 |
-
if ( ! array_key_exists( $value, $list ) ) {
|
1500 |
-
$value = $default;
|
1501 |
-
}
|
1502 |
-
|
1503 |
-
$ret = '<label for="' . $this->get_field_id( $key ) . "\">\n" .
|
1504 |
-
$label .
|
1505 |
-
"</label>\n" .
|
1506 |
-
'<select id="' . $this->get_field_id( $key ) . '" name="' . $this->get_field_name( $key ) . '" autocomplete="off">' . "\n";
|
1507 |
-
foreach ( $list as $v => $l ) {
|
1508 |
-
$ret .= '<option value="' . esc_attr( $v ) . '" ' . selected( $v, $value, false ) . '>' . $l . "</option>\n";
|
1509 |
-
}
|
1510 |
-
$ret .= "</select>\n";
|
1511 |
-
|
1512 |
-
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1513 |
-
}
|
1514 |
-
|
1515 |
-
/**
|
1516 |
-
* Generate a form P element containing a textarea input
|
1517 |
-
*
|
1518 |
-
* @since 4.8
|
1519 |
-
* @param array $instance The instance.
|
1520 |
-
* @param string $key The key in the instance array.
|
1521 |
-
* @param string $label The label to display and associate with the input (should be html escaped).
|
1522 |
-
* @param int $default The value to use if the key is not set in the instance.
|
1523 |
-
* @param string $placeholder The placeholder to use in the input (should be attribute escaped).
|
1524 |
-
* @param bool $visible Indicates if the element should be visible when rendered.
|
1525 |
-
* @param int $num_rows Number of rows.
|
1526 |
-
*
|
1527 |
-
* @return string HTML a P element containing the input, its label, class based on the key
|
1528 |
-
* and style set to display:none if visibility is off.
|
1529 |
-
*/
|
1530 |
-
private function get_textarea_html( $instance, $key, $label, $default, $placeholder, $visible, $num_rows ) {
|
1531 |
-
|
1532 |
-
$value = $default;
|
1533 |
-
|
1534 |
-
if ( isset( $instance[ $key ] ) ) {
|
1535 |
-
$value = $instance[ $key ];
|
1536 |
-
}
|
1537 |
-
|
1538 |
-
$ret = '<label for="' . esc_attr( $this->get_field_id( $key ) ) . '">' . $label . '</label>' .
|
1539 |
-
'<textarea rows="' . esc_attr( $num_rows ) . '" placeholder="' . $placeholder . '" id="' . esc_attr( $this->get_field_id( $key ) ) . '" name="' . esc_attr( $this->get_field_name( $key ) ) . '" autocomplete="off">' . esc_textarea( $value ) . '</textarea>';
|
1540 |
-
|
1541 |
-
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1542 |
-
}
|
1543 |
-
|
1544 |
-
/**
|
1545 |
-
* Generate a form P element containing a text input
|
1546 |
-
*
|
1547 |
-
* @since 4.8
|
1548 |
-
* @param array $instance The instance.
|
1549 |
-
* @param string $key The key in the instance array.
|
1550 |
-
* @param string $label The label to display and associate with the input.
|
1551 |
-
* Should be html escaped.
|
1552 |
-
* @param int $default The value to use if the key is not set in the instance.
|
1553 |
-
* @param string $placeholder The placeholder to use in the input. should be attribute escaped.
|
1554 |
-
* @param bool $visible Indicates if the element should be visible when rendered.
|
1555 |
-
*
|
1556 |
-
* @return string HTML a P element contaning the input, its label, class based on the key
|
1557 |
-
* and style set to display:none if visibility is off.
|
1558 |
-
*/
|
1559 |
-
private function get_text_input_block_html( $instance, $key, $label, $default, $placeholder, $visible ) {
|
1560 |
-
|
1561 |
-
$value = $default;
|
1562 |
-
|
1563 |
-
if ( isset( $instance[ $key ] ) ) {
|
1564 |
-
$value = $instance[ $key ];
|
1565 |
-
}
|
1566 |
-
|
1567 |
-
$ret = '<label for="' . $this->get_field_id( $key ) . "\">\n" .
|
1568 |
-
$label .
|
1569 |
-
'<input placeholder="' . $placeholder . '" id="' . $this->get_field_id( $key ) . '" name="' . $this->get_field_name( $key ) . '" type="text" value="' . esc_attr( $value ) . '" autocomplete="off"/>' . "\n" .
|
1570 |
-
"</label>\n";
|
1571 |
-
|
1572 |
-
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1573 |
-
}
|
1574 |
-
|
1575 |
-
/**
|
1576 |
-
* Generate a form P element containing a number input
|
1577 |
-
*
|
1578 |
-
* @since 4.8
|
1579 |
-
* @param array $instance The instance.
|
1580 |
-
* @param string $key The key in the instance array.
|
1581 |
-
* @param string $label The label to display and associate with the input.
|
1582 |
-
* expected to be escaped.
|
1583 |
-
* @param int $default The value to use if the key is not set in the instance.
|
1584 |
-
* @param int $min The minimum value allowed to be input.
|
1585 |
-
* @param int $max The maximum value allowed to be input.
|
1586 |
-
* @param string $placeholder The placeholder string to be used. expected to be escaped.
|
1587 |
-
* @param bool $visible Indicates if the element should be visible when rendered.
|
1588 |
-
*
|
1589 |
-
* @return string HTML a P element contaning the input, its label, class based on the key
|
1590 |
-
* and style set to display:none if visibility is off.
|
1591 |
-
*/
|
1592 |
-
private function get_number_input_block_html( $instance, $key, $label, $default, $min, $max, $placeholder, $visible ) {
|
1593 |
-
|
1594 |
-
$value = $default;
|
1595 |
-
|
1596 |
-
if ( isset( $instance[ $key ] ) ) {
|
1597 |
-
$value = $instance[ $key ];
|
1598 |
-
}
|
1599 |
-
|
1600 |
-
$minmax = '';
|
1601 |
-
if ( '' !== $min ) {
|
1602 |
-
$minmax .= ' min="' . $min . '"';
|
1603 |
-
}
|
1604 |
-
if ( '' !== $max ) {
|
1605 |
-
$minmax .= ' max="' . $max . '"';
|
1606 |
-
}
|
1607 |
-
|
1608 |
-
$ret = '<label for="' . $this->get_field_id( $key ) . "\">\n" .
|
1609 |
-
esc_html( $label ) . "\n" .
|
1610 |
-
'<input placeholder="' . $placeholder . '" id="' . esc_attr( $this->get_field_id( $key ) ) . '" name="' . esc_attr( $this->get_field_name( $key ) ) . '" class="' . esc_attr( $key ) . '" type="number"' . $minmax . ' value="' . esc_attr( $value ) . '" autocomplete="off" />' . "\n" .
|
1611 |
-
"</label>\n";
|
1612 |
-
|
1613 |
-
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1614 |
-
}
|
1615 |
-
|
1616 |
-
/**
|
1617 |
-
* Generate a form P element containing a checkbox input
|
1618 |
-
*
|
1619 |
-
* @since 4.8
|
1620 |
-
* @param array $instance The instance.
|
1621 |
-
* @param string $key The key in the instance array.
|
1622 |
-
* @param string $label The label to display and associate with the checkbox.
|
1623 |
-
* should be escaped string.
|
1624 |
-
* @param bool $default The value to use if the key is not set in the instance.
|
1625 |
-
* @param bool $visible Indicates if the element should be visible when rendered.
|
1626 |
-
*
|
1627 |
-
* @return string HTML a P element contaning the checkbox, its label, class based on the key
|
1628 |
-
* and style set to display:none if visibility is off.
|
1629 |
-
*/
|
1630 |
-
private function get_checkbox_block_html( $instance, $key, $label, $default, $visible ) {
|
1631 |
-
|
1632 |
-
$value = $default;
|
1633 |
-
|
1634 |
-
if ( array_key_exists( $key, $instance ) ) {
|
1635 |
-
if ( $instance[ $key ] ) {
|
1636 |
-
$value = true;
|
1637 |
-
} else {
|
1638 |
-
$value = false;
|
1639 |
-
}
|
1640 |
-
}
|
1641 |
-
$ret = '<label for="' . esc_attr( $this->get_field_id( $key ) ) . "\">\n" .
|
1642 |
-
'<input id="' . esc_attr( $this->get_field_id( $key ) ) . '" name="' . esc_attr( $this->get_field_name( $key ) ) . '" type="checkbox" ' . checked( $value, true, false ) . '/>' . "\n" .
|
1643 |
-
$label .
|
1644 |
-
"</label>\n";
|
1645 |
-
|
1646 |
-
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1647 |
-
}
|
1648 |
-
|
1649 |
-
/**
|
1650 |
-
* The widget configuration form back end.
|
1651 |
-
*
|
1652 |
-
* @param array $instance The parameters associated with the widget.
|
1653 |
-
* @return void
|
1654 |
-
*/
|
1655 |
-
public function form( $instance ) {
|
1656 |
-
if ( 0 === count( $instance ) ) { // new widget, use defaults.
|
1657 |
-
$instance = default_settings();
|
1658 |
-
} else { // updated widgets come from =< 4.6 excerpt filter is on.
|
1659 |
-
if ( ! isset( $instance['excerpt_filters'] ) ) {
|
1660 |
-
$instance['excerpt_filters'] = 'on';
|
1661 |
-
}
|
1662 |
-
}
|
1663 |
-
|
1664 |
-
$instance = wp_parse_args( (array) $instance, array(
|
1665 |
-
'hide_post_titles' => '',
|
1666 |
-
'excerpt' => '',
|
1667 |
-
'excerpt_more_text' => '',
|
1668 |
-
'excerpt_filters' => '',
|
1669 |
-
'date' => '',
|
1670 |
-
'date_format' => '',
|
1671 |
-
'disable_css' => '',
|
1672 |
-
'disable_font_styles' => '',
|
1673 |
-
'hide_if_empty' => '',
|
1674 |
-
'hide_social_buttons' => '',
|
1675 |
-
'preset_date_format' => 'other',
|
1676 |
-
'thumb' => false,
|
1677 |
-
'thumb_w' => get_option( 'thumbnail_size_w', 150 ),
|
1678 |
-
'thumb_h' => get_option( 'thumbnail_size_h', 150 ),
|
1679 |
-
'default_thunmbnail' => 0,
|
1680 |
-
'use_css_cropping' => true,
|
1681 |
-
'text_do_not_wrap_thumb' => false,
|
1682 |
-
) );
|
1683 |
-
|
1684 |
-
$hide_post_titles = $instance['hide_post_titles'];
|
1685 |
-
$excerpt = $instance['excerpt'];
|
1686 |
-
$excerpt_more_text = $instance['excerpt_more_text'];
|
1687 |
-
$excerpt_filters = $instance['excerpt_filters'];
|
1688 |
-
$date = $instance['date'];
|
1689 |
-
$date_format = $instance['date_format'];
|
1690 |
-
$disable_css = $instance['disable_css'];
|
1691 |
-
$disable_font_styles = $instance['disable_font_styles'];
|
1692 |
-
$hide_if_empty = $instance['hide_if_empty'];
|
1693 |
-
$preset_date_format = $instance['preset_date_format'];
|
1694 |
-
$thumb = ! empty( $instance['thumb'] );
|
1695 |
-
$thumb_w = $instance['thumb_w'];
|
1696 |
-
$thumb_h = $instance['thumb_h'];
|
1697 |
-
$default_thunmbnail = $instance['default_thunmbnail'];
|
1698 |
-
$use_css_cropping = $instance['use_css_cropping'];
|
1699 |
-
$text_do_not_wrap_thumb = $instance['text_do_not_wrap_thumb'];
|
1700 |
-
|
1701 |
-
$cat = $instance['cat'];
|
1702 |
-
|
1703 |
-
if ( ! isset( $style_done ) ) { // what an ugly hack, but can't figure out how to do it nicer on 4.3.
|
1704 |
-
?>
|
1705 |
-
<style type="text/css">
|
1706 |
-
.cpwp_ident {
|
1707 |
-
color: #6A6A6A;
|
1708 |
-
background: #F1F1F1;
|
1709 |
-
padding: 5px;
|
1710 |
-
}
|
1711 |
-
.cpwp_ident > .cpwp_ident {
|
1712 |
-
border-left:5px solid #B3B3B3;
|
1713 |
-
padding: 0 10px;
|
1714 |
-
}
|
1715 |
-
.cpwp_ident > p {
|
1716 |
-
margin: 5px 0;
|
1717 |
-
}
|
1718 |
-
.cpwp_ident > label {
|
1719 |
-
line-height: 2.75;
|
1720 |
-
display: inline-block;
|
1721 |
-
}
|
1722 |
-
.cpwp_ident_top {
|
1723 |
-
margin-top:-1em;
|
1724 |
-
padding-top:1em;
|
1725 |
-
}
|
1726 |
-
|
1727 |
-
.category-widget-cont input[type="number"] {
|
1728 |
-
width:5em;
|
1729 |
-
text-align:center;
|
1730 |
-
}
|
1731 |
-
|
1732 |
-
.categoryposts-template-help th {
|
1733 |
-
text-align:start;
|
1734 |
-
font-weight:bold;
|
1735 |
-
}
|
1736 |
-
|
1737 |
-
.categoryposts-template-help td {
|
1738 |
-
padding:2px;
|
1739 |
-
}
|
1740 |
-
|
1741 |
-
.categoryPosts-template textarea {
|
1742 |
-
font-size:16px;
|
1743 |
-
line-height:20px;
|
1744 |
-
}
|
1745 |
-
</style>
|
1746 |
-
|
1747 |
-
<?php
|
1748 |
-
$style_done = true;
|
1749 |
-
}
|
1750 |
-
?>
|
1751 |
-
|
1752 |
-
<div class="category-widget-cont">
|
1753 |
-
<p><a target="_blank" href="http://tiptoppress.com/term-and-category-based-posts-widget/?utm_source=widget_cpw&utm_campaign=get_pro_cpw&utm_medium=form"><?php esc_html_e( 'Get the Pro version', 'category-posts' ); ?></a></p>
|
1754 |
-
<?php
|
1755 |
-
$this->formTitlePanel( $instance );
|
1756 |
-
$this->formFilterPanel( $instance );
|
1757 |
-
?>
|
1758 |
-
<h4 data-panel="details"><?php esc_html_e( 'Post details', 'category-posts' ); ?></h4>
|
1759 |
-
<div>
|
1760 |
-
<?php
|
1761 |
-
$template = '';
|
1762 |
-
if ( ! isset( $instance['template'] ) ) {
|
1763 |
-
$template = convert_settings_to_template( $instance );
|
1764 |
-
} else {
|
1765 |
-
$template = $instance['template'];
|
1766 |
-
}
|
1767 |
-
?>
|
1768 |
-
<p><?php esc_html_e( 'Displayed parts', 'category-posts' ); ?></p>
|
1769 |
-
<div class="cpwp_ident">
|
1770 |
-
<?php
|
1771 |
-
echo $this->get_textarea_html( $instance, 'template', esc_html__( 'Template', 'category-posts' ) . ' <a href="#" class="dashicons toggle-template-help dashicons-editor-help imgedit-help-toggle"><span class="screen-reader-text">' . esc_html__( 'Show template help', 'category-posts' ) . '</span></a>', $template, '', true, 8 );
|
1772 |
-
preg_match_all( get_template_regex(), $template, $matches );
|
1773 |
-
$tags = array();
|
1774 |
-
if ( ! empty( $matches[0] ) ) {
|
1775 |
-
$tags = array_flip( $matches[0] );
|
1776 |
-
}
|
1777 |
-
?>
|
1778 |
-
<div class="cat-post-template-help">
|
1779 |
-
<p><?php esc_html_e( 'The following text will be replaced with the relevant information. In addition you can use any text and html (if you have the permisions) anywhere you want', 'category-posts' ); ?>
|
1780 |
-
</p>
|
1781 |
-
<table>
|
1782 |
-
<tr>
|
1783 |
-
<th><?php esc_html_e( 'New line', 'category-posts' ); ?></th>
|
1784 |
-
<td><?php esc_html_e( 'Space', 'category-posts' ); ?></td>
|
1785 |
-
</tr>
|
1786 |
-
<tr>
|
1787 |
-
<th><?php esc_html_e( 'Empty line', 'category-posts' ); ?></th>
|
1788 |
-
<td><?php esc_html_e( 'Next line is a paragraph', 'category-posts' ); ?></td>
|
1789 |
-
</tr>
|
1790 |
-
<tr>
|
1791 |
-
<th>%title%</th>
|
1792 |
-
<td><?php esc_html_e( 'Post title', 'category-posts' ); ?></td>
|
1793 |
-
</tr>
|
1794 |
-
<tr>
|
1795 |
-
<th>%thumb%</th>
|
1796 |
-
<td><?php esc_html_e( 'Post thumbnail possibly wrapped by text', 'category-posts' ); ?></td>
|
1797 |
-
</tr>
|
1798 |
-
<tr>
|
1799 |
-
<th>%date%</th>
|
1800 |
-
<td><?php esc_html_e( 'Post publish date', 'category-posts' ); ?></td>
|
1801 |
-
</tr>
|
1802 |
-
<tr>
|
1803 |
-
<th>%excerpt%</th>
|
1804 |
-
<td><?php esc_html_e( 'Post excerpt', 'category-posts' ); ?></td>
|
1805 |
-
</tr>
|
1806 |
-
<tr>
|
1807 |
-
<th>%author%</th>
|
1808 |
-
<td><?php esc_html_e( 'Post author', 'category-posts' ); ?></td>
|
1809 |
-
</tr>
|
1810 |
-
<tr>
|
1811 |
-
<th>%commentnum%</th>
|
1812 |
-
<td><?php esc_html_e( 'The number of comments to the post', 'category-posts' ); ?></td>
|
1813 |
-
</tr>
|
1814 |
-
<tr>
|
1815 |
-
<th>%post_tag%</th>
|
1816 |
-
<td><?php esc_html_e( 'Post tags', 'category-posts' ); ?></td>
|
1817 |
-
</tr>
|
1818 |
-
<tr>
|
1819 |
-
<th>%category%</th>
|
1820 |
-
<td><?php esc_html_e( 'Post categories', 'category-posts' ); ?></td>
|
1821 |
-
</tr>
|
1822 |
-
</table>
|
1823 |
-
</div>
|
1824 |
-
<div class="cat-post-premade_templates">
|
1825 |
-
<p><label><?php esc_html_e( 'Select premade Template', 'category-posts' ); ?></label></p>
|
1826 |
-
<select>
|
1827 |
-
<option value="title"><?php esc_html_e( 'Only the title', 'category-posts' ); ?></option>
|
1828 |
-
<option value="title_excerpt"><?php esc_html_e( 'Title and Excerpt', 'category-posts' ); ?></option>
|
1829 |
-
<option value="title_thumb"><?php esc_html_e( 'Title and Thumbnail', 'category-posts' ); ?></option>
|
1830 |
-
<option value="title_thum_excerpt"><?php esc_html_e( 'Title, Thumbnail and Excerpt', 'category-posts' ); ?></option>
|
1831 |
-
<option value="everything"><?php esc_html_e( 'All with icons', 'category-posts' ); ?></option>
|
1832 |
-
</select>
|
1833 |
-
<p><button type="button" class="button"><?php esc_html_e( 'Select this template', 'category-posts' ); ?></button></p>
|
1834 |
-
</div>
|
1835 |
-
</div>
|
1836 |
-
|
1837 |
-
<?php // Excerpt settings. ?>
|
1838 |
-
<div class="categoryposts-data-panel-excerpt" style="display:<?php echo ( isset( $tags['%excerpt%'] ) ) ? 'block' : 'none'; ?>">
|
1839 |
-
<p><?php esc_html_e( 'Excerpt settings', 'category-posts' ); ?></p>
|
1840 |
-
<div class="cpwp_ident">
|
1841 |
-
<?php
|
1842 |
-
echo $this->get_number_input_block_html( $instance, 'excerpt_length', esc_html__( 'Excerpt length (words):', 'category-posts' ), get_option( 'posts_per_page' ), 1, 200, '', true );
|
1843 |
-
echo $this->get_text_input_block_html( $instance, 'excerpt_more_text', esc_html__( 'Excerpt \'more\' text:', 'category-posts' ), '', esc_attr__( '...', 'category-posts' ), true );
|
1844 |
-
echo $this->get_checkbox_block_html( $instance, 'excerpt_filters', esc_html__( 'Don\'t override Themes and plugin filters', 'category-posts' ), false, true );
|
1845 |
-
?>
|
1846 |
-
</div>
|
1847 |
-
</div>
|
1848 |
-
<div class="categoryposts-data-panel-date" style="display:<?php echo ( isset( $tags['%date%'] ) ) ? 'block' : 'none'; ?>">
|
1849 |
-
<p><?php esc_html_e( 'Date format settings', 'category-posts' ); ?></p>
|
1850 |
-
<div class="cpwp_ident">
|
1851 |
-
<?php
|
1852 |
-
echo $this->get_select_block_html( $instance, 'preset_date_format', esc_html__( 'Date format', 'category-posts' ), array(
|
1853 |
-
'sitedateandtime' => esc_html__( 'Site date and time', 'category-posts' ),
|
1854 |
-
'sitedate' => esc_html__( 'Site date', 'category-posts' ),
|
1855 |
-
'sincepublished' => esc_html__( 'Time since published', 'category-posts' ),
|
1856 |
-
'other' => esc_html__( 'PHP style format', 'category-posts' ),
|
1857 |
-
), 'sitedateandtime', true );
|
1858 |
-
echo $this->get_text_input_block_html( $instance, 'date_format', esc_html__( 'PHP Style Date format', 'category-posts' ), '', 'j M Y', 'other' === $preset_date_format );
|
1859 |
-
?>
|
1860 |
-
</div>
|
1861 |
-
</div>
|
1862 |
-
|
1863 |
-
<?php // Thumbnail settings. ?>
|
1864 |
-
<div class="categoryposts-data-panel-thumb" style="display:<?php echo ( isset( $tags['%thumb%'] ) ) ? 'block' : 'none'; ?>">
|
1865 |
-
<p><?php esc_html_e( 'Thumbnail settings', 'category-posts' ); ?></p>
|
1866 |
-
<div class="cpwp_ident">
|
1867 |
-
<p><?php esc_html_e( 'Thumbnail dimensions (pixel)', 'category-posts' ); ?></p>
|
1868 |
-
<?php
|
1869 |
-
echo $this->get_number_input_block_html( $instance, 'thumb_w', esc_html__( 'Width:', 'category-posts' ), get_option( 'thumbnail_size_w', 150 ), 1, '', '', true );
|
1870 |
-
echo $this->get_number_input_block_html( $instance, 'thumb_h', esc_html__( 'Height:', 'category-posts' ), get_option( 'thumbnail_size_h', 150 ), 1, '', '', true );
|
1871 |
-
|
1872 |
-
echo $this->get_checkbox_block_html( $instance, 'text_do_not_wrap_thumb', esc_html__( 'Do not wrap thumbnail with overflowing text', 'category-posts' ), false, true );
|
1873 |
-
echo $this->get_checkbox_block_html( $instance, 'use_css_cropping', esc_html__( 'CSS crop to requested size', 'category-posts' ), false, false );
|
1874 |
-
echo $this->get_select_block_html( $instance, 'thumb_hover', esc_html__( 'Animation on mouse hover:', 'category-posts' ), array(
|
1875 |
-
'none' => esc_html__( 'None', 'category-posts' ),
|
1876 |
-
'dark' => esc_html__( 'Darker', 'category-posts' ),
|
1877 |
-
'white' => esc_html__( 'Brighter', 'category-posts' ),
|
1878 |
-
'scale' => esc_html__( 'Zoom in', 'category-posts' ),
|
1879 |
-
'blur' => esc_html__( 'Blur', 'category-posts' ),
|
1880 |
-
'icon' => esc_html__( 'Icon', 'category-posts' ),
|
1881 |
-
), 'none', true);
|
1882 |
-
echo $this->get_select_block_html( $instance, 'show_post_format', esc_html__( 'Indicate post format and position', 'category-posts' ), array(
|
1883 |
-
'none' => esc_html__( 'None', 'category-posts' ),
|
1884 |
-
'topleft' => esc_html__( 'Top left', 'category-posts' ),
|
1885 |
-
'bottomleft' => esc_html__( 'Bottom left', 'category-posts' ),
|
1886 |
-
'ceter' => esc_html__( 'Center', 'category-posts' ),
|
1887 |
-
'topright' => esc_html__( 'Top right', 'category-posts' ),
|
1888 |
-
'bottomright' => esc_html__( 'Bottom right', 'category-posts' ),
|
1889 |
-
'nocss' => esc_html__( 'HTML without styling', 'category-posts' ),
|
1890 |
-
), 'none', true );
|
1891 |
-
?>
|
1892 |
-
<p>
|
1893 |
-
<label style="display:block">
|
1894 |
-
<?php esc_html_e( 'Default thumbnail: ', 'category-posts' ); ?>
|
1895 |
-
</label>
|
1896 |
-
<input type="hidden" class="default_thumb_id" id="<?php echo esc_attr( $this->get_field_id( 'default_thunmbnail' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'default_thunmbnail' ) ); ?>" value="<?php echo esc_attr( $default_thunmbnail ); ?>"/>
|
1897 |
-
<span class="default_thumb_img">
|
1898 |
-
<?php
|
1899 |
-
if ( ! $default_thunmbnail ) {
|
1900 |
-
esc_html_e( 'None', 'category-posts' );
|
1901 |
-
} else {
|
1902 |
-
$img = wp_get_attachment_image_src( $default_thunmbnail );
|
1903 |
-
echo '<img width="60" height="60" src="' . esc_url( $img[0] ) . '" />';
|
1904 |
-
}
|
1905 |
-
?>
|
1906 |
-
</span>
|
1907 |
-
</p>
|
1908 |
-
<p>
|
1909 |
-
<button type="button" class="cwp_default_thumb_select button upload-button">
|
1910 |
-
<?php esc_html_e( 'Select image', 'category-posts' ); ?>
|
1911 |
-
</button>
|
1912 |
-
<button type="button" class="cwp_default_thumb_remove button upload-button" <?php if ( ! $default_thunmbnail ) { echo 'style="display:none"'; } ?> >
|
1913 |
-
<?php esc_html_e( 'No default', 'category-posts' ); ?>
|
1914 |
-
</button>
|
1915 |
-
</p>
|
1916 |
-
</div>
|
1917 |
-
</div>
|
1918 |
-
<?php
|
1919 |
-
echo $this->get_checkbox_block_html( $instance, 'everything_is_link', esc_html__( 'Everything is a link', 'category-posts' ), false, true );
|
1920 |
-
?>
|
1921 |
-
</div>
|
1922 |
-
<h4 data-panel="general"><?php esc_html_e( 'General', 'category-posts' ); ?></h4>
|
1923 |
-
<div>
|
1924 |
-
<div class="cpwp_ident">
|
1925 |
-
<?php echo $this->get_checkbox_block_html( $instance, 'disable_css', esc_html__( 'Disable the built-in CSS', 'category-posts' ), false, true ); ?>
|
1926 |
-
<?php echo $this->get_checkbox_block_html( $instance, 'disable_font_styles', esc_html__( 'Disable only font styles', 'category-posts' ), false, true ); ?>
|
1927 |
-
</div>
|
1928 |
-
<?php echo $this->get_checkbox_block_html( $instance, 'hide_if_empty', esc_html__( 'Hide if there are no matching posts', 'category-posts' ), false, true ); ?>
|
1929 |
-
</div>
|
1930 |
-
<h4 data-panel="footer"><?php esc_html_e( 'Footer', 'category-posts' ); ?></h4>
|
1931 |
-
<div>
|
1932 |
-
<?php echo $this->get_text_input_block_html( $instance, 'footer_link_text', esc_html__( 'Footer link text', 'category-posts' ), '', '', true ); ?>
|
1933 |
-
<?php echo $this->get_text_input_block_html( $instance, 'footer_link', esc_html__( 'Footer link URL', 'category-posts' ), '', '', true ); ?>
|
1934 |
-
</div>
|
1935 |
-
<p><a href="<?php echo esc_url( get_edit_user_link() ) . '#' . __NAMESPACE__; ?>"><?php esc_html_e( 'Widget admin behaviour settings', 'category-posts' ); ?></a></p>
|
1936 |
-
<p><a target="_blank" href="<?php echo esc_url( DOC_URL ); ?>"><?php esc_html_e( 'Documentation', 'category-posts' ); ?></a></p>
|
1937 |
-
<p><a target="_blank" href="<?php echo esc_url( SUPPORT_URL ); ?>"><?php esc_html_e( 'Support', 'category-posts' ); ?></a></p>
|
1938 |
-
<p><?php echo sprintf( wp_kses( __( 'We are on <a href="%1$s">Facebook</a> and <a href="%2$s">Twitter</a>.', 'category-posts' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://www.facebook.com/TipTopPress' ), esc_url( 'https://twitter.com/TipTopPress' ) ); ?></p>
|
1939 |
-
</div>
|
1940 |
-
<?php
|
1941 |
-
}
|
1942 |
-
}
|
1943 |
-
|
1944 |
/*
|
1945 |
* Plugin action links section
|
1946 |
*/
|
@@ -1961,11 +405,14 @@ add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), __NAMESPACE__
|
|
1961 |
* @param array $links The current links about to be displayed.
|
1962 |
*/
|
1963 |
function add_action_links( $links ) {
|
1964 |
-
$pro_link = array(
|
1965 |
-
'<a target="_blank" href="' . esc_url( PRO_URL ) . '">' . esc_html__( 'Get the Pro version', 'category-posts' ) . '</a>',
|
1966 |
-
);
|
1967 |
|
1968 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1969 |
|
1970 |
return $links;
|
1971 |
}
|
@@ -1979,125 +426,26 @@ function register_widget() {
|
|
1979 |
|
1980 |
add_action( 'widgets_init', __NAMESPACE__ . '\register_widget' );
|
1981 |
|
1982 |
-
/**
|
1983 |
-
* Output js code to handle responsive thumbnails
|
1984 |
-
*
|
1985 |
-
* @return void
|
1986 |
-
*
|
1987 |
-
* @since 4.7
|
1988 |
-
*/
|
1989 |
-
function change_cropped_image_dimensions($number,$widgetsettings) { ?>
|
1990 |
-
<script type="text/javascript">
|
1991 |
-
|
1992 |
-
if (typeof jQuery !== 'undefined') {
|
1993 |
-
|
1994 |
-
jQuery( document ).ready(function () {
|
1995 |
-
|
1996 |
-
<?php // namespace. ?>
|
1997 |
-
var cwp_namespace = window.cwp_namespace || {};
|
1998 |
-
cwp_namespace.fluid_images = cwp_namespace.fluid_images || {};
|
1999 |
-
|
2000 |
-
cwp_namespace.fluid_images = {
|
2001 |
-
|
2002 |
-
<?php // variables. ?>
|
2003 |
-
Widgets : {},
|
2004 |
-
widget : null,
|
2005 |
-
|
2006 |
-
<?php // class. ?>
|
2007 |
-
Span : function (_self, _imageRatio) {
|
2008 |
-
|
2009 |
-
<?php // variables. ?>
|
2010 |
-
this.self = _self;
|
2011 |
-
this.imageRatio = _imageRatio;
|
2012 |
-
},
|
2013 |
-
|
2014 |
-
<?php // class. ?>
|
2015 |
-
WidgetPosts : function (widget, ratio) {
|
2016 |
-
|
2017 |
-
<?php // variables. ?>
|
2018 |
-
this.Spans = {};
|
2019 |
-
this.allSpans = widget.find( '.cat-post-crop' );
|
2020 |
-
this.firstSpan = this.allSpans.first();
|
2021 |
-
this.maxSpanWidth = this.firstSpan.width();
|
2022 |
-
this.firstListItem = this.firstSpan.closest( 'li' );
|
2023 |
-
this.ratio = ratio;
|
2024 |
-
|
2025 |
-
for( var i = 0; i < this.allSpans.length; i++ ){
|
2026 |
-
var imageRatio = this.firstSpan.width() / jQuery(this.allSpans[i]).find( 'img' ).height();
|
2027 |
-
this.Spans[i] = new cwp_namespace.fluid_images.Span( jQuery(this.allSpans[i]), imageRatio );
|
2028 |
-
}
|
2029 |
-
|
2030 |
-
<?php // functions. ?>
|
2031 |
-
this.changeImageSize = function changeImageSize() {
|
2032 |
-
|
2033 |
-
this.listItemWidth = this.firstListItem.width();
|
2034 |
-
this.SpanWidth = this.firstSpan.width();
|
2035 |
-
|
2036 |
-
if(this.listItemWidth < this.SpanWidth || <?php /* if the layout-width have not enough space to show the regular source-width */ echo "\r\n"; ?>
|
2037 |
-
this.listItemWidth < this.maxSpanWidth) { <?php /* defined start and stop working width for the image: Accomplish only the image width will be get smaller as the source-width */ echo "\r\n"; ?>
|
2038 |
-
this.allSpans.width( this.listItemWidth );
|
2039 |
-
var spanHeight = this.listItemWidth / this.ratio;
|
2040 |
-
this.allSpans.height( spanHeight );
|
2041 |
-
|
2042 |
-
for( var index in this.Spans ){
|
2043 |
-
var imageHeight = this.listItemWidth / this.Spans[index].imageRatio;
|
2044 |
-
jQuery(this.Spans[index].self).find( 'img' ).css({
|
2045 |
-
height: imageHeight,
|
2046 |
-
marginTop: -(imageHeight - spanHeight) / 2
|
2047 |
-
});
|
2048 |
-
};
|
2049 |
-
}
|
2050 |
-
}
|
2051 |
-
},
|
2052 |
-
}
|
2053 |
-
|
2054 |
-
<?php
|
2055 |
-
/**
|
2056 |
-
* The cpw_crop_widgets is an internal filter that is used
|
2057 |
-
* to gather the ids of the widgets to which apply cropping
|
2058 |
-
*
|
2059 |
-
* For easier prevention of duplication, the widget id number should be an index
|
2060 |
-
* in the array while the ratio of width/height be the value
|
2061 |
-
*/
|
2062 |
-
$widgets_ids = apply_filters( 'cpw_crop_widgets', array() );
|
2063 |
-
foreach ( $widgets_ids as $num => $ratio ) {
|
2064 |
-
if($num != $number) {
|
2065 |
-
continue;
|
2066 |
-
} ?>
|
2067 |
-
cwp_namespace.fluid_images.widget = jQuery('#<?php echo esc_attr( $num ); ?>');
|
2068 |
-
cwp_namespace.fluid_images.Widgets['<?php echo esc_attr( $num ); ?>'] = new cwp_namespace.fluid_images.WidgetPosts(cwp_namespace.fluid_images.widget,<?php echo esc_attr( $ratio ); ?>);
|
2069 |
-
<?php } ?>
|
2070 |
-
|
2071 |
-
<?php /* do on page load or on resize the browser window */ echo "\r\n"; ?>
|
2072 |
-
jQuery(window).on('load resize', function() {
|
2073 |
-
for (var widget in cwp_namespace.fluid_images.Widgets) {
|
2074 |
-
cwp_namespace.fluid_images.Widgets[widget].changeImageSize();
|
2075 |
-
}
|
2076 |
-
});
|
2077 |
-
});
|
2078 |
-
}
|
2079 |
-
</script>
|
2080 |
-
<?php
|
2081 |
-
}
|
2082 |
-
|
2083 |
/*
|
2084 |
* shortcode section.
|
2085 |
*/
|
2086 |
|
2087 |
/**
|
2088 |
-
*
|
2089 |
*
|
2090 |
-
*
|
2091 |
-
*
|
2092 |
*
|
2093 |
-
*
|
|
|
2094 |
*
|
2095 |
-
*
|
|
|
2096 |
*
|
2097 |
-
*
|
2098 |
*/
|
2099 |
-
function shortcode_settings( $name ) {
|
2100 |
-
$meta = get_post_meta(
|
2101 |
|
2102 |
if ( ! empty( $meta ) && ! is_array( reset( $meta ) ) ) {
|
2103 |
$meta = array( '' => $meta ); // the conversion.
|
@@ -2111,16 +459,19 @@ function shortcode_settings( $name ) {
|
|
2111 |
if ( is_customize_preview() ) {
|
2112 |
$o = get_option( '_virtual-' . WIDGET_BASE_ID );
|
2113 |
if ( is_array( $o ) ) {
|
2114 |
-
$instance = $o[
|
|
|
2115 |
}
|
2116 |
}
|
2117 |
-
|
2118 |
if ( isset( $instance['template'] ) && $instance['template'] ) {
|
2119 |
;
|
2120 |
} else {
|
2121 |
$instance['template'] = convert_settings_to_template( $instance );
|
2122 |
}
|
2123 |
|
|
|
|
|
2124 |
return $instance;
|
2125 |
}
|
2126 |
|
@@ -2133,7 +484,7 @@ function shortcode_settings( $name ) {
|
|
2133 |
* @return string An HTML of the "widget" based on its settings, actual or customized
|
2134 |
*/
|
2135 |
function shortcode( $attr, $content = null ) {
|
2136 |
-
$repository = new
|
2137 |
|
2138 |
$shortcodes = $repository->getShortcodes();
|
2139 |
|
@@ -2192,41 +543,52 @@ function shortcode_names( $shortcode_name, $content ) {
|
|
2192 |
*/
|
2193 |
function default_settings() {
|
2194 |
return array(
|
2195 |
-
'title'
|
2196 |
-
'title_link'
|
2197 |
-
'title_link_url'
|
2198 |
-
'hide_title'
|
2199 |
-
'cat'
|
2200 |
-
'num'
|
2201 |
-
'offset'
|
2202 |
-
'sort_by'
|
2203 |
-
'status'
|
2204 |
-
'asc_sort_order'
|
2205 |
-
'exclude_current_post'
|
2206 |
-
'hideNoThumb'
|
2207 |
-
'footer_link_text'
|
2208 |
-
'footer_link'
|
2209 |
-
'thumb_w'
|
2210 |
-
'
|
2211 |
-
'
|
2212 |
-
'
|
2213 |
-
'
|
2214 |
-
'
|
2215 |
-
'
|
2216 |
-
'
|
2217 |
-
'
|
2218 |
-
'
|
2219 |
-
'
|
2220 |
-
'
|
2221 |
-
'
|
2222 |
-
'
|
2223 |
-
'
|
2224 |
-
'
|
2225 |
-
'no_cat_childs'
|
2226 |
-
'everything_is_link'
|
2227 |
-
'preset_date_format'
|
2228 |
-
'template'
|
2229 |
-
'text_do_not_wrap_thumb'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2230 |
);
|
2231 |
}
|
2232 |
|
@@ -2288,26 +650,7 @@ add_action( 'save_post', __NAMESPACE__ . '\save_post', 10, 2 );
|
|
2288 |
*/
|
2289 |
function customize_register( $wp_customize ) {
|
2290 |
|
2291 |
-
|
2292 |
-
public $form;
|
2293 |
-
public $title_postfix;
|
2294 |
-
|
2295 |
-
public function render_content() {
|
2296 |
-
$widget_title = 'Category Posts Shortcode' . $this->title_postfix;
|
2297 |
-
?>
|
2298 |
-
<div class="widget-top">
|
2299 |
-
<div class="widget-title"><h3><?php echo esc_html( $widget_title ); ?><span class="in-widget-title"></span></h3></div>
|
2300 |
-
</div>
|
2301 |
-
<div class="widget-inside" style="display: block;">
|
2302 |
-
<div class="form">
|
2303 |
-
<div class="widget-content">
|
2304 |
-
<?php echo $this->form; ?>
|
2305 |
-
</div>
|
2306 |
-
</div>
|
2307 |
-
</div>
|
2308 |
-
<?php
|
2309 |
-
}
|
2310 |
-
}
|
2311 |
|
2312 |
$args = array(
|
2313 |
'post_type' => 'any',
|
@@ -2343,14 +686,12 @@ function customize_register( $wp_customize ) {
|
|
2343 |
}
|
2344 |
|
2345 |
foreach ( $meta as $k => $m ) {
|
2346 |
-
|
2347 |
if ( isset( $m['template'] ) && $m['template'] ) {
|
2348 |
;
|
2349 |
} else {
|
2350 |
$m['template'] = convert_settings_to_template( $m );
|
2351 |
}
|
2352 |
-
|
2353 |
-
$m = wp_parse_args( $m, default_settings() );
|
2354 |
|
2355 |
if ( 0 === count( $meta ) ) { // new widget, use defaults.
|
2356 |
;
|
@@ -2360,6 +701,8 @@ function customize_register( $wp_customize ) {
|
|
2360 |
}
|
2361 |
}
|
2362 |
|
|
|
|
|
2363 |
$section_title = $k;
|
2364 |
if ( '' === $section_title ) {
|
2365 |
$section_title = __( '[shortcode]', 'category-posts' );
|
@@ -2415,7 +758,7 @@ function customize_register( $wp_customize ) {
|
|
2415 |
};
|
2416 |
}
|
2417 |
|
2418 |
-
$sc = new
|
2419 |
$wp_customize,
|
2420 |
'_virtual-' . WIDGET_BASE_ID . '[' . $p->ID . '][' . $k . '][title]',
|
2421 |
$args
|
@@ -2501,7 +844,7 @@ function mce_external_plugins( $plugin_array ) {
|
|
2501 |
if ( is_array( $meta ) && isset( $meta['editor'] ) ) {
|
2502 |
;
|
2503 |
} else {
|
2504 |
-
$plugin_array[ __NAMESPACE__ ] = plugins_url( 'js/admin/tinymce.js?ver=' . VERSION, __FILE__ );
|
2505 |
}
|
2506 |
}
|
2507 |
|
@@ -2606,7 +949,7 @@ function show_user_profile( $user ) {
|
|
2606 |
<th><label for="<?php echo __NAMESPACE__; ?>[panels]"><?php esc_html_e( 'Open panels behavior', 'category-posts' ); ?></label></th>
|
2607 |
<td>
|
2608 |
<input type="checkbox" name="<?php echo __NAMESPACE__; ?>[panels]" id="<?php echo __NAMESPACE__; ?>[panels]" <?php checked( $accordion ); ?>>
|
2609 |
-
<label for=<?php echo __NAMESPACE__; ?>[panels]><?php esc_html_e( 'Close the
|
2610 |
</td>
|
2611 |
</tr>
|
2612 |
<tr>
|
@@ -2647,426 +990,6 @@ function personal_options_update( $user_id ) {
|
|
2647 |
}
|
2648 |
}
|
2649 |
|
2650 |
-
/*
|
2651 |
-
* external API.
|
2652 |
-
*/
|
2653 |
-
|
2654 |
-
/**
|
2655 |
-
* Class that represent a virtual widget. Each widget being created will have relevant
|
2656 |
-
* CSS output in the header, but still requires a call for getHTML method or renderHTML
|
2657 |
-
* to get or output the HTML
|
2658 |
-
*
|
2659 |
-
* @since 4.7
|
2660 |
-
*/
|
2661 |
-
class virtualWidget {
|
2662 |
-
|
2663 |
-
/**
|
2664 |
-
* A container for all the "active" objects
|
2665 |
-
*
|
2666 |
-
* @var Array
|
2667 |
-
*
|
2668 |
-
* @since 4.7
|
2669 |
-
*/
|
2670 |
-
private static $collection = array();
|
2671 |
-
|
2672 |
-
/**
|
2673 |
-
* The identifier use as the id of the root html element when the HTML is generated.
|
2674 |
-
*
|
2675 |
-
* @var string
|
2676 |
-
*
|
2677 |
-
* @since 4.7
|
2678 |
-
*/
|
2679 |
-
private $id;
|
2680 |
-
|
2681 |
-
/**
|
2682 |
-
* A container for all the "active" objects
|
2683 |
-
*
|
2684 |
-
* @var string The class name to be use us the class attribute on the root html element.
|
2685 |
-
*
|
2686 |
-
* @since 4.7
|
2687 |
-
*/
|
2688 |
-
private $class;
|
2689 |
-
|
2690 |
-
/**
|
2691 |
-
* Construct the virtual widget. This should happen before wp_head action with priority
|
2692 |
-
* 10 is executed if any CSS output should be generated.
|
2693 |
-
*
|
2694 |
-
* @param string $id The identifier use as the id of the root html element when the HTML
|
2695 |
-
* is generated.
|
2696 |
-
*
|
2697 |
-
* @param string $class The class name to be use us the class attribute on the root html element.
|
2698 |
-
*
|
2699 |
-
* @param array $args The setting to be applied to the widget.
|
2700 |
-
*
|
2701 |
-
* @since 4.7
|
2702 |
-
*/
|
2703 |
-
public function __construct( $id, $class, $args ) {
|
2704 |
-
$this->id = $id;
|
2705 |
-
$this->class = $class;
|
2706 |
-
self::$collection[ $id ] = wp_parse_args( $args, default_settings() );
|
2707 |
-
}
|
2708 |
-
|
2709 |
-
/**
|
2710 |
-
* Do what ever cleanup needed when the object is destroyed.
|
2711 |
-
*
|
2712 |
-
* @since 4.7
|
2713 |
-
*/
|
2714 |
-
public function __destruct() {
|
2715 |
-
unset( self::$collection[ $this->id ] );
|
2716 |
-
}
|
2717 |
-
|
2718 |
-
/**
|
2719 |
-
* Return the HTML of the widget as is generated based on the settings passed at construction time
|
2720 |
-
*
|
2721 |
-
* @return string
|
2722 |
-
*
|
2723 |
-
* @since 4.7
|
2724 |
-
*/
|
2725 |
-
public function getHTML() {
|
2726 |
-
|
2727 |
-
$widget = new Widget();
|
2728 |
-
$widget->number = $this->id; // needed to make a unique id for the widget html element.
|
2729 |
-
ob_start();
|
2730 |
-
$args = self::$collection[ $this->id ];
|
2731 |
-
$args['is_shortcode'] = true; // indicate that we are doing shortcode processing to outputting funtions.
|
2732 |
-
$widget->widget(array(
|
2733 |
-
'before_widget' => '',
|
2734 |
-
'after_widget' => '',
|
2735 |
-
'before_title' => '',
|
2736 |
-
'after_title' => '',
|
2737 |
-
), $args);
|
2738 |
-
$ret = ob_get_clean();
|
2739 |
-
$ret = '<div id="' . esc_attr( $this->id ) . '" class="' . esc_attr( $this->class ) . '">' . $ret . '</div>';
|
2740 |
-
return $ret;
|
2741 |
-
}
|
2742 |
-
|
2743 |
-
/**
|
2744 |
-
* Output the widget HTML
|
2745 |
-
*
|
2746 |
-
* Just a wrapper that output getHTML
|
2747 |
-
*
|
2748 |
-
* @return void
|
2749 |
-
*
|
2750 |
-
* @since 4.7
|
2751 |
-
*/
|
2752 |
-
public function renderHTML() {
|
2753 |
-
echo $this->getHTML();
|
2754 |
-
}
|
2755 |
-
|
2756 |
-
/**
|
2757 |
-
* Calculate the CSS rules required for the widget as is generated based on the settings passed at construction time
|
2758 |
-
*
|
2759 |
-
* @param bool $is_shortcode Indicated if rules are generated for a shortcode.
|
2760 |
-
* @param array $ret "returned" Collection of CSS rules.
|
2761 |
-
*
|
2762 |
-
* @since 4.7
|
2763 |
-
*/
|
2764 |
-
public function getCSSRules( $is_shortcode, &$rules ) {
|
2765 |
-
$ret = array();
|
2766 |
-
$settings = self::$collection[ $this->id ];
|
2767 |
-
$widget_id = $this->id;
|
2768 |
-
if ( ! $is_shortcode ) {
|
2769 |
-
$widget_id .= '-internal';
|
2770 |
-
}
|
2771 |
-
$disable_css = isset( $settings['disable_css'] ) && $settings['disable_css'];
|
2772 |
-
|
2773 |
-
if ( ! $disable_css ) { // checks if css disable is not set.
|
2774 |
-
|
2775 |
-
$styles = array( // styles that should be applied to all widgets.
|
2776 |
-
'thumb_clenup' => '.cat-post-item img {max-width: initial; max-height: initial; margin: initial;}',
|
2777 |
-
'author_clenup' => '.cat-post-author {margin-bottom: 0;}',
|
2778 |
-
'thumb' => '.cat-post-thumbnail {margin: 5px 10px 5px 0;}',
|
2779 |
-
'item_clenup' => '.cat-post-item:before {content: ""; clear: both;}',
|
2780 |
-
);
|
2781 |
-
|
2782 |
-
if ( ! ( isset( $settings['disable_font_styles'] ) && $settings['disable_font_styles'] ) ) { // checks if disable font styles is not set.
|
2783 |
-
// add general styles which apply to font styling.
|
2784 |
-
$styles['title_font'] = '.cat-post-title {font-size: 15px;}';
|
2785 |
-
$styles['current_title_font'] = '.cat-post-current .cat-post-title {font-weight: bold; text-transform: uppercase;}';
|
2786 |
-
$styles['date_font'] = '.cat-post-date {font-size: 14px; line-height: 18px; font-style: italic; margin-bottom: 5px;}';
|
2787 |
-
$styles['comment_num_font'] = '.cat-post-comment-num {font-size: 14px; line-height: 18px;}';
|
2788 |
-
}
|
2789 |
-
|
2790 |
-
/*
|
2791 |
-
* The twenty seventeen theme have a border between the LI elements of a widget,
|
2792 |
-
* so remove our border if we detect its use to avoid conflicting styling.
|
2793 |
-
*/
|
2794 |
-
if ( ! $is_shortcode && function_exists( 'twentyseventeen_setup' ) ) {
|
2795 |
-
$styles['item_style'] = '.cat-post-item {list-style: none; list-style-type: none; margin: 0; padding: 3px 0;}';
|
2796 |
-
} else {
|
2797 |
-
$styles['item_style'] = '.cat-post-item {border-bottom: 1px solid #ccc; list-style: none; list-style-type: none; margin: 3px 0; padding: 3px 0;}';
|
2798 |
-
$styles['last_item_style'] = '.cat-post-item:last-child {border-bottom: none;}';
|
2799 |
-
}
|
2800 |
-
|
2801 |
-
// everything link related styling
|
2802 |
-
// if we are dealing with "everything is a link" option, we need to add the clear:both to the a element, not the div.
|
2803 |
-
if ( isset( $settings['everything_is_link'] ) && $settings['everything_is_link'] ) {
|
2804 |
-
$styles['after_item'] = '.cat-post-item a:after {content: ""; display: table; clear: both;}';
|
2805 |
-
} else {
|
2806 |
-
$styles['after_item'] = '.cat-post-item:after {content: ""; display: table; clear: both;}';
|
2807 |
-
}
|
2808 |
-
|
2809 |
-
// add post format css if needed.
|
2810 |
-
if ( isset( $settings['template'] ) && preg_match( '/%thumb%/', $settings['template'] ) ) {
|
2811 |
-
if ( ! isset( $settings['show_post_format'] ) || ( ( 'none' !== $settings['show_post_format'] ) && ( 'nocss' !== $settings['show_post_format'] ) ) ) {
|
2812 |
-
static $fonts_added = false;
|
2813 |
-
if ( ! $fonts_added ) {
|
2814 |
-
$fonturl = esc_url( plugins_url( 'icons/font', __FILE__ ) );
|
2815 |
-
$ret['post_format_font'] = "@font-face {\n" .
|
2816 |
-
"font-family: 'cat_post';\n" .
|
2817 |
-
"src: url('$fonturl/cat_post.eot?58348147');\n" .
|
2818 |
-
"src: url('$fonturl/cat_post.eot?58348147#iefix') format('embedded-opentype'),\n" .
|
2819 |
-
" url('$fonturl/cat_post.woff2?58348147') format('woff2'),\n" .
|
2820 |
-
" url('$fonturl/cat_post.woff?58348147') format('woff'),\n" .
|
2821 |
-
" url('$fonturl/cat_post.ttf?58348147') format('truetype');\n" .
|
2822 |
-
" font-weight: normal;\n" .
|
2823 |
-
" font-style: normal;\n" .
|
2824 |
-
"}\n";
|
2825 |
-
}
|
2826 |
-
$fonts_added = true;
|
2827 |
-
|
2828 |
-
$placement = '';
|
2829 |
-
switch ( $settings['show_post_format'] ) {
|
2830 |
-
case 'topleft':
|
2831 |
-
$placement = 'top:10%; left:10%;';
|
2832 |
-
break;
|
2833 |
-
case 'bottomleft':
|
2834 |
-
$placement = 'bottom:10%; left:10%;';
|
2835 |
-
break;
|
2836 |
-
case 'ceter':
|
2837 |
-
$placement = 'top:calc(50% - 34px); left:calc(50% - 34px);';
|
2838 |
-
break;
|
2839 |
-
case 'topright':
|
2840 |
-
$placement = 'top:10%; right:10%;';
|
2841 |
-
break;
|
2842 |
-
case 'bottomright':
|
2843 |
-
$placement = 'bottom:10%; right:10%;';
|
2844 |
-
break;
|
2845 |
-
}
|
2846 |
-
$styles['post_format_thumb'] = '.cat-post-thumbnail span {position:relative}';
|
2847 |
-
$styles['post_format_icon_styling'] = '.cat-post-format:before {font-family: "cat_post"; position:absolute; color:#FFFFFF; font-size:64px; line-height: 1; ' . $placement . '}';
|
2848 |
-
|
2849 |
-
$styles['post_format_icon_aside'] = ".cat-post-format-aside:before { content: '\\f0f6'; }";
|
2850 |
-
$styles['post_format_icon_chat'] = ".cat-post-format-chat:before { content: '\\e802'; }";
|
2851 |
-
$styles['post_format_icon_gallery'] = ".cat-post-format-gallery:before { content: '\\e805'; }";
|
2852 |
-
$styles['post_format_icon_link'] = ".cat-post-format-link:before { content: '\\e809'; }";
|
2853 |
-
$styles['post_format_icon_image'] = ".cat-post-format-image:before { content: '\\e800'; }";
|
2854 |
-
$styles['post_format_icon_quote'] = ".cat-post-format-quote:before { content: '\\f10d'; }";
|
2855 |
-
$styles['post_format_icon_status'] = ".cat-post-format-status:before { content: '\\e80a'; }";
|
2856 |
-
$styles['post_format_icon_video'] = ".cat-post-format-video:before { content: '\\e801'; }";
|
2857 |
-
$styles['post_format_icon_audio'] = ".cat-post-format-audio:before { content: '\\e803'; }";
|
2858 |
-
|
2859 |
-
}
|
2860 |
-
}
|
2861 |
-
|
2862 |
-
foreach ( $styles as $key => $style ) {
|
2863 |
-
$ret[ $key ] = '#' . $widget_id . ' ' . $style;
|
2864 |
-
}
|
2865 |
-
|
2866 |
-
if ( $is_shortcode ) {
|
2867 |
-
// Twenty Sixteen Theme adds underlines to links with box whadow wtf ...
|
2868 |
-
$ret['twentysixteen_thumb'] = '#' . $widget_id . ' .cat-post-thumbnail {box-shadow:none}'; // this for the thumb link.
|
2869 |
-
if ( ! ( isset( $settings['disable_font_styles'] ) && $settings['disable_font_styles'] ) ) { // checks if disable font styles is not set.
|
2870 |
-
$ret['twentysixteen_tag_link'] = '#' . $widget_id . ' .cat-post-tax-post_tag a {box-shadow:none}'; // this for the tag link.
|
2871 |
-
$ret['twentysixteen_tag_span'] = '#' . $widget_id . ' .cat-post-tax-post_tag span {box-shadow:none}'; // this for the tag link.
|
2872 |
-
}
|
2873 |
-
// Twenty Fifteen Theme adds border ...
|
2874 |
-
$ret['twentyfifteen_thumb'] = '#' . $widget_id . ' .cat-post-thumbnail {border:0}'; // this for the thumb link.
|
2875 |
-
if ( ! ( isset( $settings['disable_font_styles'] ) && $settings['disable_font_styles'] ) ) { // checks if disable font styles is not set.
|
2876 |
-
$ret['twentysixteen_tag_link'] = '#' . $widget_id . ' .cat-post-tax-post_tag a {border:0}'; // this for the tag link.
|
2877 |
-
$ret['twentysixteen_tag_span'] = '#' . $widget_id . ' .cat-post-tax-post_tag span {border:0}'; // this for the tag link.
|
2878 |
-
}
|
2879 |
-
}
|
2880 |
-
|
2881 |
-
// probably all Themes have too much margin on their p element when used in the shortcode or widget.
|
2882 |
-
$ret['p_styling'] = '#' . $widget_id . ' p {margin:5px 0 0 0}'; // since on bottom it will make the spacing on cover
|
2883 |
-
// bigger (add to the padding) use only top for now.
|
2884 |
-
$ret['div_styling'] = '#' . $widget_id . ' li > div {margin:5px 0 0 0; clear:both;}'; // Add margin between the rows.
|
2885 |
-
|
2886 |
-
// use WP dashicons in the template (e.g. for premade Template 'All and icons')
|
2887 |
-
$ret['dashicons'] = '#' . $widget_id . ' .dashicons {vertical-align:middle;}';
|
2888 |
-
}
|
2889 |
-
|
2890 |
-
// Regardless if css is disabled we need some styling for the thumbnail
|
2891 |
-
// to make sure cropping is properly done, and they fit the allocated space.
|
2892 |
-
if ( isset( $settings['template'] ) && preg_match( '/%thumb%/', $settings['template'], $m, PREG_OFFSET_CAPTURE ) ) {
|
2893 |
-
if ( isset( $settings['use_css_cropping'] ) && $settings['use_css_cropping'] ) {
|
2894 |
-
$ret['thumb_crop'] = '#' . $widget_id . ' .cat-post-crop {overflow: hidden; display:inline-block}';
|
2895 |
-
} else {
|
2896 |
-
$ret['thumb_overflow'] = '#' . $widget_id . ' .cat-post-thumbnail span {overflow: hidden; display:inline-block}';
|
2897 |
-
}
|
2898 |
-
$ret['thumb_styling'] = '#' . $widget_id . ' .cat-post-item img {margin: initial;}';
|
2899 |
-
|
2900 |
-
// Thumbnail related positioning rules.
|
2901 |
-
$wrap = isset( $settings['text_do_not_wrap_thumb'] ) && $settings['text_do_not_wrap_thumb'];
|
2902 |
-
if ( $wrap ) {
|
2903 |
-
$ret['thumb_flex'] = '#' . $widget_id . ' .cat-post-do-not-wrap-thumbnail {display:flex;}'; // Thumbnail container should flex.
|
2904 |
-
}
|
2905 |
-
$ret['text_do_not_wrap_thumb'] = '#' . $widget_id . ' .cat-post-thumbnail {float:left;}';
|
2906 |
-
}
|
2907 |
-
|
2908 |
-
// Some hover effect require css to work, add it even if CSS is disabled.
|
2909 |
-
if ( isset( $settings['thumb_hover'] ) ) {
|
2910 |
-
switch ( $settings['thumb_hover'] ) {
|
2911 |
-
case 'white':
|
2912 |
-
$ret['white_hover_background'] = '#' . $widget_id . ' .cat-post-white {background-color: white;}';
|
2913 |
-
$ret['white_hover_thumb'] = '#' . $widget_id . ' .cat-post-white img {padding-bottom: 0 !important; -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease;}';
|
2914 |
-
$ret['white_hover_transform'] = '#' . $widget_id . ' .cat-post-white:hover img {opacity: 0.8;}';
|
2915 |
-
break;
|
2916 |
-
case 'dark':
|
2917 |
-
$ret['dark_hover_thumb'] = '#' . $widget_id . ' .cat-post-dark img {padding-bottom: 0 !important; -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease;}';
|
2918 |
-
$ret['dark_hover_transform'] = '#' . $widget_id . ' .cat-post-dark:hover img {-webkit-filter: brightness(75%); -moz-filter: brightness(75%); -ms-filter: brightness(75%); -o-filter: brightness(75%); filter: brightness(75%);}';
|
2919 |
-
break;
|
2920 |
-
case 'scale':
|
2921 |
-
$ret['scale_hover_thumb'] = '#' . $widget_id . ' .cat-post-scale img {margin: initial; padding-bottom: 0 !important; -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease;}';
|
2922 |
-
$ret['scale_hover_transform'] = '#' . $widget_id . ' .cat-post-scale:hover img {-webkit-transform: scale(1.1, 1.1); -ms-transform: scale(1.1, 1.1); transform: scale(1.1, 1.1);}';
|
2923 |
-
break;
|
2924 |
-
case 'blur':
|
2925 |
-
$ret['blur_hover_thumb'] = '#' . $widget_id . ' .cat-post-blur img {padding-bottom: 0 !important; -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease;}';
|
2926 |
-
$ret['blur_hover_transform'] = '#' . $widget_id . ' .cat-post-blur:hover img {-webkit-filter: blur(2px); -moz-filter: blur(2px); -o-filter: blur(2px); -ms-filter: blur(2px); filter: blur(2px);}';
|
2927 |
-
break;
|
2928 |
-
case 'icon':
|
2929 |
-
$fonturl = esc_url( plugins_url( 'icons/font', __FILE__ ) );
|
2930 |
-
$ret['icon_hover_font'] = "@font-face {\n" .
|
2931 |
-
"font-family: 'cat_post';\n" .
|
2932 |
-
"src: url('$fonturl/cat_post.eot?58348147');\n" .
|
2933 |
-
"src: url('$fonturl/cat_post.eot?58348147#iefix') format('embedded-opentype'),\n" .
|
2934 |
-
" url('$fonturl/cat_post.woff2?58348147') format('woff2'),\n" .
|
2935 |
-
" url('$fonturl/cat_post.woff?58348147') format('woff'),\n" .
|
2936 |
-
" url('$fonturl/cat_post.ttf?58348147') format('truetype');\n" .
|
2937 |
-
" font-weight: normal;\n" .
|
2938 |
-
" font-style: normal;\n" .
|
2939 |
-
"}\n";
|
2940 |
-
|
2941 |
-
$ret['icon_hover_thumb'] = '#' . $widget_id . ' .cat-post-format-standard:before {opacity:0; -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease;}';
|
2942 |
-
$ret['icon_hover_transform'] = '#' . $widget_id . ' .cat-post-thumbnail:hover .cat-post-format-standard:before {opacity:1;}';
|
2943 |
-
if ( isset( $settings['show_post_format'] ) && ( 'none' === $settings['show_post_format'] ) ) {
|
2944 |
-
$ret[] = '#' . $widget_id . ' .cat-post-thumbnail {position:relative}';
|
2945 |
-
$ret[] = '#' . $widget_id . ' .cat-post-icon .cat-post-format:before {font-family: "cat_post"; position:absolute; color:#FFFFFF; font-size:64px; line-height: 1; ' .
|
2946 |
-
'top:calc(50% - 34px); left:calc(50% - 34px);}';
|
2947 |
-
}
|
2948 |
-
$ret[] = '#' . $widget_id . " .cat-post-format-standard:before {padding-left:12px; content: '\\e806'; }";
|
2949 |
-
break;
|
2950 |
-
}
|
2951 |
-
}
|
2952 |
-
$rules[] = $ret;
|
2953 |
-
}
|
2954 |
-
|
2955 |
-
/**
|
2956 |
-
* Output the widget CSS
|
2957 |
-
*
|
2958 |
-
* Just a wrapper that output getCSSRules
|
2959 |
-
*
|
2960 |
-
* @param bool $is_shortcode Indicates if we are in the context os a shortcode.
|
2961 |
-
*
|
2962 |
-
* @since 4.7
|
2963 |
-
*/
|
2964 |
-
public function outputCSS( $is_shortcode ) {
|
2965 |
-
$rules = array();
|
2966 |
-
getCSSRules( $is_shortcode, $rules );
|
2967 |
-
foreach ( $rules as $rule ) {
|
2968 |
-
echo "$rule\n";
|
2969 |
-
}
|
2970 |
-
}
|
2971 |
-
|
2972 |
-
/**
|
2973 |
-
* Get the id the virtual widget was registered with
|
2974 |
-
*
|
2975 |
-
* @return string
|
2976 |
-
*
|
2977 |
-
* @since 4.7
|
2978 |
-
*/
|
2979 |
-
public function id() {
|
2980 |
-
return $this->id;
|
2981 |
-
}
|
2982 |
-
|
2983 |
-
/**
|
2984 |
-
* Get all the setting of the virtual widgets in an array
|
2985 |
-
*
|
2986 |
-
* @return array
|
2987 |
-
*
|
2988 |
-
* @since 4.7
|
2989 |
-
*/
|
2990 |
-
public static function getAllSettings() {
|
2991 |
-
return self::$collection;
|
2992 |
-
}
|
2993 |
-
|
2994 |
-
}
|
2995 |
-
|
2996 |
-
/**
|
2997 |
-
* Class that implement a simple repository for the virtual widgets representing
|
2998 |
-
* actuall shortcode and widgets
|
2999 |
-
*
|
3000 |
-
* @since 4.7
|
3001 |
-
*/
|
3002 |
-
class virtualWidgetsRepository {
|
3003 |
-
|
3004 |
-
/**
|
3005 |
-
* Collection of objects representing shortcodes.
|
3006 |
-
*
|
3007 |
-
* @var array
|
3008 |
-
*
|
3009 |
-
* @since 4.7
|
3010 |
-
*/
|
3011 |
-
private static $shortcodeCollection = array();
|
3012 |
-
|
3013 |
-
/**
|
3014 |
-
* Collection of objects representing widgets.
|
3015 |
-
*
|
3016 |
-
* @var array
|
3017 |
-
*
|
3018 |
-
* @since 4.7
|
3019 |
-
*/
|
3020 |
-
private static $widgetCollection = array();
|
3021 |
-
|
3022 |
-
/**
|
3023 |
-
* Add a virtual widget representing a shortcode to the repository
|
3024 |
-
*
|
3025 |
-
* @param string $index A name to identify the specific shortcode.
|
3026 |
-
* @param virtualWidget $widget The virtual widget for it.
|
3027 |
-
*
|
3028 |
-
* @since 4.7
|
3029 |
-
*/
|
3030 |
-
public function addShortcode( $index, $widget ) {
|
3031 |
-
self::$shortcodeCollection[ $index ] = $widget;
|
3032 |
-
}
|
3033 |
-
|
3034 |
-
/**
|
3035 |
-
* Get all the virtual widgets representing actual shortcodes
|
3036 |
-
*
|
3037 |
-
* @return array
|
3038 |
-
*
|
3039 |
-
* @since 4.7
|
3040 |
-
*/
|
3041 |
-
public function getShortcodes() {
|
3042 |
-
return self::$shortcodeCollection;
|
3043 |
-
}
|
3044 |
-
|
3045 |
-
/**
|
3046 |
-
* Add a virtual widget representing awidget to the repository
|
3047 |
-
*
|
3048 |
-
* @param string $index A name to identify the specific widget.
|
3049 |
-
* @param virtualWidget $widget The virstual widget for it.
|
3050 |
-
*
|
3051 |
-
* @since 4.7
|
3052 |
-
*/
|
3053 |
-
public function addWidget( $index, $widget ) {
|
3054 |
-
self::$widgetCollection[ $index ] = $widget;
|
3055 |
-
}
|
3056 |
-
|
3057 |
-
/**
|
3058 |
-
* Get all the virtual widgets representing actual widgets
|
3059 |
-
*
|
3060 |
-
* @return array
|
3061 |
-
*
|
3062 |
-
* @since 4.7
|
3063 |
-
*/
|
3064 |
-
public function getWidgets() {
|
3065 |
-
return self::$widgetCollection;
|
3066 |
-
}
|
3067 |
-
|
3068 |
-
}
|
3069 |
-
|
3070 |
add_action( 'wp_loaded', __NAMESPACE__ . '\wp_loaded' );
|
3071 |
|
3072 |
/**
|
12 |
Plugin URI: https://wordpress.org/plugins/category-posts/
|
13 |
Description: Adds a widget that shows the most recent posts from a single category.
|
14 |
Author: TipTopPress
|
15 |
+
Version: 4.9.1
|
16 |
Author URI: http://tiptoppress.com
|
17 |
Text Domain: category-posts
|
18 |
Domain Path: /languages
|
25 |
exit;
|
26 |
}
|
27 |
|
28 |
+
const VERSION = '4.9.1';
|
29 |
+
const DOC_URL = 'http://tiptoppress.com/category-posts-widget/documentation-4-9/';
|
30 |
+
const PRO_URL = 'http://tiptoppress.com/term-and-category-based-posts-widget/';
|
31 |
+
const SUPPORT_URL = 'https://wordpress.org/support/plugin/category-posts/';
|
32 |
const SHORTCODE_NAME = 'catposts';
|
33 |
const SHORTCODE_META = 'categoryPosts-shorcode';
|
34 |
const WIDGET_BASE_ID = 'category-posts';
|
35 |
|
36 |
+
require_once __DIR__ . '/class-virtual-widget.php';
|
37 |
+
require_once __DIR__ . '/class-virtual-widgets-repository.php';
|
38 |
+
require_once __DIR__ . '/class-widget.php';
|
39 |
+
require_once __DIR__ . '/loadmore.php';
|
40 |
+
require_once __DIR__ . '/localizeddate.php';
|
41 |
+
|
42 |
/**
|
43 |
* Adds the "Customize" link to the Toolbar on edit mode.
|
44 |
*
|
85 |
*/
|
86 |
function wp_head() {
|
87 |
|
88 |
+
$widget_repository = new Virtual_Widgets_Repository();
|
89 |
|
90 |
$styles = array();
|
91 |
|
99 |
|
100 |
if ( ! empty( $styles ) ) {
|
101 |
?>
|
102 |
+
<style>
|
103 |
<?php
|
104 |
foreach ( $styles as $rules ) {
|
105 |
foreach ( $rules as $rule ) {
|
125 |
global $post;
|
126 |
global $wp_registered_widgets;
|
127 |
|
128 |
+
$repository = new Virtual_Widgets_Repository();
|
129 |
|
130 |
// check first for shortcode settings.
|
131 |
if ( is_singular() ) {
|
132 |
$names = shortcode_names( SHORTCODE_NAME, $post->post_content );
|
133 |
|
134 |
foreach ( $names as $name ) {
|
135 |
+
$meta = shortcode_settings( get_the_ID(), $name );
|
136 |
if ( is_array( $meta ) ) {
|
137 |
$id = WIDGET_BASE_ID . '-shortcode-' . get_the_ID(); // needed to make a unique id for the widget html element.
|
138 |
if ( '' !== $name ) { // if not default name append to the id.
|
139 |
$id .= '-' . sanitize_title( $name ); // sanitize to be on the safe side, not sure where when and how this will be used.
|
140 |
}
|
141 |
+
$repository->addShortcode( $name, new Virtual_Widget( $id, WIDGET_BASE_ID . '-shortcode', $meta ) );
|
142 |
}
|
143 |
}
|
144 |
}
|
159 |
$widgetclass = new $class();
|
160 |
$allsettings = $widgetclass->get_settings();
|
161 |
$settings = isset( $allsettings[ str_replace( $widget_base . '-', '', $widget ) ] ) ? $allsettings[ str_replace( $widget_base . '-', '', $widget ) ] : false;
|
162 |
+
$repository->addWidget( $widget, new Virtual_Widget( $widget, $widget, $settings ) );
|
163 |
}
|
164 |
}
|
165 |
}
|
169 |
|
170 |
add_action( 'wp_head', __NAMESPACE__ . '\wp_head' );
|
171 |
|
172 |
+
/**
|
173 |
+
* Enqueue widget related scripts for the widget front-end
|
174 |
+
*
|
175 |
+
* @since 4.8
|
176 |
+
*/
|
177 |
+
function frontend_script() {
|
178 |
+
$suffix = 'min.js';
|
179 |
+
if ( defined( 'WP_DEBUG' ) && WP_DEBUG === true ) {
|
180 |
+
$suffix = 'js';
|
181 |
+
}
|
182 |
+
wp_enqueue_script( 'cat-posts-frontend-js', plugins_url( 'js/frontend/category-posts-frontend.' . $suffix, __FILE__ ), array( 'jquery' ), VERSION, true );
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Embed the front end JS in the HTML footer.
|
187 |
+
*
|
188 |
+
* @since 4.9
|
189 |
+
*/
|
190 |
+
function embed_front_end_scripts() {
|
191 |
+
$suffix = 'min.js';
|
192 |
+
if ( defined( 'WP_DEBUG' ) && WP_DEBUG === true ) {
|
193 |
+
$suffix = 'js';
|
194 |
+
}
|
195 |
+
echo '<script>';
|
196 |
+
include __DIR__ . '/js/frontend/category-posts-frontend.' . $suffix;
|
197 |
+
echo '</script>';
|
198 |
+
}
|
199 |
+
|
200 |
/**
|
201 |
* Enqueue widget related scripts for the widget admin page and customizer.
|
202 |
*
|
204 |
*/
|
205 |
function admin_scripts( $hook ) {
|
206 |
|
207 |
+
if ( 'widgets.php' === $hook || 'post.php' === $hook ) { // enqueue only for widget admin and customizer. (add if post.php: fix make widget SiteOrigin Page Builder plugin, GH issue #181)
|
208 |
|
209 |
+
/*
|
210 |
+
* Add script to control admin UX.
|
211 |
+
*/
|
212 |
+
|
213 |
+
// Use unminified version of JS when debuging, and minified when not.
|
214 |
+
$suffix = 'min.js';
|
215 |
+
if ( defined( 'WP_DEBUG' ) && WP_DEBUG === true ) {
|
216 |
+
$suffix = 'js';
|
217 |
+
}
|
218 |
+
wp_register_script( 'category-posts-widget-admin-js', plugins_url( 'js/admin/category-posts-widget.' . $suffix, __FILE__ ), array( 'jquery' ), VERSION, true );
|
219 |
wp_enqueue_script( 'category-posts-widget-admin-js' );
|
220 |
|
221 |
$js_data = array( 'accordion' => false );
|
251 |
load_plugin_textdomain( 'category-posts', false, plugin_basename( dirname( __FILE__ ) ) . '/languages' );
|
252 |
}
|
253 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
254 |
/**
|
255 |
+
* Add styles for widget admin sections
|
256 |
*
|
257 |
* @since 4.1
|
258 |
**/
|
259 |
function admin_styles() {
|
260 |
+
wp_enqueue_style( 'cat-posts-admin-styles', plugins_url( 'styles/admin/category-posts-widget.css', __FILE__ ), array(), VERSION, false );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
261 |
}
|
262 |
|
263 |
+
add_action( 'admin_print_styles-widgets.php', __NAMESPACE__ . '\admin_styles' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
264 |
|
265 |
+
// fix make widget SiteOrigin Page Builder plugin, GH issue #181
|
266 |
+
add_action('siteorigin_panel_enqueue_admin_scripts', __NAMESPACE__ . '\admin_styles' );
|
267 |
|
268 |
/**
|
269 |
* Get the tags which might be used in the template.
|
299 |
return $regexp;
|
300 |
}
|
301 |
|
302 |
+
/**
|
303 |
+
* The convert old data structure to current one.
|
304 |
+
*
|
305 |
+
* @param array $settings The settings to upgrade.
|
306 |
+
*
|
307 |
+
* @return array The settings matching current version standard.
|
308 |
+
*
|
309 |
+
* @since 4.8
|
310 |
+
*/
|
311 |
+
function upgrade_settings( $settings ) {
|
312 |
+
|
313 |
+
if ( 0 === count( $settings ) ) {
|
314 |
+
return default_settings();
|
315 |
+
}
|
316 |
+
|
317 |
+
if ( ! isset( $settings['ver'] ) ) {
|
318 |
+
/*
|
319 |
+
* Pre 4.9 version.
|
320 |
+
*/
|
321 |
+
|
322 |
+
// Upgrade the hide if empty option.
|
323 |
+
if ( isset( $settings['hide_if_empty'] ) && $settings['hide_if_empty'] ) {
|
324 |
+
$settings['no_match_handling'] = 'hide';
|
325 |
+
} else {
|
326 |
+
$settings['no_match_handling'] = 'nothing';
|
327 |
+
}
|
328 |
+
if ( isset( $settings['hide_if_empty'] ) ) {
|
329 |
+
unset( $settings['hide_if_empty'] );
|
330 |
+
}
|
331 |
+
}
|
332 |
+
|
333 |
+
$settings['ver'] = VERSION;
|
334 |
+
|
335 |
+
// Make sure all "empty" settings have default value.
|
336 |
+
$settings = wp_parse_args( $settings, default_settings() );
|
337 |
+
|
338 |
+
return $settings;
|
339 |
+
}
|
340 |
+
|
341 |
/**
|
342 |
* Convert pre 4.8 settings into template
|
343 |
*
|
385 |
return $template;
|
386 |
}
|
387 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
388 |
/*
|
389 |
* Plugin action links section
|
390 |
*/
|
405 |
* @param array $links The current links about to be displayed.
|
406 |
*/
|
407 |
function add_action_links( $links ) {
|
|
|
|
|
|
|
408 |
|
409 |
+
if ( ! class_exists( '\\termcategoryPostsPro\\Widget' ) ) {
|
410 |
+
$pro_link = array(
|
411 |
+
'<a target="_blank" href="' . esc_url( PRO_URL ) . '">' . esc_html__( 'Get the Pro version', 'category-posts' ) . '</a>',
|
412 |
+
);
|
413 |
+
|
414 |
+
$links = array_merge( $pro_link, $links );
|
415 |
+
}
|
416 |
|
417 |
return $links;
|
418 |
}
|
426 |
|
427 |
add_action( 'widgets_init', __NAMESPACE__ . '\register_widget' );
|
428 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
429 |
/*
|
430 |
* shortcode section.
|
431 |
*/
|
432 |
|
433 |
/**
|
434 |
+
* Get shortcode settings taking into account if it is being customized
|
435 |
*
|
436 |
+
* When not customized returns the settings as stored in the meta, but when
|
437 |
+
* it is customized returns the setting stored in the virtual option used by the customizer
|
438 |
*
|
439 |
+
* @param string $pid The ID of the post in which the shortcode is.
|
440 |
+
* @param string $name The name of the shortcode to retun, empty string indicates the nameless.
|
441 |
*
|
442 |
+
* @return array The shortcode settings if a short code name exists or is an empty string,
|
443 |
+
* empty array if name not found.
|
444 |
*
|
445 |
+
* @since 4.6
|
446 |
*/
|
447 |
+
function shortcode_settings( $pid, $name ) {
|
448 |
+
$meta = get_post_meta( $pid, SHORTCODE_META, true );
|
449 |
|
450 |
if ( ! empty( $meta ) && ! is_array( reset( $meta ) ) ) {
|
451 |
$meta = array( '' => $meta ); // the conversion.
|
459 |
if ( is_customize_preview() ) {
|
460 |
$o = get_option( '_virtual-' . WIDGET_BASE_ID );
|
461 |
if ( is_array( $o ) ) {
|
462 |
+
$instance = $o[ $pid ][ $name ];
|
463 |
+
$instance['ver'] = VERSION;
|
464 |
}
|
465 |
}
|
466 |
+
|
467 |
if ( isset( $instance['template'] ) && $instance['template'] ) {
|
468 |
;
|
469 |
} else {
|
470 |
$instance['template'] = convert_settings_to_template( $instance );
|
471 |
}
|
472 |
|
473 |
+
$instance = upgrade_settings( $instance );
|
474 |
+
|
475 |
return $instance;
|
476 |
}
|
477 |
|
484 |
* @return string An HTML of the "widget" based on its settings, actual or customized
|
485 |
*/
|
486 |
function shortcode( $attr, $content = null ) {
|
487 |
+
$repository = new Virtual_Widgets_Repository();
|
488 |
|
489 |
$shortcodes = $repository->getShortcodes();
|
490 |
|
543 |
*/
|
544 |
function default_settings() {
|
545 |
return array(
|
546 |
+
'title' => __( 'Recent Posts', 'category-posts' ),
|
547 |
+
'title_link' => false,
|
548 |
+
'title_link_url' => '',
|
549 |
+
'hide_title' => false,
|
550 |
+
'cat' => 0,
|
551 |
+
'num' => get_option( 'posts_per_page' ),
|
552 |
+
'offset' => 1,
|
553 |
+
'sort_by' => 'date',
|
554 |
+
'status' => 'publish',
|
555 |
+
'asc_sort_order' => false,
|
556 |
+
'exclude_current_post' => false,
|
557 |
+
'hideNoThumb' => false,
|
558 |
+
'footer_link_text' => '',
|
559 |
+
'footer_link' => '',
|
560 |
+
'thumb_w' => get_option( 'thumbnail_size_w', 150 ),
|
561 |
+
'thumb_fluid_width' => 100,
|
562 |
+
'thumb_h' => get_option( 'thumbnail_size_h', 150 ),
|
563 |
+
'use_css_cropping' => true,
|
564 |
+
'thumb_hover' => 'none',
|
565 |
+
'hide_post_titles' => false,
|
566 |
+
'excerpt_lines' => 5,
|
567 |
+
'excerpt_length' => 0,
|
568 |
+
'excerpt_more_text' => __( '...', 'category-posts' ),
|
569 |
+
'excerpt_filters' => false,
|
570 |
+
'comment_num' => false,
|
571 |
+
'date_link' => false,
|
572 |
+
'date_format' => '',
|
573 |
+
'disable_css' => false,
|
574 |
+
'disable_font_styles' => false,
|
575 |
+
'show_post_format' => 'none',
|
576 |
+
'no_cat_childs' => false,
|
577 |
+
'everything_is_link' => false,
|
578 |
+
'preset_date_format' => 'sitedateandtime',
|
579 |
+
'template' => "%title%\n\n%thumb%",
|
580 |
+
'text_do_not_wrap_thumb' => false,
|
581 |
+
'enable_loadmore' => false,
|
582 |
+
'loadmore_text' => __( 'Load More', 'category-posts' ),
|
583 |
+
'loading_text' => __( 'Loading...', 'category-posts' ),
|
584 |
+
'date_range' => 'off',
|
585 |
+
'start_date' => '',
|
586 |
+
'end_date' => '',
|
587 |
+
'days_ago' => 30,
|
588 |
+
'no_match_handling' => 'nothing',
|
589 |
+
'no_match_text' => '',
|
590 |
+
'default_thunmbnail' => 0,
|
591 |
+
'ver' => VERSION,
|
592 |
);
|
593 |
}
|
594 |
|
650 |
*/
|
651 |
function customize_register( $wp_customize ) {
|
652 |
|
653 |
+
require_once __DIR__ . '/class-shortcode-control.php';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
654 |
|
655 |
$args = array(
|
656 |
'post_type' => 'any',
|
686 |
}
|
687 |
|
688 |
foreach ( $meta as $k => $m ) {
|
689 |
+
|
690 |
if ( isset( $m['template'] ) && $m['template'] ) {
|
691 |
;
|
692 |
} else {
|
693 |
$m['template'] = convert_settings_to_template( $m );
|
694 |
}
|
|
|
|
|
695 |
|
696 |
if ( 0 === count( $meta ) ) { // new widget, use defaults.
|
697 |
;
|
701 |
}
|
702 |
}
|
703 |
|
704 |
+
$m = upgrade_settings( $m );
|
705 |
+
|
706 |
$section_title = $k;
|
707 |
if ( '' === $section_title ) {
|
708 |
$section_title = __( '[shortcode]', 'category-posts' );
|
758 |
};
|
759 |
}
|
760 |
|
761 |
+
$sc = new ShortCode_Control(
|
762 |
$wp_customize,
|
763 |
'_virtual-' . WIDGET_BASE_ID . '[' . $p->ID . '][' . $k . '][title]',
|
764 |
$args
|
844 |
if ( is_array( $meta ) && isset( $meta['editor'] ) ) {
|
845 |
;
|
846 |
} else {
|
847 |
+
$plugin_array[ __NAMESPACE__ ] = plugins_url( 'js/admin/tinymce.min.js?ver=' . VERSION, __FILE__ );
|
848 |
}
|
849 |
}
|
850 |
|
949 |
<th><label for="<?php echo __NAMESPACE__; ?>[panels]"><?php esc_html_e( 'Open panels behavior', 'category-posts' ); ?></label></th>
|
950 |
<td>
|
951 |
<input type="checkbox" name="<?php echo __NAMESPACE__; ?>[panels]" id="<?php echo __NAMESPACE__; ?>[panels]" <?php checked( $accordion ); ?>>
|
952 |
+
<label for=<?php echo __NAMESPACE__; ?>[panels]><?php esc_html_e( 'Close the currently open panel when opening a new one', 'category-posts' ); ?></label>
|
953 |
</td>
|
954 |
</tr>
|
955 |
<tr>
|
990 |
}
|
991 |
}
|
992 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
993 |
add_action( 'wp_loaded', __NAMESPACE__ . '\wp_loaded' );
|
994 |
|
995 |
/**
|
class-shortcode-control.php
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Costumizer Shortcode control class implementation.
|
4 |
+
*
|
5 |
+
* @package categoryposts.
|
6 |
+
*
|
7 |
+
* @since 4.9
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace categoryPosts;
|
11 |
+
|
12 |
+
// Don't call the file directly.
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Costumizer Shortcode control.
|
19 |
+
*
|
20 |
+
* @since 4.9
|
21 |
+
*/
|
22 |
+
class ShortCode_Control extends \WP_Customize_Control {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* The form that should be displayed in the control.
|
26 |
+
*
|
27 |
+
* @var string
|
28 |
+
*
|
29 |
+
* @since 4.7
|
30 |
+
*/
|
31 |
+
public $form;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* The suffix of the title to be displayed in the control (unescaped).
|
35 |
+
*
|
36 |
+
* @var string
|
37 |
+
*
|
38 |
+
* @since 4.7
|
39 |
+
*/
|
40 |
+
public $title_postfix;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Render the control.
|
44 |
+
*
|
45 |
+
* @since 4.6
|
46 |
+
*/
|
47 |
+
public function render_content() {
|
48 |
+
$widget_title = 'Category Posts Shortcode' . $this->title_postfix;
|
49 |
+
?>
|
50 |
+
<div class="widget-top">
|
51 |
+
<div class="widget-title"><h3><?php echo esc_html( $widget_title ); ?><span class="in-widget-title"></span></h3></div>
|
52 |
+
</div>
|
53 |
+
<div class="widget-inside" style="display: block;">
|
54 |
+
<div class="form">
|
55 |
+
<div class="widget-content">
|
56 |
+
<?php echo $this->form; // Xss off. ?>
|
57 |
+
</div>
|
58 |
+
</div>
|
59 |
+
</div>
|
60 |
+
<?php
|
61 |
+
}
|
62 |
+
}
|
class-virtual-widget.php
ADDED
@@ -0,0 +1,412 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Implementation of virtual widget.
|
4 |
+
*
|
5 |
+
* @package categoryposts.
|
6 |
+
*
|
7 |
+
* @since 4.7
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace categoryPosts;
|
11 |
+
|
12 |
+
// Don't call the file directly.
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Class that represent a virtual widget. Each widget being created will have relevant
|
19 |
+
* CSS output in the header, but still requires a call for getHTML method or renderHTML
|
20 |
+
* to get or output the HTML
|
21 |
+
*
|
22 |
+
* @since 4.7
|
23 |
+
*/
|
24 |
+
class Virtual_Widget {
|
25 |
+
|
26 |
+
/**
|
27 |
+
* A container for all the "active" objects
|
28 |
+
*
|
29 |
+
* @var Array
|
30 |
+
*
|
31 |
+
* @since 4.7
|
32 |
+
*/
|
33 |
+
private static $collection = array();
|
34 |
+
|
35 |
+
/**
|
36 |
+
* The identifier use as the id of the root html element when the HTML is generated.
|
37 |
+
*
|
38 |
+
* @var string
|
39 |
+
*
|
40 |
+
* @since 4.7
|
41 |
+
*/
|
42 |
+
private $id;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* The class name to be use us the class attribute on the root html element.
|
46 |
+
*
|
47 |
+
* @var string
|
48 |
+
*
|
49 |
+
* @since 4.7
|
50 |
+
*/
|
51 |
+
private $class;
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Construct the virtual widget. This should happen before wp_head action with priority
|
55 |
+
* 10 is executed if any CSS output should be generated.
|
56 |
+
*
|
57 |
+
* @param string $id The identifier use as the id of the root html element when the HTML
|
58 |
+
* is generated.
|
59 |
+
*
|
60 |
+
* @param string $class The class name to be use us the class attribute on the root html element.
|
61 |
+
*
|
62 |
+
* @param array $args The setting to be applied to the widget.
|
63 |
+
*
|
64 |
+
* @since 4.7
|
65 |
+
*/
|
66 |
+
public function __construct( $id, $class, $args ) {
|
67 |
+
$this->id = $id;
|
68 |
+
$this->class = $class;
|
69 |
+
self::$collection[ $id ] = upgrade_settings( $args );
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Do what ever cleanup needed when the object is destroyed.
|
74 |
+
*
|
75 |
+
* @since 4.7
|
76 |
+
*/
|
77 |
+
public function __destruct() {
|
78 |
+
unset( self::$collection[ $this->id ] );
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Return the HTML of the widget as is generated based on the settings passed at construction time
|
83 |
+
*
|
84 |
+
* @return string
|
85 |
+
*
|
86 |
+
* @since 4.7
|
87 |
+
*/
|
88 |
+
public function getHTML() {
|
89 |
+
|
90 |
+
$widget = new Widget();
|
91 |
+
$widget->number = $this->id; // needed to make a unique id for the widget html element.
|
92 |
+
ob_start();
|
93 |
+
$args = self::$collection[ $this->id ];
|
94 |
+
$args['is_shortcode'] = true; // indicate that we are doing shortcode processing to outputting funtions.
|
95 |
+
$widget->widget(array(
|
96 |
+
'before_widget' => '',
|
97 |
+
'after_widget' => '',
|
98 |
+
'before_title' => '',
|
99 |
+
'after_title' => '',
|
100 |
+
), $args);
|
101 |
+
$ret = ob_get_clean();
|
102 |
+
$ret = '<div id="' . esc_attr( $this->id ) . '" class="' . esc_attr( $this->class ) . '">' . $ret . '</div>';
|
103 |
+
return $ret;
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Get an array of HTML pre item, for item starting from a specific position.
|
108 |
+
*
|
109 |
+
* @since 4.9
|
110 |
+
*
|
111 |
+
* @param int $start The start element (0 based).
|
112 |
+
* @param int $number The maximal number of elements to return. A value of 0
|
113 |
+
* Indicates to use the widget settings for that.
|
114 |
+
* @param string $context The ID of the post in which the items will be displayed.
|
115 |
+
* A empty string or any value which is not of an ID
|
116 |
+
* of actual post will be treated as if there is no context.
|
117 |
+
*
|
118 |
+
* @return string[] Array of HTML per element with the $start element first
|
119 |
+
* $start+1 next etc. An empty array is returned if there
|
120 |
+
* are no applicable items.
|
121 |
+
*/
|
122 |
+
public function get_elements_HTML( $start, $number, $context ) {
|
123 |
+
$ret = array();
|
124 |
+
|
125 |
+
$widget = new Widget();
|
126 |
+
$widget->number = $this->id; // needed to make a unique id for the widget html element.
|
127 |
+
|
128 |
+
$ret = $widget->get_elements_HTML( self::$collection[ $this->id ], $context, $start, $number );
|
129 |
+
return $ret;
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Output the widget HTML
|
134 |
+
*
|
135 |
+
* Just a wrapper that output getHTML
|
136 |
+
*
|
137 |
+
* @return void
|
138 |
+
*
|
139 |
+
* @since 4.7
|
140 |
+
*/
|
141 |
+
public function renderHTML() {
|
142 |
+
echo $this->getHTML(); // Xss off. Raw HTML is generated elsewhre.
|
143 |
+
}
|
144 |
+
|
145 |
+
/**
|
146 |
+
* Calculate the CSS rules required for the widget as is generated based on the settings passed at construction time
|
147 |
+
*
|
148 |
+
* @param bool $is_shortcode Indicated if rules are generated for a shortcode.
|
149 |
+
* @param array $rules "returned" Collection of CSS rules.
|
150 |
+
*
|
151 |
+
* @since 4.7
|
152 |
+
*/
|
153 |
+
public function getCSSRules( $is_shortcode, &$rules ) {
|
154 |
+
$ret = array();
|
155 |
+
$settings = self::$collection[ $this->id ];
|
156 |
+
$widget_id = $this->id;
|
157 |
+
if ( ! $is_shortcode ) {
|
158 |
+
$widget_id .= '-internal';
|
159 |
+
}
|
160 |
+
$disable_css = isset( $settings['disable_css'] ) && $settings['disable_css'];
|
161 |
+
|
162 |
+
if ( ! $disable_css ) { // checks if css disable is not set.
|
163 |
+
|
164 |
+
$styles = array( // styles that should be applied to all widgets.
|
165 |
+
'normalize' => 'ul {padding: 0;}',
|
166 |
+
'thumb_clenup' => '.cat-post-item img {max-width: initial; max-height: initial; margin: initial;}',
|
167 |
+
'author_clenup' => '.cat-post-author {margin-bottom: 0;}',
|
168 |
+
'thumb' => '.cat-post-thumbnail {margin: 5px 10px 5px 0;}',
|
169 |
+
'item_clenup' => '.cat-post-item:before {content: ""; clear: both;}',
|
170 |
+
);
|
171 |
+
|
172 |
+
if ( ! ( isset( $settings['disable_font_styles'] ) && $settings['disable_font_styles'] ) ) { // checks if disable font styles is not set.
|
173 |
+
// add general styles which apply to font styling.
|
174 |
+
$styles['title_font'] = '.cat-post-title {font-size: 15px;}';
|
175 |
+
$styles['current_title_font'] = '.cat-post-current .cat-post-title {font-weight: bold; text-transform: uppercase;}';
|
176 |
+
$styles['date_font'] = '.cat-post-date {font-size: 14px; line-height: 18px; font-style: italic; margin-bottom: 5px;}';
|
177 |
+
$styles['comment_num_font'] = '.cat-post-comment-num {font-size: 14px; line-height: 18px;}';
|
178 |
+
}
|
179 |
+
|
180 |
+
/*
|
181 |
+
* The twenty seventeen theme have a border between the LI elements of a widget,
|
182 |
+
* so remove our border if we detect its use to avoid conflicting styling.
|
183 |
+
*/
|
184 |
+
if ( ! $is_shortcode && function_exists( 'twentyseventeen_setup' ) ) {
|
185 |
+
$styles['item_style'] = '.cat-post-item {list-style: none; list-style-type: none; margin: 0; padding: 3px 0;}';
|
186 |
+
} else {
|
187 |
+
$styles['item_style'] = '.cat-post-item {border-bottom: 1px solid #ccc; list-style: none; list-style-type: none; margin: 3px 0; padding: 3px 0;}';
|
188 |
+
$styles['last_item_style'] = '.cat-post-item:last-child {border-bottom: none;}';
|
189 |
+
}
|
190 |
+
|
191 |
+
// everything link related styling
|
192 |
+
// if we are dealing with "everything is a link" option, we need to add the clear:both to the a element, not the div.
|
193 |
+
if ( isset( $settings['everything_is_link'] ) && $settings['everything_is_link'] ) {
|
194 |
+
$styles['after_item'] = '.cat-post-item a:after {content: ""; display: table; clear: both;}';
|
195 |
+
} else {
|
196 |
+
$styles['after_item'] = '.cat-post-item:after {content: ""; display: table; clear: both;}';
|
197 |
+
}
|
198 |
+
|
199 |
+
|
200 |
+
if ( isset( $settings['template'] ) && preg_match( '/%excerpt%/', $settings['template'] ) ) {
|
201 |
+
if ( isset( $settings['excerpt_lines'] ) && $settings['excerpt_lines'] != 0 ) {
|
202 |
+
$styles['excerpt_lines'] = '.cat-post-item p {overflow: hidden;text-overflow: ellipsis;white-space: initial;'.
|
203 |
+
'display: -webkit-box;-webkit-line-clamp: '.$settings['excerpt_lines'].';-webkit-box-orient: vertical;}';
|
204 |
+
}
|
205 |
+
}
|
206 |
+
|
207 |
+
// add post format css if needed.
|
208 |
+
if ( isset( $settings['template'] ) && preg_match( '/%thumb%/', $settings['template'] ) ) {
|
209 |
+
if ( ! isset( $settings['show_post_format'] ) || ( ( 'none' !== $settings['show_post_format'] ) && ( 'nocss' !== $settings['show_post_format'] ) ) ) {
|
210 |
+
static $fonts_added = false;
|
211 |
+
if ( ! $fonts_added ) {
|
212 |
+
$fonturl = esc_url( plugins_url( 'icons/font', __FILE__ ) );
|
213 |
+
$ret['post_format_font'] = "@font-face {\n" .
|
214 |
+
"font-family: 'cat_post';\n" .
|
215 |
+
"src: url('$fonturl/cat_post.eot?58348147');\n" .
|
216 |
+
"src: url('$fonturl/cat_post.eot?58348147#iefix') format('embedded-opentype'),\n" .
|
217 |
+
" url('$fonturl/cat_post.woff2?58348147') format('woff2'),\n" .
|
218 |
+
" url('$fonturl/cat_post.woff?58348147') format('woff'),\n" .
|
219 |
+
" url('$fonturl/cat_post.ttf?58348147') format('truetype');\n" .
|
220 |
+
" font-weight: normal;\n" .
|
221 |
+
" font-style: normal;\n" .
|
222 |
+
"}\n";
|
223 |
+
}
|
224 |
+
$fonts_added = true;
|
225 |
+
|
226 |
+
$placement = '';
|
227 |
+
switch ( $settings['show_post_format'] ) {
|
228 |
+
case 'topleft':
|
229 |
+
$placement = 'top:10%; left:10%;';
|
230 |
+
break;
|
231 |
+
case 'bottomleft':
|
232 |
+
$placement = 'bottom:10%; left:10%;';
|
233 |
+
break;
|
234 |
+
case 'ceter':
|
235 |
+
$placement = 'top:calc(50% - 34px); left:calc(50% - 34px);';
|
236 |
+
break;
|
237 |
+
case 'topright':
|
238 |
+
$placement = 'top:10%; right:10%;';
|
239 |
+
break;
|
240 |
+
case 'bottomright':
|
241 |
+
$placement = 'bottom:10%; right:10%;';
|
242 |
+
break;
|
243 |
+
}
|
244 |
+
$styles['post_format_thumb'] = '.cat-post-thumbnail span {position:relative}';
|
245 |
+
$styles['post_format_icon_styling'] = '.cat-post-format:before {font-family: "cat_post"; position:absolute; color:#FFFFFF; font-size:64px; line-height: 1; ' . $placement . '}';
|
246 |
+
|
247 |
+
$styles['post_format_icon_aside'] = ".cat-post-format-aside:before { content: '\\f0f6'; }";
|
248 |
+
$styles['post_format_icon_chat'] = ".cat-post-format-chat:before { content: '\\e802'; }";
|
249 |
+
$styles['post_format_icon_gallery'] = ".cat-post-format-gallery:before { content: '\\e805'; }";
|
250 |
+
$styles['post_format_icon_link'] = ".cat-post-format-link:before { content: '\\e809'; }";
|
251 |
+
$styles['post_format_icon_image'] = ".cat-post-format-image:before { content: '\\e800'; }";
|
252 |
+
$styles['post_format_icon_quote'] = ".cat-post-format-quote:before { content: '\\f10d'; }";
|
253 |
+
$styles['post_format_icon_status'] = ".cat-post-format-status:before { content: '\\e80a'; }";
|
254 |
+
$styles['post_format_icon_video'] = ".cat-post-format-video:before { content: '\\e801'; }";
|
255 |
+
$styles['post_format_icon_audio'] = ".cat-post-format-audio:before { content: '\\e803'; }";
|
256 |
+
|
257 |
+
}
|
258 |
+
}
|
259 |
+
|
260 |
+
foreach ( $styles as $key => $style ) {
|
261 |
+
$ret[ $key ] = '#' . $widget_id . ' ' . $style;
|
262 |
+
}
|
263 |
+
|
264 |
+
if ( $is_shortcode ) {
|
265 |
+
// Twenty Sixteen Theme adds underlines to links with box whadow wtf ...
|
266 |
+
$ret['twentysixteen_thumb'] = '#' . $widget_id . ' .cat-post-thumbnail {box-shadow:none}'; // this for the thumb link.
|
267 |
+
if ( ! ( isset( $settings['disable_font_styles'] ) && $settings['disable_font_styles'] ) ) { // checks if disable font styles is not set.
|
268 |
+
$ret['twentysixteen_tag_link'] = '#' . $widget_id . ' .cat-post-tax-tag a {box-shadow:none}'; // this for the tag link.
|
269 |
+
$ret['twentysixteen_tag_span'] = '#' . $widget_id . ' .cat-post-tax-tag span {box-shadow:none}'; // this for the tag link.
|
270 |
+
}
|
271 |
+
// Twenty Fifteen Theme adds border ...
|
272 |
+
$ret['twentyfifteen_thumb'] = '#' . $widget_id . ' .cat-post-thumbnail {border:0}'; // this for the thumb link.
|
273 |
+
if ( ! ( isset( $settings['disable_font_styles'] ) && $settings['disable_font_styles'] ) ) { // checks if disable font styles is not set.
|
274 |
+
$ret['twentysixteen_tag_link'] = '#' . $widget_id . ' .cat-post-tax-tag a {border:0}'; // this for the tag link.
|
275 |
+
$ret['twentysixteen_tag_span'] = '#' . $widget_id . ' .cat-post-tax-tag span {border:0}'; // this for the tag link.
|
276 |
+
}
|
277 |
+
}
|
278 |
+
|
279 |
+
// probably all Themes have too much margin on their p element when used in the shortcode or widget.
|
280 |
+
$ret['p_styling'] = '#' . $widget_id . ' p {margin:5px 0 0 0}'; // since on bottom it will make the spacing on cover
|
281 |
+
// bigger (add to the padding) use only top for now.
|
282 |
+
$ret['div_styling'] = '#' . $widget_id . ' li > div {margin:5px 0 0 0; clear:both;}'; // Add margin between the rows.
|
283 |
+
|
284 |
+
// use WP dashicons in the template (e.g. for premade Template 'All and icons').
|
285 |
+
$ret['dashicons'] = '#' . $widget_id . ' .dashicons {vertical-align:middle;}';
|
286 |
+
}
|
287 |
+
|
288 |
+
// Regardless if css is disabled we need some styling for the thumbnail
|
289 |
+
// to make sure cropping is properly done, and they fit the allocated space.
|
290 |
+
if ( isset( $settings['template'] ) && preg_match( '/%thumb%/', $settings['template'], $m, PREG_OFFSET_CAPTURE ) ) {
|
291 |
+
$wrap = isset( $settings['text_do_not_wrap_thumb'] ) && $settings['text_do_not_wrap_thumb'];
|
292 |
+
if ( isset( $settings['use_css_cropping'] ) && $settings['use_css_cropping'] ) {
|
293 |
+
if ( isset( $settings['thumb_w'] ) && $settings['thumb_w'] != 0 ) {
|
294 |
+
$ret['thumb_empty_w'] = '#' . $widget_id .' .cat-post-thumbnail .cat-post-crop img {width: '.$settings['thumb_w'].'px;}';
|
295 |
+
}
|
296 |
+
if ( isset( $settings['thumb_h'] ) && $settings['thumb_h'] != 0 ) {
|
297 |
+
$ret['thumb_crop_h'] = '#' . $widget_id . ' .cat-post-thumbnail .cat-post-crop img {height: '.$settings['thumb_h'].'px;}';
|
298 |
+
}
|
299 |
+
$ret['thumb_crop'] = '#' . $widget_id . ' .cat-post-thumbnail .cat-post-crop img {object-fit: cover;max-width:100%;}';
|
300 |
+
|
301 |
+
$ret['thumb_crop_not_supported'] = '#' . $widget_id .' .cat-post-thumbnail .cat-post-crop-not-supported img {width:100%;}';
|
302 |
+
|
303 |
+
if ( ! $wrap ) {
|
304 |
+
$ret['thumb_fluid_width'] = '#' . $widget_id . ' .cat-post-thumbnail {max-width:' . $settings['thumb_fluid_width'] . '%;}';
|
305 |
+
} else {
|
306 |
+
$ret['thumb_fluid_width'] = '#' . $widget_id . ' .cat-post-thumbnail {flex-basis:' . $settings['thumb_fluid_width'] . '%;}';
|
307 |
+
}
|
308 |
+
} else {
|
309 |
+
$ret['thumb_overflow'] = '#' . $widget_id . ' .cat-post-thumbnail span {overflow: hidden; display:inline-block}';
|
310 |
+
}
|
311 |
+
$ret['thumb_styling'] = '#' . $widget_id . ' .cat-post-item img {margin: initial;}';
|
312 |
+
|
313 |
+
// Thumbnail related positioning rules.
|
314 |
+
if ( $wrap ) {
|
315 |
+
$ret['thumb_flex'] = '#' . $widget_id . ' .cat-post-do-not-wrap-thumbnail {display:flex;}'; // Thumbnail container should flex.
|
316 |
+
$ret['thumb_flex_length'] = '#' . $widget_id . ' .cat-post-do-not-wrap-thumbnail > div {-webkit-flex: 1; -ms-flex: 1; flex: 1;}'; // Thumbnail container should flex.
|
317 |
+
}
|
318 |
+
$ret['text_do_not_wrap_thumb'] = '#' . $widget_id . ' .cat-post-thumbnail {float:left;}';
|
319 |
+
}
|
320 |
+
|
321 |
+
// Some hover effect require css to work, add it even if CSS is disabled.
|
322 |
+
if ( isset( $settings['thumb_hover'] ) ) {
|
323 |
+
switch ( $settings['thumb_hover'] ) {
|
324 |
+
case 'white':
|
325 |
+
$ret['white_hover_background'] = '#' . $widget_id . ' .cat-post-white span {background-color: white;}';
|
326 |
+
$ret['white_hover_thumb'] = '#' . $widget_id . ' .cat-post-white img {padding-bottom: 0 !important; -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease;}';
|
327 |
+
$ret['white_hover_transform'] = '#' . $widget_id . ' .cat-post-white:hover img {opacity: 0.8;}';
|
328 |
+
break;
|
329 |
+
case 'dark':
|
330 |
+
$ret['dark_hover_thumb'] = '#' . $widget_id . ' .cat-post-dark img {padding-bottom: 0 !important; -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease;}';
|
331 |
+
$ret['dark_hover_transform'] = '#' . $widget_id . ' .cat-post-dark:hover img {-webkit-filter: brightness(75%); -moz-filter: brightness(75%); -ms-filter: brightness(75%); -o-filter: brightness(75%); filter: brightness(75%);}';
|
332 |
+
break;
|
333 |
+
case 'scale':
|
334 |
+
$ret['scale_hover_thumb'] = '#' . $widget_id . ' .cat-post-scale img {margin: initial; padding-bottom: 0 !important; -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease;}';
|
335 |
+
$ret['scale_hover_transform'] = '#' . $widget_id . ' .cat-post-scale:hover img {-webkit-transform: scale(1.1, 1.1); -ms-transform: scale(1.1, 1.1); transform: scale(1.1, 1.1);}';
|
336 |
+
break;
|
337 |
+
case 'blur':
|
338 |
+
$ret['blur_hover_thumb'] = '#' . $widget_id . ' .cat-post-blur img {padding-bottom: 0 !important; -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease;}';
|
339 |
+
$ret['blur_hover_transform'] = '#' . $widget_id . ' .cat-post-blur:hover img {-webkit-filter: blur(2px); -moz-filter: blur(2px); -o-filter: blur(2px); -ms-filter: blur(2px); filter: blur(2px);}';
|
340 |
+
break;
|
341 |
+
case 'icon':
|
342 |
+
$fonturl = esc_url( plugins_url( 'icons/font', __FILE__ ) );
|
343 |
+
$ret['icon_hover_font'] = "@font-face {\n" .
|
344 |
+
"font-family: 'cat_post';\n" .
|
345 |
+
"src: url('$fonturl/cat_post.eot?58348147');\n" .
|
346 |
+
"src: url('$fonturl/cat_post.eot?58348147#iefix') format('embedded-opentype'),\n" .
|
347 |
+
" url('$fonturl/cat_post.woff2?58348147') format('woff2'),\n" .
|
348 |
+
" url('$fonturl/cat_post.woff?58348147') format('woff'),\n" .
|
349 |
+
" url('$fonturl/cat_post.ttf?58348147') format('truetype');\n" .
|
350 |
+
" font-weight: normal;\n" .
|
351 |
+
" font-style: normal;\n" .
|
352 |
+
"}\n";
|
353 |
+
|
354 |
+
$ret['icon_hover_thumb'] = '#' . $widget_id . ' .cat-post-format-standard:before {opacity:0; -webkit-transition: all 0.3s ease; -moz-transition: all 0.3s ease; -ms-transition: all 0.3s ease; -o-transition: all 0.3s ease; transition: all 0.3s ease;}';
|
355 |
+
$ret['icon_hover_transform'] = '#' . $widget_id . ' .cat-post-thumbnail:hover .cat-post-format-standard:before {opacity:1;}';
|
356 |
+
if ( isset( $settings['show_post_format'] ) && ( 'none' === $settings['show_post_format'] ) ) {
|
357 |
+
$ret[] = '#' . $widget_id . ' .cat-post-thumbnail {position:relative}';
|
358 |
+
$ret[] = '#' . $widget_id . ' .cat-post-icon .cat-post-format:before {font-family: "cat_post"; position:absolute; color:#FFFFFF; font-size:64px; line-height: 1; ' .
|
359 |
+
'top:calc(50% - 34px); left:calc(50% - 34px);}';
|
360 |
+
}
|
361 |
+
$ret[] = '#' . $widget_id . " .cat-post-format-standard:before {padding-left:12px; content: '\\e806'; }";
|
362 |
+
break;
|
363 |
+
}
|
364 |
+
|
365 |
+
if ( $settings['enable_loadmore'] ) {
|
366 |
+
// $this->id is ued over $widget_id because we need the id of the outer div, not the UL itself.
|
367 |
+
$ret['loadmore'] = '#' . $this->id . ' .' . __NAMESPACE__ . '-loadmore {text-align:center;margin-top:10px}';
|
368 |
+
}
|
369 |
+
}
|
370 |
+
$rules[] = $ret;
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* Output the widget CSS
|
375 |
+
*
|
376 |
+
* Just a wrapper that output getCSSRules
|
377 |
+
*
|
378 |
+
* @param bool $is_shortcode Indicates if we are in the context os a shortcode.
|
379 |
+
*
|
380 |
+
* @since 4.7
|
381 |
+
*/
|
382 |
+
public function outputCSS( $is_shortcode ) {
|
383 |
+
$rules = array();
|
384 |
+
getCSSRules( $is_shortcode, $rules );
|
385 |
+
foreach ( $rules as $rule ) {
|
386 |
+
echo "$rule\n"; // Xss off - raw css can not be html escaped.
|
387 |
+
}
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Get the id the virtual widget was registered with
|
392 |
+
*
|
393 |
+
* @return string
|
394 |
+
*
|
395 |
+
* @since 4.7
|
396 |
+
*/
|
397 |
+
public function id() {
|
398 |
+
return $this->id;
|
399 |
+
}
|
400 |
+
|
401 |
+
/**
|
402 |
+
* Get all the setting of the virtual widgets in an array
|
403 |
+
*
|
404 |
+
* @return array
|
405 |
+
*
|
406 |
+
* @since 4.7
|
407 |
+
*/
|
408 |
+
public static function getAllSettings() {
|
409 |
+
return self::$collection;
|
410 |
+
}
|
411 |
+
|
412 |
+
}
|
class-virtual-widgets-repository.php
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Implementation of virtual widget repository.
|
4 |
+
*
|
5 |
+
* @package categoryposts.
|
6 |
+
*
|
7 |
+
* @since 4.7
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace categoryPosts;
|
11 |
+
|
12 |
+
// Don't call the file directly.
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Class that implement a simple repository for the virtual widgets representing
|
19 |
+
* actuall shortcode and widgets
|
20 |
+
*
|
21 |
+
* @since 4.7
|
22 |
+
*/
|
23 |
+
class Virtual_Widgets_Repository {
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Collection of objects representing shortcodes.
|
27 |
+
*
|
28 |
+
* @var array
|
29 |
+
*
|
30 |
+
* @since 4.7
|
31 |
+
*/
|
32 |
+
private static $shortcodeCollection = array();
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Collection of objects representing widgets.
|
36 |
+
*
|
37 |
+
* @var array
|
38 |
+
*
|
39 |
+
* @since 4.7
|
40 |
+
*/
|
41 |
+
private static $widgetCollection = array();
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Add a virtual widget representing a shortcode to the repository
|
45 |
+
*
|
46 |
+
* @param string $index A name to identify the specific shortcode.
|
47 |
+
* @param Virtual_Widget $widget The virtual widget for it.
|
48 |
+
*
|
49 |
+
* @since 4.7
|
50 |
+
*/
|
51 |
+
public function addShortcode( $index, $widget ) {
|
52 |
+
self::$shortcodeCollection[ $index ] = $widget;
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Get all the virtual widgets representing actual shortcodes
|
57 |
+
*
|
58 |
+
* @return array
|
59 |
+
*
|
60 |
+
* @since 4.7
|
61 |
+
*/
|
62 |
+
public function getShortcodes() {
|
63 |
+
return self::$shortcodeCollection;
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Add a virtual widget representing awidget to the repository
|
68 |
+
*
|
69 |
+
* @param string $index A name to identify the specific widget.
|
70 |
+
* @param Virtual_Widget $widget The virstual widget for it.
|
71 |
+
*
|
72 |
+
* @since 4.7
|
73 |
+
*/
|
74 |
+
public function addWidget( $index, $widget ) {
|
75 |
+
self::$widgetCollection[ $index ] = $widget;
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Get all the virtual widgets representing actual widgets
|
80 |
+
*
|
81 |
+
* @return array
|
82 |
+
*
|
83 |
+
* @since 4.7
|
84 |
+
*/
|
85 |
+
public function getWidgets() {
|
86 |
+
return self::$widgetCollection;
|
87 |
+
}
|
88 |
+
|
89 |
+
}
|
class-widget.php
ADDED
@@ -0,0 +1,1685 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Implementation of the widget class.
|
4 |
+
*
|
5 |
+
* @package categoryposts.
|
6 |
+
*
|
7 |
+
* @since 4.7
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace categoryPosts;
|
11 |
+
|
12 |
+
// Don't call the file directly.
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Category Posts Widget Class
|
19 |
+
*
|
20 |
+
* Shows the single category posts with some configurable options
|
21 |
+
*/
|
22 |
+
class Widget extends \WP_Widget {
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Widget constructor.
|
26 |
+
*/
|
27 |
+
public function __construct() {
|
28 |
+
$widget_ops = array(
|
29 |
+
'classname' => 'cat-post-widget',
|
30 |
+
'description' => __( 'List single category posts', 'category-posts' ),
|
31 |
+
);
|
32 |
+
parent::__construct( WIDGET_BASE_ID, __( 'Category Posts', 'category-posts' ), $widget_ops );
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Calculate the HTML for showing the thumb of a post item.
|
37 |
+
*
|
38 |
+
* Used as a filter for the thumb wordpress API to add css based stretching and cropping
|
39 |
+
* when the image is not at the requested dimensions
|
40 |
+
*
|
41 |
+
* @param string $html The original HTML generated by the core APIS.
|
42 |
+
* @param int $post_id the ID of the post of which the thumb is a featured image.
|
43 |
+
* @param int $post_thumbnail_id The id of the featured image attachment.
|
44 |
+
* @param string|array $size The requested size identified by name or (width, height) array.
|
45 |
+
* @param mixed $attr ignored in this context.
|
46 |
+
* @return string The HTML for the thumb related to the post
|
47 |
+
*
|
48 |
+
* @since 4.1
|
49 |
+
*/
|
50 |
+
public function post_thumbnail_html( $html, $post_id, $post_thumbnail_id, $size, $attr ) {
|
51 |
+
|
52 |
+
$use_css_cropping = isset( $this->instance['use_css_cropping'] ) && $this->instance['use_css_cropping'];
|
53 |
+
$thumb = isset( $this->instance['template'] ) && preg_match( '/%thumb%/', $this->instance['template'] );
|
54 |
+
|
55 |
+
if ( ! ( $use_css_cropping && $thumb ) ) {
|
56 |
+
return $html;
|
57 |
+
}
|
58 |
+
$meta = image_get_intermediate_size( $post_thumbnail_id, $size );
|
59 |
+
|
60 |
+
if ( empty( $meta ) ) {
|
61 |
+
$post_img = wp_get_attachment_metadata( $post_thumbnail_id, $size );
|
62 |
+
$meta['file'] = basename( $post_img['file'] );
|
63 |
+
}
|
64 |
+
|
65 |
+
$origfile = get_attached_file( $post_thumbnail_id, true ); // the location of the full file.
|
66 |
+
$file = dirname( $origfile ) . '/' . $meta['file']; // the location of the file displayed as thumb.
|
67 |
+
if ( file_exists( $file ) ) {
|
68 |
+
list( $width, $height ) = getimagesize( $file ); // get actual size of the thumb file.
|
69 |
+
|
70 |
+
if ( isset( $this->instance['use_css_cropping'] ) && $this->instance['use_css_cropping'] ) {
|
71 |
+
$show_post_format = isset( $this->instance['show_post_format'] ) && ( 'none' !== $this->instance['show_post_format'] );
|
72 |
+
if ( $show_post_format || $this->instance['thumb_hover'] ) {
|
73 |
+
$format = get_post_format() ? : 'standard';
|
74 |
+
$post_format_class = 'cat-post-format cat-post-format-' . $format;
|
75 |
+
}
|
76 |
+
$html = '<figure class="cat-post-crop">' . $html . '</figure>';
|
77 |
+
} else {
|
78 |
+
// use_css_cropping is not used.
|
79 |
+
// wrap span.
|
80 |
+
$html = '<span>' . $html . '</span>';
|
81 |
+
}
|
82 |
+
}
|
83 |
+
return $html;
|
84 |
+
}
|
85 |
+
|
86 |
+
/*
|
87 |
+
* wrapper to execute the the_post_thumbnail with filters.
|
88 |
+
*/
|
89 |
+
/**
|
90 |
+
* Calculate the HTML for showing the thumb of a post item.
|
91 |
+
*
|
92 |
+
* It is a wrapper to execute the the_post_thumbnail with filters
|
93 |
+
*
|
94 |
+
* @param string|array $size The requested size identified by name or (width, height) array.
|
95 |
+
*
|
96 |
+
* @return string The HTML for the thumb related to the post and empty string if it can not be calculated
|
97 |
+
*
|
98 |
+
* @since 4.1
|
99 |
+
*/
|
100 |
+
public function the_post_thumbnail( $size = 'post-thumbnail' ) {
|
101 |
+
if ( empty( $size ) ) { // if junk value, make it a normal thumb.
|
102 |
+
$size = 'post-thumbnail';
|
103 |
+
} elseif ( is_array( $size ) && ( 2 === count( $size ) ) ) { // good format at least.
|
104 |
+
// normalize to ints first.
|
105 |
+
$size[0] = (int) $size[0];
|
106 |
+
$size[1] = (int) $size[1];
|
107 |
+
if ( ( 0 === $size[0] ) && ( 0 === $size[1] ) ) { // Both values zero then revert to thumbnail.
|
108 |
+
$size = array( get_option( 'thumbnail_size_w', 150 ), get_option( 'thumbnail_size_h', 150 ) );
|
109 |
+
} elseif ( ( 0 === $size[0] ) && ( 0 !== $size[1] ) ) {
|
110 |
+
// if thumb width 0 set to max/full widths for wp rendering
|
111 |
+
$post_thumb = get_the_post_thumbnail( get_the_ID(), 'full' );
|
112 |
+
preg_match( '/(?<=width=")[\d]*/', $post_thumb, $thumb_full_w );
|
113 |
+
$size[0] = $thumb_full_w[0];
|
114 |
+
} elseif ( ( 0 !== $size[0] ) && ( 0 === $size[1] ) ) {
|
115 |
+
// if thumb height 0 get full thumb for ratio and calc height with ratio
|
116 |
+
$post_thumb = get_the_post_thumbnail( get_the_ID(), 'full' );
|
117 |
+
preg_match( '/(?<=width=")[\d]*/', $post_thumb, $thumb_full_w );
|
118 |
+
preg_match( '/(?<=height=")[\d]*/', $post_thumb, $thumb_full_h );
|
119 |
+
$ratio = $thumb_full_w[0] / $thumb_full_h[0];
|
120 |
+
$size[1] = intval( $size[0] * $ratio );
|
121 |
+
}
|
122 |
+
} else {
|
123 |
+
$size = array( get_option( 'thumbnail_size_w', 150 ), get_option( 'thumbnail_size_h', 150 ) ); // yet another form of junk.
|
124 |
+
}
|
125 |
+
|
126 |
+
$post_thumbnail_id = get_post_thumbnail_id( get_the_ID() );
|
127 |
+
if ( ! $post_thumbnail_id && $this->instance['default_thunmbnail'] ) {
|
128 |
+
$post_thumbnail_id = $this->instance['default_thunmbnail'];
|
129 |
+
}
|
130 |
+
|
131 |
+
do_action( 'begin_fetch_post_thumbnail_html', get_the_ID(), $post_thumbnail_id, $size );
|
132 |
+
$html = wp_get_attachment_image( $post_thumbnail_id, $size, false, '' );
|
133 |
+
if ( ! $html ) {
|
134 |
+
$ret = '';
|
135 |
+
} else {
|
136 |
+
$ret = $this->post_thumbnail_html( $html, get_the_ID(), $post_thumbnail_id, $size, '' );
|
137 |
+
}
|
138 |
+
do_action( 'end_fetch_post_thumbnail_html', get_the_ID(), $post_thumbnail_id, $size );
|
139 |
+
|
140 |
+
return $ret;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Excerpt more link filter
|
145 |
+
*
|
146 |
+
* @param string $more The "more" text passed by the filter.
|
147 |
+
*
|
148 |
+
* @return string The link to the post with the "more" text configured in the widget.
|
149 |
+
*/
|
150 |
+
public function excerpt_more_filter( $more ) {
|
151 |
+
return ' <a class="cat-post-excerpt-more more-link" href="' . get_permalink() . '">' . esc_html( $this->instance['excerpt_more_text'] ) . '</a>';
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Apply the_content filter for excerpt
|
156 |
+
* This should show sharing buttons which comes with other widgets in the widget output in the same way as on the main content
|
157 |
+
*
|
158 |
+
* @param string $text The HTML with other applied excerpt filters.
|
159 |
+
*
|
160 |
+
* @return string If option hide_social_buttons is unchecked applay the_content filter.
|
161 |
+
*
|
162 |
+
* @since 4.6
|
163 |
+
*/
|
164 |
+
public function apply_the_excerpt( $text ) {
|
165 |
+
$ret = apply_filters( 'the_content', $text );
|
166 |
+
|
167 |
+
return $ret;
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Calculate the wp-query arguments matching the filter settings of the widget
|
172 |
+
*
|
173 |
+
* @param array $instance Array which contains the various settings.
|
174 |
+
* @return array The array that can be fed to wp_Query to get the relevant posts
|
175 |
+
*
|
176 |
+
* @since 4.6
|
177 |
+
*/
|
178 |
+
public function queryArgs( $instance ) {
|
179 |
+
|
180 |
+
$valid_sort_orders = array( 'date', 'title', 'comment_count', 'rand' );
|
181 |
+
if ( isset( $instance['sort_by'] ) && in_array( $instance['sort_by'], $valid_sort_orders, true ) ) {
|
182 |
+
$sort_by = $instance['sort_by'];
|
183 |
+
} else {
|
184 |
+
$sort_by = 'date';
|
185 |
+
}
|
186 |
+
$sort_order = ( isset( $instance['asc_sort_order'] ) && $instance['asc_sort_order'] ) ? 'ASC' : 'DESC';
|
187 |
+
|
188 |
+
// Get array of post info.
|
189 |
+
$args = array(
|
190 |
+
'orderby' => $sort_by,
|
191 |
+
'order' => $sort_order,
|
192 |
+
'ignore_sticky_posts' => 1, // Make sure we do not get stickies out of order.
|
193 |
+
'no_found_rows' => true, // Do not count the total numbers of rows by default.
|
194 |
+
);
|
195 |
+
|
196 |
+
$non_default_valid_status = array(
|
197 |
+
'publish',
|
198 |
+
'future',
|
199 |
+
'publish,future',
|
200 |
+
'private',
|
201 |
+
'private,publish',
|
202 |
+
'private,publish,future',
|
203 |
+
);
|
204 |
+
if ( isset( $instance['status'] ) && in_array( $instance['status'], $non_default_valid_status, true ) ) {
|
205 |
+
$args['post_status'] = $instance['status'];
|
206 |
+
}
|
207 |
+
|
208 |
+
if ( isset( $instance['num'] ) ) {
|
209 |
+
$args['showposts'] = (int) $instance['num'];
|
210 |
+
}
|
211 |
+
|
212 |
+
if ( isset( $instance['offset'] ) && ( (int) $instance['offset'] > 1 ) ) {
|
213 |
+
$args['offset'] = (int) $instance['offset'] - 1;
|
214 |
+
}
|
215 |
+
if ( isset( $instance['cat'] ) ) {
|
216 |
+
if ( isset( $instance['no_cat_childs'] ) && $instance['no_cat_childs'] ) {
|
217 |
+
$args['category__in'] = (int) $instance['cat'];
|
218 |
+
} else {
|
219 |
+
$args['cat'] = (int) $instance['cat'];
|
220 |
+
}
|
221 |
+
}
|
222 |
+
|
223 |
+
if ( is_singular() && isset( $instance['exclude_current_post'] ) && $instance['exclude_current_post'] ) {
|
224 |
+
$args['post__not_in'] = array( get_the_ID() );
|
225 |
+
}
|
226 |
+
|
227 |
+
if ( isset( $instance['hideNoThumb'] ) && $instance['hideNoThumb'] ) {
|
228 |
+
$args = array_merge( $args, array(
|
229 |
+
'meta_query' => array(
|
230 |
+
array(
|
231 |
+
'key' => '_thumbnail_id',
|
232 |
+
'compare' => 'EXISTS',
|
233 |
+
),
|
234 |
+
),
|
235 |
+
) );
|
236 |
+
}
|
237 |
+
|
238 |
+
switch ( $instance['date_range'] ) {
|
239 |
+
case 'days_ago':
|
240 |
+
$ago = (int) $instance['days_ago'];
|
241 |
+
|
242 |
+
// If there is no valid integer value given, bail.
|
243 |
+
if ( 0 === $ago ) {
|
244 |
+
break;
|
245 |
+
}
|
246 |
+
|
247 |
+
$date = date( 'Y-m-d', strtotime( '-' . $ago . ' days' ) );
|
248 |
+
$args['date_query'] = array(
|
249 |
+
'after' => $date,
|
250 |
+
'inclusive' => true,
|
251 |
+
);
|
252 |
+
break;
|
253 |
+
case 'between_dates':
|
254 |
+
// Validation note - not doing any, assuming the query will
|
255 |
+
// fail gracefully enough for now as it is not clear what Should
|
256 |
+
// the validation be right now.
|
257 |
+
$start_date = $instance['start_date'];
|
258 |
+
$end_date = $instance['end_date'];
|
259 |
+
$args['date_query'] = array(
|
260 |
+
'after' => $start_date,
|
261 |
+
'before' => $end_date,
|
262 |
+
'inclusive' => true,
|
263 |
+
);
|
264 |
+
break;
|
265 |
+
}
|
266 |
+
|
267 |
+
return $args;
|
268 |
+
}
|
269 |
+
|
270 |
+
/**
|
271 |
+
* Calculate the HTML of the title based on the widget settings
|
272 |
+
*
|
273 |
+
* @param string $before_title The sidebar configured HTML that should come
|
274 |
+
* before the title itself.
|
275 |
+
* @param string $after_title The sidebar configured HTML that should come
|
276 |
+
* after the title itself.
|
277 |
+
* @param array $instance Array which contains the various settings.
|
278 |
+
* @return string The HTML for the title area
|
279 |
+
*
|
280 |
+
* @since 4.6
|
281 |
+
*/
|
282 |
+
public function titleHTML( $before_title, $after_title, $instance ) {
|
283 |
+
$ret = '';
|
284 |
+
|
285 |
+
// If no title, use the name of the category.
|
286 |
+
if ( ! isset( $instance['title'] ) || ! $instance['title'] ) {
|
287 |
+
$instance['title'] = '';
|
288 |
+
if ( 0 !== (int) $instance['cat'] ) {
|
289 |
+
$category_info = get_category( $instance['cat'] );
|
290 |
+
if ( $category_info && ! is_wp_error( $category_info ) ) {
|
291 |
+
$instance['title'] = $category_info->name;
|
292 |
+
} else {
|
293 |
+
$instance['cat'] = 0; // For further processing treat it like "all categories".
|
294 |
+
$instance['title'] = __( 'Recent Posts', 'category-posts' );
|
295 |
+
}
|
296 |
+
} else {
|
297 |
+
$instance['title'] = __( 'Recent Posts', 'category-posts' );
|
298 |
+
}
|
299 |
+
}
|
300 |
+
|
301 |
+
if ( ! ( isset( $instance['hide_title'] ) && $instance['hide_title'] ) ) {
|
302 |
+
$ret = $before_title;
|
303 |
+
if ( isset( $instance['is_shortcode'] ) ) {
|
304 |
+
$title = esc_html( $instance['title'] );
|
305 |
+
} else {
|
306 |
+
$title = apply_filters( 'widget_title', $instance['title'] );
|
307 |
+
}
|
308 |
+
|
309 |
+
if ( isset( $instance['title_link'] ) && $instance['title_link'] ) {
|
310 |
+
if ( 0 !== $instance['cat'] ) {
|
311 |
+
$ret .= '<a href="' . get_category_link( $instance['cat'] ) . '">' . $title . '</a>';
|
312 |
+
} elseif ( isset( $instance['title_link_url'] ) && $instance['title_link_url'] ) {
|
313 |
+
$ret .= '<a href="' . esc_url( $instance['title_link_url'] ) . '">' . $title . '</a>';
|
314 |
+
} else {
|
315 |
+
$ret .= '<a href="' . esc_url( $this->blog_page_url() ) . '">' . $title . '</a>';
|
316 |
+
}
|
317 |
+
} else {
|
318 |
+
$ret .= $title;
|
319 |
+
}
|
320 |
+
|
321 |
+
$ret .= $after_title;
|
322 |
+
}
|
323 |
+
|
324 |
+
return $ret;
|
325 |
+
}
|
326 |
+
|
327 |
+
/**
|
328 |
+
* Get the URL of the blog page or home page if no explicit blog page is defined.
|
329 |
+
*
|
330 |
+
* @return string The URL of the blog page
|
331 |
+
*
|
332 |
+
* @since 4.8
|
333 |
+
*/
|
334 |
+
private function blog_page_url() {
|
335 |
+
|
336 |
+
$blog_page = get_option( 'page_for_posts' );
|
337 |
+
if ( $blog_page ) {
|
338 |
+
$url = get_permalink( $blog_page );
|
339 |
+
} else {
|
340 |
+
$url = home_url();
|
341 |
+
}
|
342 |
+
|
343 |
+
return $url;
|
344 |
+
}
|
345 |
+
|
346 |
+
/**
|
347 |
+
* Calculate the HTML of the load more button based on the widget settings
|
348 |
+
*
|
349 |
+
* @param array $instance Array which contains the various settings.
|
350 |
+
*
|
351 |
+
* @return string The HTML for the load more area
|
352 |
+
*
|
353 |
+
* @since 4.9
|
354 |
+
*/
|
355 |
+
public function loadMoreHTML( $instance ) {
|
356 |
+
|
357 |
+
if ( ! $instance['enable_loadmore'] ) {
|
358 |
+
return '';
|
359 |
+
}
|
360 |
+
|
361 |
+
$ret = '<div class="' . __NAMESPACE__ . '-loadmore">';
|
362 |
+
$context = 0;
|
363 |
+
if ( is_singular() ) {
|
364 |
+
$context = get_the_ID();
|
365 |
+
}
|
366 |
+
|
367 |
+
add_action( 'wp_footer', __NAMESPACE__ . '\embed_loadmore_scripts' );
|
368 |
+
|
369 |
+
// We rely on the widget number to be properly set.
|
370 |
+
// but need a slight different handling for proper widgets.
|
371 |
+
if ( is_int( $this->number ) ) {
|
372 |
+
// it is a proper widget, add the prefix.
|
373 |
+
$id = 'widget-' . $this->number;
|
374 |
+
} else {
|
375 |
+
$id = str_replace( WIDGET_BASE_ID . '-', '', $this->number );
|
376 |
+
}
|
377 |
+
|
378 |
+
$number = $instance['num'];
|
379 |
+
$start = $instance['offset'] + $number;
|
380 |
+
$loading = $instance['loading_text'];
|
381 |
+
|
382 |
+
$ret .= '<button type="button" data-loading="' . esc_attr( $loading ) . '" data-id="' . esc_attr( $id ) . '" data-start="' . esc_attr( $start ) . '" data-context="' . esc_attr( $context ) . '" data-number="' . esc_attr( $number ) . '">' . esc_html( $instance['loadmore_text'] ) . '</button>';
|
383 |
+
$ret .= '</div>';
|
384 |
+
return $ret;
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Calculate the HTML of the footer based on the widget settings
|
389 |
+
*
|
390 |
+
* @param array $instance Array which contains the various settings.
|
391 |
+
* @return string The HTML for the footer area
|
392 |
+
*
|
393 |
+
* @since 4.6
|
394 |
+
*/
|
395 |
+
public function footerHTML( $instance ) {
|
396 |
+
|
397 |
+
$ret = '';
|
398 |
+
$url = '';
|
399 |
+
$text = '';
|
400 |
+
|
401 |
+
if ( isset( $instance['footer_link'] ) ) {
|
402 |
+
$url = $instance['footer_link'];
|
403 |
+
}
|
404 |
+
|
405 |
+
if ( isset( $instance['footer_link_text'] ) ) {
|
406 |
+
$text = $instance['footer_link_text'];
|
407 |
+
}
|
408 |
+
|
409 |
+
// if url is set, but no text, just use the url as text.
|
410 |
+
if ( empty( $text ) && ! empty( $url ) ) {
|
411 |
+
$text = $url;
|
412 |
+
}
|
413 |
+
|
414 |
+
// if no url is set but just text, assume the url should be to the relevant archive page
|
415 |
+
// category archive for categories filter and home page or blog page when "all categories"
|
416 |
+
// is used.
|
417 |
+
if ( ! empty( $text ) && empty( $url ) ) {
|
418 |
+
if ( isset( $instance['cat'] ) && ( 0 !== $instance['cat'] ) && ( null !== get_category( $instance['cat'] ) ) ) {
|
419 |
+
$url = get_category_link( $instance['cat'] );
|
420 |
+
} else {
|
421 |
+
$url = $this->blog_page_url();
|
422 |
+
}
|
423 |
+
}
|
424 |
+
|
425 |
+
if ( ! empty( $url ) ) {
|
426 |
+
$ret .= '<a class="cat-post-footer-link" href="' . esc_url( $url ) . '">' . esc_html( $text ) . '</a>';
|
427 |
+
}
|
428 |
+
|
429 |
+
return $ret;
|
430 |
+
}
|
431 |
+
|
432 |
+
/**
|
433 |
+
* Current post item date string based on the format requested in the settings
|
434 |
+
*
|
435 |
+
* @param array $instance Array which contains the various settings.
|
436 |
+
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
437 |
+
*
|
438 |
+
* @since 4.8
|
439 |
+
*/
|
440 |
+
public function itemDate( $instance, $everything_is_link ) {
|
441 |
+
$ret = '';
|
442 |
+
|
443 |
+
if ( ! isset( $instance['preset_date_format'] ) ) {
|
444 |
+
$preset_date_format = 'other';
|
445 |
+
} else {
|
446 |
+
$preset_date_format = $instance['preset_date_format'];
|
447 |
+
}
|
448 |
+
|
449 |
+
$attr = '';
|
450 |
+
switch ( $preset_date_format ) {
|
451 |
+
case 'sitedateandtime':
|
452 |
+
$date = get_the_time( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) );
|
453 |
+
break;
|
454 |
+
case 'localsitedateandtime':
|
455 |
+
$date = get_the_time( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ) ) . ' GMT';
|
456 |
+
$time = get_post_time( 'U', true );
|
457 |
+
$attr = ' data-publishtime="' . $time . '" data-format="time"';
|
458 |
+
add_action( 'wp_footer', __NAMESPACE__ . '\embed_date_scripts' );
|
459 |
+
break;
|
460 |
+
case 'sitedate':
|
461 |
+
$date = get_the_time( get_option( 'date_format' ) );
|
462 |
+
break;
|
463 |
+
case 'localsitedate':
|
464 |
+
$date = get_the_time( get_option( 'date_format' ) ) . ' GMT';
|
465 |
+
$time = get_post_time( 'U', true );
|
466 |
+
$attr = ' data-publishtime="' . $time . '" data-format="date"';
|
467 |
+
add_action( 'wp_footer', __NAMESPACE__ . '\embed_date_scripts' );
|
468 |
+
break;
|
469 |
+
case 'sincepublished':
|
470 |
+
$date = human_time_diff( get_the_time( 'U' ), current_time( 'timestamp' ) );
|
471 |
+
break;
|
472 |
+
default:
|
473 |
+
if ( isset( $instance['date_format'] ) && strlen( trim( $instance['date_format'] ) ) > 0 ) {
|
474 |
+
$date_format = $instance['date_format'];
|
475 |
+
} else {
|
476 |
+
$date_format = 'j M Y';
|
477 |
+
}
|
478 |
+
$date = get_the_time( $date_format );
|
479 |
+
break;
|
480 |
+
}
|
481 |
+
$ret .= '<span class="cat-post-date"' . $attr . '>';
|
482 |
+
if ( isset( $instance['date_link'] ) && $instance['date_link'] && ! $everything_is_link ) {
|
483 |
+
$ret .= '<a href="' . \get_the_permalink() . '">';
|
484 |
+
}
|
485 |
+
$ret .= $date;
|
486 |
+
|
487 |
+
if ( isset( $instance['date_link'] ) && $instance['date_link'] && ! $everything_is_link ) {
|
488 |
+
$ret .= '</a>';
|
489 |
+
}
|
490 |
+
$ret .= '</span>';
|
491 |
+
return $ret;
|
492 |
+
}
|
493 |
+
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Calculate the HTML for showing the thumb of a post item.
|
497 |
+
* Expected to be called from a loop with globals properly set.
|
498 |
+
*
|
499 |
+
* @param array $instance Array which contains the various settings.
|
500 |
+
* @param bool $no_link indicates whether the thumb should be wrapped in a link or a span.
|
501 |
+
* @return string The HTML for the thumb related to the post
|
502 |
+
*
|
503 |
+
* @since 4.6
|
504 |
+
*/
|
505 |
+
public function itemThumb( $instance, $no_link ) {
|
506 |
+
$ret = '';
|
507 |
+
|
508 |
+
if ( ( isset( $instance['default_thunmbnail'] ) && ( 0 !== $instance['default_thunmbnail'] ) ) || has_post_thumbnail() ) {
|
509 |
+
$class = '';
|
510 |
+
$disable_css = isset( $instance['disable_css'] ) && $instance['disable_css'];
|
511 |
+
|
512 |
+
if ( isset( $this->instance['thumb_hover'] ) && ! $disable_css ) {
|
513 |
+
$class = 'class="cat-post-thumbnail cat-post-' . $instance['thumb_hover'] . '"';
|
514 |
+
} else {
|
515 |
+
$class = 'class="cat-post-thumbnail"';
|
516 |
+
}
|
517 |
+
|
518 |
+
$title_args = array( 'echo' => false );
|
519 |
+
|
520 |
+
if ( $no_link ) {
|
521 |
+
$ret .= '<span ' . $class . '>';
|
522 |
+
} else {
|
523 |
+
$ret .= '<a ' . $class . ' href="' . get_the_permalink() . '" title="' . the_title_attribute( $title_args ) . '">';
|
524 |
+
}
|
525 |
+
|
526 |
+
$ret .= $this->the_post_thumbnail( array( $this->instance['thumb_w'], $this->instance['thumb_h'] ) );
|
527 |
+
|
528 |
+
if ( $no_link ) {
|
529 |
+
$ret .= '</span>';
|
530 |
+
} else {
|
531 |
+
$ret .= '</a>';
|
532 |
+
}
|
533 |
+
}
|
534 |
+
|
535 |
+
return $ret;
|
536 |
+
}
|
537 |
+
|
538 |
+
/**
|
539 |
+
* Current post item categories string
|
540 |
+
*
|
541 |
+
* @param array $instance Array which contains the various settings.
|
542 |
+
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
543 |
+
*
|
544 |
+
* @since 4.8
|
545 |
+
*/
|
546 |
+
public function itemCategories( $instance, $everything_is_link ) {
|
547 |
+
|
548 |
+
$ret = '<span class="cat-post-tax-category">';
|
549 |
+
$cat_ids = wp_get_post_categories( get_the_ID(), array( 'number' => 0 ) );
|
550 |
+
foreach ( $cat_ids as $cat_id ) {
|
551 |
+
if ( $everything_is_link ) {
|
552 |
+
$ret .= ' ' . get_cat_name( $cat_id );
|
553 |
+
} else {
|
554 |
+
$ret .= " <a href='" . get_category_link( $cat_id ) . "'>" . get_cat_name( $cat_id ) . '</a>';
|
555 |
+
}
|
556 |
+
}
|
557 |
+
$ret .= '</span>';
|
558 |
+
return $ret;
|
559 |
+
}
|
560 |
+
|
561 |
+
/**
|
562 |
+
* Current post item tags string
|
563 |
+
*
|
564 |
+
* @param array $instance Array which contains the various settings.
|
565 |
+
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
566 |
+
*
|
567 |
+
* @since 4.8
|
568 |
+
*/
|
569 |
+
public function itemTags( $instance, $everything_is_link ) {
|
570 |
+
|
571 |
+
$ret = '<span class="cat-post-tax-tag">';
|
572 |
+
$tag_ids = wp_get_post_tags( get_the_ID(), array( 'number' => 0 ) );
|
573 |
+
foreach ( $tag_ids as $tag_id ) {
|
574 |
+
if ( $everything_is_link ) {
|
575 |
+
$ret .= ' ' . $tag_id->name;
|
576 |
+
} else {
|
577 |
+
$ret .= " <a href='" . get_tag_link( $tag_id->term_id ) . "'>" . $tag_id->name . '</a>';
|
578 |
+
}
|
579 |
+
}
|
580 |
+
$ret .= '</span>';
|
581 |
+
return $ret;
|
582 |
+
}
|
583 |
+
|
584 |
+
/**
|
585 |
+
* Current post item comment number string
|
586 |
+
*
|
587 |
+
* @param array $instance Array which contains the various settings.
|
588 |
+
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
589 |
+
*
|
590 |
+
* @since 4.8
|
591 |
+
*/
|
592 |
+
public function itemCommentNum( $instance, $everything_is_link ) {
|
593 |
+
global $post;
|
594 |
+
|
595 |
+
$ret = '<span class="cat-post-comment-num">';
|
596 |
+
|
597 |
+
if ( $everything_is_link ) {
|
598 |
+
$ret .= '(' . \get_comments_number() . ')';
|
599 |
+
} else {
|
600 |
+
$link = sprintf(
|
601 |
+
'<a href="%1$s" title="%2$s">(%3$d)</a>',
|
602 |
+
esc_url( get_comments_link( $post->ID ) ),
|
603 |
+
esc_attr( sprintf( __( '(%d) comments to this post' ), get_comments_number() ) ),
|
604 |
+
get_comments_number()
|
605 |
+
);
|
606 |
+
$ret .= $link;
|
607 |
+
}
|
608 |
+
|
609 |
+
$ret .= '</span>';
|
610 |
+
return $ret;
|
611 |
+
}
|
612 |
+
|
613 |
+
/**
|
614 |
+
* Current post item author string
|
615 |
+
*
|
616 |
+
* @param array $instance Array which contains the various settings.
|
617 |
+
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
618 |
+
*
|
619 |
+
* @since 4.8
|
620 |
+
*/
|
621 |
+
public function itemAuthor( $instance, $everything_is_link ) {
|
622 |
+
|
623 |
+
$ret = '<span class="cat-post-author">';
|
624 |
+
|
625 |
+
if ( $everything_is_link ) {
|
626 |
+
$ret .= get_the_author();
|
627 |
+
} else {
|
628 |
+
$link = get_the_author_posts_link();
|
629 |
+
$ret .= $link;
|
630 |
+
}
|
631 |
+
$ret .= '</span>';
|
632 |
+
return $ret;
|
633 |
+
}
|
634 |
+
|
635 |
+
/**
|
636 |
+
* Current post item excerpt string
|
637 |
+
*
|
638 |
+
* @param array $instance Array which contains the various settings.
|
639 |
+
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
640 |
+
*
|
641 |
+
* @since 4.8
|
642 |
+
*/
|
643 |
+
public function itemExcerpt( $instance, $everything_is_link ) {
|
644 |
+
global $post;
|
645 |
+
|
646 |
+
// use the_excerpt filter to get the "normal" excerpt of the post
|
647 |
+
// then apply our filter to let users customize excerpts in their own way.
|
648 |
+
if ( isset( $instance['excerpt_length'] ) && ( $instance['excerpt_length'] > 0 ) ) {
|
649 |
+
$length = (int) $instance['excerpt_length'];
|
650 |
+
} else {
|
651 |
+
$length = 999; // Use the wordpress default.
|
652 |
+
}
|
653 |
+
|
654 |
+
if ( ! isset( $instance['excerpt_filters'] ) || $instance['excerpt_filters'] ) { // pre 4.7 widgets has filters on.
|
655 |
+
$excerpt = apply_filters( 'the_excerpt', \get_the_excerpt() );
|
656 |
+
} else { // if filters off replicate functionality of core generating excerpt.
|
657 |
+
$more_text = '[…]';
|
658 |
+
if ( isset( $instance['excerpt_more_text'] ) && $instance['excerpt_more_text'] ) {
|
659 |
+
$more_text = ltrim( $instance['excerpt_more_text'] );
|
660 |
+
}
|
661 |
+
|
662 |
+
if ( $everything_is_link ) {
|
663 |
+
$excerpt_more_text = ' <span class="cat-post-excerpt-more">' . $more_text . '</span>';
|
664 |
+
} else {
|
665 |
+
$excerpt_more_text = ' <a class="cat-post-excerpt-more" href="' . get_permalink() . '" title="' . sprintf( __( 'Continue reading %s' ), get_the_title() ) . '">' . $more_text . '</a>';
|
666 |
+
}
|
667 |
+
if ( '' === $post->post_excerpt ) {
|
668 |
+
$text = get_the_content( '' );
|
669 |
+
$text = strip_shortcodes( $text );
|
670 |
+
$excerpt = \wp_trim_words( $text, $length, $excerpt_more_text );
|
671 |
+
// adjust html output same way as for the normal excerpt,
|
672 |
+
// just force all functions depending on the_excerpt hook.
|
673 |
+
$excerpt = shortcode_unautop( wpautop( convert_chars( convert_smilies( wptexturize( $excerpt ) ) ) ) );
|
674 |
+
} else {
|
675 |
+
$text = $post->post_excerpt;
|
676 |
+
$excerpt = \wp_trim_words( $text, $length, $excerpt_more_text );
|
677 |
+
$excerpt = shortcode_unautop( wpautop( convert_chars( convert_smilies( wptexturize( $excerpt ) ) ) ) );
|
678 |
+
}
|
679 |
+
}
|
680 |
+
$ret = apply_filters( 'cpw_excerpt', $excerpt, $this );
|
681 |
+
return $ret;
|
682 |
+
}
|
683 |
+
|
684 |
+
/**
|
685 |
+
* Current post item title string
|
686 |
+
*
|
687 |
+
* @param array $instance Array which contains the various settings.
|
688 |
+
* @param bool $everything_is_link Indicates whether the return string should avoid links.
|
689 |
+
*
|
690 |
+
* @since 4.8
|
691 |
+
*/
|
692 |
+
public function itemTitle( $instance, $everything_is_link ) {
|
693 |
+
|
694 |
+
$ret = '';
|
695 |
+
|
696 |
+
if ( $everything_is_link ) {
|
697 |
+
$ret .= '<span class="cat-post-title">' . get_the_title() . '</span>';
|
698 |
+
} else {
|
699 |
+
$ret .= '<a class="cat-post-title"';
|
700 |
+
$ret .= ' href="' . get_the_permalink() . '" rel="bookmark">' . get_the_title();
|
701 |
+
$ret .= '</a>';
|
702 |
+
}
|
703 |
+
return $ret;
|
704 |
+
}
|
705 |
+
|
706 |
+
/**
|
707 |
+
* Calculate the HTML for a post item based on the widget settings and post.
|
708 |
+
* Expected to be called in an active loop with all the globals set.
|
709 |
+
*
|
710 |
+
* @param array $instance Array which contains the various settings.
|
711 |
+
* @param null|integer $current_post_id If on singular page specifies the id of
|
712 |
+
* the post, otherwise null.
|
713 |
+
* @return string The HTML for item related to the post
|
714 |
+
*
|
715 |
+
* @since 4.6
|
716 |
+
*/
|
717 |
+
public function itemHTML( $instance, $current_post_id ) {
|
718 |
+
global $post;
|
719 |
+
|
720 |
+
$everything_is_link = isset( $instance['everything_is_link'] ) && $instance['everything_is_link'];
|
721 |
+
$wrap = isset( $instance['text_do_not_wrap_thumb'] ) && $instance['text_do_not_wrap_thumb'];
|
722 |
+
|
723 |
+
$template = '';
|
724 |
+
if ( isset( $instance['template'] ) ) {
|
725 |
+
$template = $instance['template'];
|
726 |
+
} else {
|
727 |
+
$template = convert_settings_to_template( $instance );
|
728 |
+
}
|
729 |
+
$ret = '<li ';
|
730 |
+
|
731 |
+
// Current post.
|
732 |
+
if ( $current_post_id === $post->ID ) {
|
733 |
+
$ret .= "class='cat-post-item cat-post-current'";
|
734 |
+
} else {
|
735 |
+
$ret .= "class='cat-post-item'";
|
736 |
+
}
|
737 |
+
$ret .= '>'; // close the li opening tag.
|
738 |
+
|
739 |
+
if ( $everything_is_link ) {
|
740 |
+
$ret .= '<a class="cat-post-everything-is-link" href="' . get_the_permalink() . '" title="">';
|
741 |
+
}
|
742 |
+
|
743 |
+
// Try to do smart formatting for floating thumb based on its location.
|
744 |
+
if ( $wrap ) {
|
745 |
+
if ( preg_match( '#(\%thumb\%)#', $template ) && ! preg_match( '#(\%thumb\%$)#', $template ) ) {
|
746 |
+
$thumb_flex = explode( '%thumb%', $template );
|
747 |
+
if ( 1 === count( $thumb_flex ) ) {
|
748 |
+
$template = '<div class="cat-post-do-not-wrap-thumbnail">%thumb%<div>' . $thumb_flex[0] . '</div></div>';
|
749 |
+
}
|
750 |
+
if ( 2 === count( $thumb_flex ) ) {
|
751 |
+
$template = $thumb_flex[0] . '<div class="cat-post-do-not-wrap-thumbnail">%thumb%<div>' . $thumb_flex[1] . '</div></div>';
|
752 |
+
}
|
753 |
+
}
|
754 |
+
}
|
755 |
+
|
756 |
+
// Post details (Template).
|
757 |
+
$widget = $this;
|
758 |
+
$template_res = preg_replace_callback( get_template_regex(), function ( $matches ) use ( $widget, $instance, $everything_is_link ) {
|
759 |
+
switch ( $matches[0] ) {
|
760 |
+
case '%title%':
|
761 |
+
return $widget->itemTitle( $instance, $everything_is_link );
|
762 |
+
case '%author%':
|
763 |
+
return $widget->itemAuthor( $instance, $everything_is_link );
|
764 |
+
case '%commentnum%':
|
765 |
+
return $widget->itemCommentNum( $instance, $everything_is_link );
|
766 |
+
case '%date%':
|
767 |
+
return $widget->itemDate( $instance, $everything_is_link );
|
768 |
+
case '%thumb%':
|
769 |
+
return $widget->itemThumb( $instance, $everything_is_link );
|
770 |
+
case '%post_tag%':
|
771 |
+
return $widget->itemTags( $instance, $everything_is_link );
|
772 |
+
case '%category%':
|
773 |
+
return $widget->itemCategories( $instance, $everything_is_link );
|
774 |
+
case '%excerpt%':
|
775 |
+
return $widget->itemExcerpt( $instance, $everything_is_link );
|
776 |
+
default:
|
777 |
+
return $matches[0];
|
778 |
+
}
|
779 |
+
}, $template );
|
780 |
+
|
781 |
+
// Replace empty line with closing and opening DIV.
|
782 |
+
$template_res = trim( $template_res );
|
783 |
+
$template_res = str_replace( "\n\r", '</div><div>', $template_res ); // in widget areas.
|
784 |
+
$template_res = str_replace( "\n\n", '</div><div>', $template_res ); // as shortcode.
|
785 |
+
$template_res = '<div>' . $template_res . '</div>';
|
786 |
+
|
787 |
+
// replace new lines with spaces.
|
788 |
+
$template_res = str_replace( "\n\r", ' ', $template_res ); // in widget areas.
|
789 |
+
$template_res = str_replace( "\n\n", ' ', $template_res ); // as shortcode.
|
790 |
+
|
791 |
+
$ret .= $template_res;
|
792 |
+
|
793 |
+
if ( $everything_is_link ) {
|
794 |
+
$ret .= '</a>';
|
795 |
+
}
|
796 |
+
|
797 |
+
$ret .= '</li>';
|
798 |
+
return $ret;
|
799 |
+
}
|
800 |
+
|
801 |
+
/**
|
802 |
+
* Filter to set the number of words in an excerpt
|
803 |
+
*
|
804 |
+
* @param int $length The number of words as configured by wordpress core or set by previous filters.
|
805 |
+
* @return int The number of words configured for the widget,
|
806 |
+
* or the $length parameter if it is not configured or garbage value.
|
807 |
+
*
|
808 |
+
* @since 4.6
|
809 |
+
*/
|
810 |
+
public function excerpt_length_filter( $length ) {
|
811 |
+
if ( isset( $this->instance['excerpt_length'] ) && $this->instance['excerpt_length'] > 0 ) {
|
812 |
+
$length = $this->instance['excerpt_length'];
|
813 |
+
}
|
814 |
+
return $length;
|
815 |
+
}
|
816 |
+
|
817 |
+
/**
|
818 |
+
* Set the proper excerpt filters based on the settings
|
819 |
+
*
|
820 |
+
* @param array $instance widget settings.
|
821 |
+
* @return void
|
822 |
+
*
|
823 |
+
* @since 4.6
|
824 |
+
*/
|
825 |
+
public function setExcerpFilters( $instance ) {
|
826 |
+
|
827 |
+
if ( isset( $instance['excerpt'] ) && $instance['excerpt'] ) {
|
828 |
+
|
829 |
+
// Excerpt length filter.
|
830 |
+
if ( isset( $instance['excerpt_length'] ) && ( (int) $instance['excerpt_length'] ) > 0 ) {
|
831 |
+
add_filter( 'excerpt_length', array( $this, 'excerpt_length_filter' ) );
|
832 |
+
}
|
833 |
+
|
834 |
+
if ( isset( $instance['excerpt_more_text'] ) && ( '' !== ltrim( $instance['excerpt_more_text'] ) ) ) {
|
835 |
+
add_filter( 'excerpt_more', array( $this, 'excerpt_more_filter' ) );
|
836 |
+
}
|
837 |
+
|
838 |
+
add_filter( 'the_excerpt', array( $this, 'apply_the_excerpt' ) );
|
839 |
+
}
|
840 |
+
}
|
841 |
+
|
842 |
+
/**
|
843 |
+
* Remove the excerpt filter
|
844 |
+
*
|
845 |
+
* @param array $instance widget settings.
|
846 |
+
* @return void
|
847 |
+
*
|
848 |
+
* @since 4.6
|
849 |
+
*/
|
850 |
+
public function removeExcerpFilters( $instance ) {
|
851 |
+
remove_filter( 'excerpt_length', array( $this, 'excerpt_length_filter' ) );
|
852 |
+
remove_filter( 'excerpt_more', array( $this, 'excerpt_more_filter' ) );
|
853 |
+
add_filter( 'get_the_excerpt', 'wp_trim_excerpt' );
|
854 |
+
remove_filter( 'the_excerpt', array( $this, 'apply_the_excerpt' ) );
|
855 |
+
}
|
856 |
+
|
857 |
+
/**
|
858 |
+
* The main widget display controller
|
859 |
+
*
|
860 |
+
* Called by the sidebar processing core logic to display the widget.
|
861 |
+
*
|
862 |
+
* @param array $args An array containing the "environment" setting for the widget,
|
863 |
+
* namely, the enclosing tags for the widget and its title.
|
864 |
+
* @param array $instance The settings associate with the widget.
|
865 |
+
*
|
866 |
+
* @since 4.1
|
867 |
+
*/
|
868 |
+
public function widget( $args, $instance ) {
|
869 |
+
|
870 |
+
$instance = upgrade_settings( $instance );
|
871 |
+
|
872 |
+
extract( $args );
|
873 |
+
|
874 |
+
$this->instance = $instance;
|
875 |
+
|
876 |
+
$current_post_id = '';
|
877 |
+
if ( is_singular() ) {
|
878 |
+
$current_post_id = get_the_ID();
|
879 |
+
}
|
880 |
+
|
881 |
+
$items = $this->get_elements_HTML( $instance, $current_post_id, 0, 0 );
|
882 |
+
|
883 |
+
if ( ( 'nothing' === $instance['no_match_handling'] ) || ! empty( $items ) ) {
|
884 |
+
echo $before_widget; // Xss ok. This is how widget actually expected to behave.
|
885 |
+
echo $this->titleHTML( $before_title, $after_title, $instance );
|
886 |
+
|
887 |
+
$thumb = isset( $this->instance['template'] ) && preg_match( '/%thumb%/', $this->instance['template'] );
|
888 |
+
|
889 |
+
if ( ! ( isset( $instance['is_shortcode'] ) && $instance['is_shortcode'] ) ) { // the internal id is needed only for widgets.
|
890 |
+
echo '<ul id="' . esc_attr( WIDGET_BASE_ID ) . '-' . esc_attr( $this->number ) . '-internal" class="' . esc_attr( WIDGET_BASE_ID ) . '-internal' . "\">\n";
|
891 |
+
} else {
|
892 |
+
echo '<ul>';
|
893 |
+
}
|
894 |
+
|
895 |
+
// image crop browser fallback and workaround, no polyfill.
|
896 |
+
if ( $thumb ) {
|
897 |
+
if ( apply_filters( 'cpw_enqueue_resources', false ) ) {
|
898 |
+
frontend_script();
|
899 |
+
} else {
|
900 |
+
add_action( 'wp_footer', __NAMESPACE__ . '\embed_front_end_scripts' );
|
901 |
+
}
|
902 |
+
}
|
903 |
+
|
904 |
+
// set widget filters.
|
905 |
+
if ( ! isset( $instance['excerpt_filters'] ) || $instance['excerpt_filters'] ) { // pre 4.7 widgets has filters on.
|
906 |
+
$this->setExcerpFilters( $instance );
|
907 |
+
}
|
908 |
+
|
909 |
+
foreach ( $items as $item ) {
|
910 |
+
echo $item;
|
911 |
+
}
|
912 |
+
echo "</ul>\n";
|
913 |
+
|
914 |
+
// Load more only if we think we have more items.
|
915 |
+
if ( count( $items ) === (int) $instance['num'] ) {
|
916 |
+
echo $this->loadMoreHTML( $instance );
|
917 |
+
}
|
918 |
+
|
919 |
+
echo $this->footerHTML( $instance );
|
920 |
+
echo $after_widget; // Xss ok. This is how widget actually expected to behave.
|
921 |
+
|
922 |
+
// remove widget filters.
|
923 |
+
if ( ! isset( $instance['excerpt_filters'] ) || $instance['excerpt_filters'] ) { // pre 4.7 widgets has filters on.
|
924 |
+
$this->removeExcerpFilters( $instance );
|
925 |
+
}
|
926 |
+
|
927 |
+
wp_reset_postdata();
|
928 |
+
} elseif ( 'text' === $instance['no_match_handling'] ) {
|
929 |
+
echo $before_widget; // Xss ok. This is how widget actually expected to behave.
|
930 |
+
echo $this->titleHTML( $before_title, $after_title, $instance );
|
931 |
+
echo esc_html( $instance['no_match_text'] );
|
932 |
+
echo $this->footerHTML( $instance );
|
933 |
+
echo $after_widget; // Xss ok. This is how widget actually expected to behave.
|
934 |
+
}
|
935 |
+
}
|
936 |
+
|
937 |
+
/**
|
938 |
+
* Get an array of HTML pre item, for item starting from a specific position.
|
939 |
+
*
|
940 |
+
* @since 4.9
|
941 |
+
*
|
942 |
+
* @param array $instance An array containing the settings of the widget.
|
943 |
+
* @param string $singular_id The ID of the post in which the widget is rendered,
|
944 |
+
* an empty string indicates the rendering context
|
945 |
+
* is not singular.
|
946 |
+
* @param int $start The start element (0 based).
|
947 |
+
* @param int $number The maximal number of elements to return. A value of 0
|
948 |
+
* Indicates to use the widget settings for that.
|
949 |
+
*
|
950 |
+
* @return string[] Array of HTML per element with the $start element first
|
951 |
+
* $start+1 next etc. An empty array is returned if there
|
952 |
+
* are no applicable items.
|
953 |
+
*/
|
954 |
+
public function get_elements_HTML( $instance, $singular_id, $start, $number ) {
|
955 |
+
$ret = array();
|
956 |
+
|
957 |
+
if ( 0 === count( $instance ) ) {
|
958 |
+
$instance = default_settings();
|
959 |
+
}
|
960 |
+
|
961 |
+
$this->instance = $instance;
|
962 |
+
|
963 |
+
$instance['offset'] = $start;
|
964 |
+
$number = (int) $number; // sanitize number with the side effect of non
|
965 |
+
// numbers are converted to zero.
|
966 |
+
if ( 0 < $number ) {
|
967 |
+
$instance['num'] = $number;
|
968 |
+
}
|
969 |
+
$args = $this->queryArgs( $instance );
|
970 |
+
$cat_posts = new \WP_Query( $args );
|
971 |
+
$current_post_id = null;
|
972 |
+
if ( '' !== $singular_id ) {
|
973 |
+
$current_post_id = (int) $singular_id;
|
974 |
+
}
|
975 |
+
|
976 |
+
while ( $cat_posts->have_posts() ) {
|
977 |
+
$cat_posts->the_post();
|
978 |
+
$ret[] = $this->itemHTML( $instance, $current_post_id );
|
979 |
+
}
|
980 |
+
|
981 |
+
wp_reset_postdata();
|
982 |
+
|
983 |
+
return $ret;
|
984 |
+
}
|
985 |
+
|
986 |
+
/**
|
987 |
+
* Update the options.
|
988 |
+
*
|
989 |
+
* @param array $new_instance The new settings of the widget.
|
990 |
+
* @param array $old_instance The current settings of the widget.
|
991 |
+
* @return array
|
992 |
+
*/
|
993 |
+
public function update( $new_instance, $old_instance ) {
|
994 |
+
|
995 |
+
$new_instance['title'] = sanitize_text_field( $new_instance['title'] ); // sanitize the title like core widgets do.
|
996 |
+
if ( ! isset( $new_instance['excerpt_filters'] ) ) {
|
997 |
+
$new_instance['excerpt_filters'] = '';
|
998 |
+
}
|
999 |
+
if ( current_user_can( 'unfiltered_html' ) ) {
|
1000 |
+
$instance['text'] = $new_instance['template'];
|
1001 |
+
} else {
|
1002 |
+
$instance['text'] = wp_kses_post( $new_instance['template'] );
|
1003 |
+
}
|
1004 |
+
|
1005 |
+
// Set the version of the DB structure.
|
1006 |
+
$new_instance['ver'] = VERSION;
|
1007 |
+
return $new_instance;
|
1008 |
+
}
|
1009 |
+
|
1010 |
+
/**
|
1011 |
+
* Output the title panel of the widget configuration form.
|
1012 |
+
*
|
1013 |
+
* @param array $instance The widget's settings.
|
1014 |
+
* @return void
|
1015 |
+
*
|
1016 |
+
* @since 4.6
|
1017 |
+
*/
|
1018 |
+
public function formTitlePanel( $instance ) {
|
1019 |
+
$cat = (int) $instance['cat'];
|
1020 |
+
|
1021 |
+
$hide_title = false;
|
1022 |
+
if ( isset( $instance['hide_title'] ) && $instance['hide_title'] ) {
|
1023 |
+
$hide_title = true;
|
1024 |
+
}
|
1025 |
+
?>
|
1026 |
+
<h4 data-panel="title"><?php esc_html_e( 'Title', 'category-posts' ); ?></h4>
|
1027 |
+
<div class="cpwp_ident">
|
1028 |
+
<?php echo $this->get_checkbox_block_html( $instance, 'hide_title', esc_html__( 'Hide title', 'category-posts' ), true ); ?>
|
1029 |
+
<div class="categoryposts-data-panel-title-settings" <?php echo ( $hide_title ) ? 'style="display:none"' : ''; ?>>
|
1030 |
+
<?php echo $this->get_text_input_block_html( $instance, 'title', esc_html__( 'Title', 'category-posts' ), '', true ); ?>
|
1031 |
+
<?php echo $this->get_checkbox_block_html( $instance, 'title_link', esc_html__( 'Make widget title link', 'category-posts' ), 0 !== $cat ); ?>
|
1032 |
+
<?php echo $this->get_text_input_block_html( $instance, 'title_link_url', esc_html__( 'Title link URL', 'category-posts' ), '', 0 === $cat ); ?>
|
1033 |
+
</div>
|
1034 |
+
</div>
|
1035 |
+
<?php
|
1036 |
+
}
|
1037 |
+
|
1038 |
+
/**
|
1039 |
+
* Output the filter panel of the widget configuration form.
|
1040 |
+
*
|
1041 |
+
* @param array $instance The parameters configured for the widget.
|
1042 |
+
* @return void
|
1043 |
+
*
|
1044 |
+
* @since 4.6
|
1045 |
+
*/
|
1046 |
+
public function formFilterPanel( $instance ) {
|
1047 |
+
$cat = $instance['cat'];
|
1048 |
+
?>
|
1049 |
+
<h4 data-panel="filter"><?php esc_html_e( 'Filter', 'category-posts' ); ?></h4>
|
1050 |
+
<div>
|
1051 |
+
<p>
|
1052 |
+
<label>
|
1053 |
+
<?php esc_html_e( 'Category', 'category-posts' ); ?>:
|
1054 |
+
<?php
|
1055 |
+
wp_dropdown_categories( array(
|
1056 |
+
'show_option_all' => __( 'All categories', 'category-posts' ),
|
1057 |
+
'hide_empty' => 0,
|
1058 |
+
'name' => $this->get_field_name( 'cat' ),
|
1059 |
+
'selected' => $instance['cat'],
|
1060 |
+
'class' => 'categoryposts-data-panel-filter-cat',
|
1061 |
+
) );
|
1062 |
+
?>
|
1063 |
+
</label>
|
1064 |
+
</p>
|
1065 |
+
<?php
|
1066 |
+
echo $this->get_checkbox_block_html( $instance, 'no_cat_childs', esc_html__( 'Exclude child categories', 'category-posts' ), ! empty( $instance['cat'] ) );
|
1067 |
+
echo $this->get_select_block_html( $instance, 'status', esc_html__( 'Status', 'category-posts' ), array(
|
1068 |
+
'default' => esc_html__( 'WordPress Default', 'category-posts' ),
|
1069 |
+
'publish' => esc_html__( 'Published', 'category-posts' ),
|
1070 |
+
'future' => esc_html__( 'Scheduled', 'category-posts' ),
|
1071 |
+
'private' => esc_html__( 'Private', 'category-posts' ),
|
1072 |
+
'publish,future' => esc_html__( 'Published or Scheduled', 'category-posts' ),
|
1073 |
+
'private,publish' => esc_html__( 'Published or Private', 'category-posts' ),
|
1074 |
+
'private,future' => esc_html__( 'Private or Scheduled', 'category-posts' ),
|
1075 |
+
'private,publish,future' => esc_html__( 'Published, Private or Scheduled', 'category-posts' ),
|
1076 |
+
), 'default', true );
|
1077 |
+
echo $this->get_number_input_block_html( $instance, 'num', esc_html__( 'Number of posts to show', 'category-posts' ), 1, '', '', true );
|
1078 |
+
echo $this->get_number_input_block_html( $instance, 'offset', esc_html__( 'Start with post', 'category-posts' ), 1, '', '', true );
|
1079 |
+
echo $this->get_select_block_html( $instance, 'date_range', esc_html__( 'Date Range', 'category-posts' ), array(
|
1080 |
+
'off' => esc_html__( 'Off', 'category-posts' ),
|
1081 |
+
'days_ago' => esc_html__( 'Days ago', 'category-posts' ),
|
1082 |
+
'between_dates' => esc_html__( 'Between dates', 'category-posts' ),
|
1083 |
+
), 'off', true );
|
1084 |
+
?>
|
1085 |
+
<div class="cpwp_ident categoryPosts-date-range" style="display:<?php echo 'off' === $instance['date_range'] ? 'none' : 'block'; ?>">
|
1086 |
+
<?php
|
1087 |
+
echo $this->get_number_input_block_html( $instance, 'days_ago', esc_html__( 'Up to', 'category-posts' ), 1, '', '', 'days_ago' === $instance['date_range'] );
|
1088 |
+
echo $this->get_date_input_block_html( $instance, 'start_date', esc_html__( 'After', 'category-posts' ), 'between_dates' === $instance['date_range'] );
|
1089 |
+
echo $this->get_date_input_block_html( $instance, 'end_date', esc_html__( 'Before', 'category-posts' ), 'between_dates' === $instance['date_range'] );
|
1090 |
+
?>
|
1091 |
+
</div>
|
1092 |
+
<?php
|
1093 |
+
echo $this->get_select_block_html( $instance, 'sort_by', esc_html__( 'Sort by', 'category-posts' ), array(
|
1094 |
+
'date' => esc_html__( 'Date', 'category-posts' ),
|
1095 |
+
'title' => esc_html__( 'Title', 'category-posts' ),
|
1096 |
+
'comment_count' => esc_html__( 'Number of comments', 'category-posts' ),
|
1097 |
+
'rand' => esc_html__( 'Random', 'category-posts' ),
|
1098 |
+
), 'date', true );
|
1099 |
+
echo $this->get_checkbox_block_html( $instance, 'asc_sort_order', esc_html__( 'Reverse sort order (ascending)', 'category-posts' ), true );
|
1100 |
+
echo $this->get_checkbox_block_html( $instance, 'exclude_current_post', esc_html__( 'Exclude current post', 'category-posts' ), true );
|
1101 |
+
echo $this->get_checkbox_block_html( $instance, 'hideNoThumb', esc_html__( 'Exclude posts which have no thumbnail', 'category-posts' ), true );
|
1102 |
+
?>
|
1103 |
+
</div>
|
1104 |
+
<?php
|
1105 |
+
}
|
1106 |
+
|
1107 |
+
/**
|
1108 |
+
* Generate the wrapper P around a form input element
|
1109 |
+
*
|
1110 |
+
* @since 4.8
|
1111 |
+
* @param string $html The HTML to wrap.
|
1112 |
+
* @param string $key The key to use as the prefix to the class.
|
1113 |
+
* @param bool $visible Indicates if the element should be visible when rendered.
|
1114 |
+
*
|
1115 |
+
* @return string HTML with P element contaning the html being passed with class based on the key
|
1116 |
+
* and style set to display:none if visibility is off.
|
1117 |
+
*/
|
1118 |
+
private function get_wrap_block_html( $html, $key, $visible ) {
|
1119 |
+
|
1120 |
+
$cl = ' class="' . __NAMESPACE__ . '-' . esc_attr( $key ) . '"';
|
1121 |
+
|
1122 |
+
$style = '';
|
1123 |
+
if ( ! $visible ) {
|
1124 |
+
$style = ' style="display:none"';
|
1125 |
+
}
|
1126 |
+
$ret = '<p' . $cl . $style . ">\n" . $html . "</p>\n";
|
1127 |
+
|
1128 |
+
return $ret;
|
1129 |
+
}
|
1130 |
+
|
1131 |
+
/**
|
1132 |
+
* Generate a form P element containing a select element
|
1133 |
+
*
|
1134 |
+
* @since 4.8
|
1135 |
+
* @param array $instance The instance.
|
1136 |
+
* @param string $key The key in the instance array.
|
1137 |
+
* @param string $label The label to display and associate with the input.
|
1138 |
+
* @param array $list An array of pairs value (index) => label to be used for the options.
|
1139 |
+
* The labels are expected to be html escaped.
|
1140 |
+
* @param int $default The value to use if the key is not set in the instance.
|
1141 |
+
* @param bool $visible Indicates if the element should be visible when rendered.
|
1142 |
+
*
|
1143 |
+
* @return string HTML a P element contaning the select, its label, class based on the key
|
1144 |
+
* and style set to display:none if visibility is off.
|
1145 |
+
*/
|
1146 |
+
private function get_select_block_html( $instance, $key, $label, $list, $default, $visible ) {
|
1147 |
+
$value = $instance[ $key ];
|
1148 |
+
|
1149 |
+
if ( ! array_key_exists( $value, $list ) ) {
|
1150 |
+
$value = $default;
|
1151 |
+
}
|
1152 |
+
|
1153 |
+
$ret = '<label for="' . $this->get_field_id( $key ) . "\">\n" .
|
1154 |
+
$label .
|
1155 |
+
"</label>\n" .
|
1156 |
+
'<select id="' . $this->get_field_id( $key ) . '" name="' . $this->get_field_name( $key ) . '" autocomplete="off">' . "\n";
|
1157 |
+
foreach ( $list as $v => $l ) {
|
1158 |
+
$ret .= '<option value="' . esc_attr( $v ) . '" ' . selected( $v, $value, false ) . '>' . $l . "</option>\n";
|
1159 |
+
}
|
1160 |
+
$ret .= "</select>\n";
|
1161 |
+
|
1162 |
+
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1163 |
+
}
|
1164 |
+
|
1165 |
+
/**
|
1166 |
+
* Generate a form P element containing a textarea input
|
1167 |
+
*
|
1168 |
+
* @since 4.8
|
1169 |
+
* @param array $instance The instance.
|
1170 |
+
* @param string $key The key in the instance array.
|
1171 |
+
* @param string $label The label to display and associate with the input (should be html escaped).
|
1172 |
+
* @param string $placeholder The placeholder to use in the input (should be attribute escaped).
|
1173 |
+
* @param bool $visible Indicates if the element should be visible when rendered.
|
1174 |
+
* @param int $num_rows Number of rows.
|
1175 |
+
*
|
1176 |
+
* @return string HTML a P element containing the input, its label, class based on the key
|
1177 |
+
* and style set to display:none if visibility is off.
|
1178 |
+
*/
|
1179 |
+
private function get_textarea_html( $instance, $key, $label, $placeholder, $visible, $num_rows ) {
|
1180 |
+
|
1181 |
+
$value = $instance[ $key ];
|
1182 |
+
|
1183 |
+
$ret = '<label for="' . esc_attr( $this->get_field_id( $key ) ) . '">' . $label .
|
1184 |
+
'<textarea rows="' . esc_attr( $num_rows ) . '" placeholder="' . $placeholder . '" id="' . esc_attr( $this->get_field_id( $key ) ) . '" name="' . esc_attr( $this->get_field_name( $key ) ) . '" autocomplete="off">' . esc_textarea( $value ) . '</textarea>' .
|
1185 |
+
'</label>';
|
1186 |
+
|
1187 |
+
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1188 |
+
}
|
1189 |
+
|
1190 |
+
/**
|
1191 |
+
* Generate a form P element containing a text input
|
1192 |
+
*
|
1193 |
+
* @since 4.8
|
1194 |
+
* @param array $instance The instance.
|
1195 |
+
* @param string $key The key in the instance array.
|
1196 |
+
* @param string $label The label to display and associate with the input.
|
1197 |
+
* Should be html escaped.
|
1198 |
+
* @param string $placeholder The placeholder to use in the input. should be attribute escaped.
|
1199 |
+
* @param bool $visible Indicates if the element should be visible when rendered.
|
1200 |
+
*
|
1201 |
+
* @return string HTML a P element contaning the input, its label, class based on the key
|
1202 |
+
* and style set to display:none if visibility is off.
|
1203 |
+
*/
|
1204 |
+
private function get_text_input_block_html( $instance, $key, $label, $placeholder, $visible ) {
|
1205 |
+
|
1206 |
+
$value = $instance[ $key ];
|
1207 |
+
|
1208 |
+
$ret = '<label for="' . $this->get_field_id( $key ) . "\">\n" .
|
1209 |
+
$label . "\n" .
|
1210 |
+
'<input placeholder="' . $placeholder . '" id="' . $this->get_field_id( $key ) . '" name="' . $this->get_field_name( $key ) . '" type="text" value="' . esc_attr( $value ) . '" autocomplete="off"/>' . "\n" .
|
1211 |
+
"</label>\n";
|
1212 |
+
|
1213 |
+
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1214 |
+
}
|
1215 |
+
|
1216 |
+
/**
|
1217 |
+
* Generate a form P element containing a range input
|
1218 |
+
*
|
1219 |
+
* @since 4.8
|
1220 |
+
* @param array $instance The instance.
|
1221 |
+
* @param string $key The key in the instance array.
|
1222 |
+
* @param string $label The label to display and associate with the input.
|
1223 |
+
* expected to be escaped.
|
1224 |
+
* @param int $min The minimum value allowed to be input.
|
1225 |
+
* @param int $max The maximum value allowed to be input.
|
1226 |
+
* @param string $value The start value
|
1227 |
+
* @param string $step The range of each step
|
1228 |
+
* @param bool $visible Indicates if the element should be visible when rendered.
|
1229 |
+
*
|
1230 |
+
* @return string HTML a P element contaning the input, its label, class based on the key
|
1231 |
+
* and style set to display:none if visibility is off.
|
1232 |
+
*/
|
1233 |
+
private function get_range_input_block_html( $instance, $key, $label, $min, $max, $value, $step, $visible ) {
|
1234 |
+
|
1235 |
+
$value = $instance[ $key ];
|
1236 |
+
|
1237 |
+
$minMaxStep = '';
|
1238 |
+
if ( '' !== $min ) {
|
1239 |
+
$minMaxStep .= ' min="' . $min . '"';
|
1240 |
+
}
|
1241 |
+
if ( '' !== $max ) {
|
1242 |
+
$minMaxStep .= ' max="' . $max . '"';
|
1243 |
+
}
|
1244 |
+
if ( '' !== $step ) {
|
1245 |
+
$minMaxStep .= ' step="' . $step . '"';
|
1246 |
+
}
|
1247 |
+
|
1248 |
+
$ret = '<label for="' . $this->get_field_id( $key ) . "\">\n" .
|
1249 |
+
esc_html( $label ) . " <span>" . $value . "%</span>\n" .
|
1250 |
+
'<input id="' . esc_attr( $this->get_field_id( $key ) ) . '" value="' . $value . '" name="' . esc_attr( $this->get_field_name( $key ) ) . '" class="' . esc_attr( $key ) . '" type="range"' . $minMaxStep . ' />' . "\n" .
|
1251 |
+
"</label>\n";
|
1252 |
+
|
1253 |
+
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1254 |
+
}
|
1255 |
+
|
1256 |
+
/**
|
1257 |
+
* Generate a form P element containing a number input
|
1258 |
+
*
|
1259 |
+
* @since 4.8
|
1260 |
+
* @param array $instance The instance.
|
1261 |
+
* @param string $key The key in the instance array.
|
1262 |
+
* @param string $label The label to display and associate with the input.
|
1263 |
+
* expected to be escaped.
|
1264 |
+
* @param int $min The minimum value allowed to be input.
|
1265 |
+
* @param int $max The maximum value allowed to be input.
|
1266 |
+
* @param string $placeholder The placeholder string to be used. expected to be escaped.
|
1267 |
+
* @param bool $visible Indicates if the element should be visible when rendered.
|
1268 |
+
*
|
1269 |
+
* @return string HTML a P element contaning the input, its label, class based on the key
|
1270 |
+
* and style set to display:none if visibility is off.
|
1271 |
+
*/
|
1272 |
+
private function get_number_input_block_html( $instance, $key, $label, $min, $max, $placeholder, $visible ) {
|
1273 |
+
|
1274 |
+
$value = $instance[ $key ];
|
1275 |
+
|
1276 |
+
$minmax = '';
|
1277 |
+
if ( '' !== $min ) {
|
1278 |
+
$minmax .= ' min="' . $min . '"';
|
1279 |
+
}
|
1280 |
+
if ( '' !== $max ) {
|
1281 |
+
$minmax .= ' max="' . $max . '"';
|
1282 |
+
}
|
1283 |
+
|
1284 |
+
$ret = '<label for="' . $this->get_field_id( $key ) . "\">\n" .
|
1285 |
+
esc_html( $label ) . "\n" .
|
1286 |
+
'<input placeholder="' . $placeholder . '" id="' . esc_attr( $this->get_field_id( $key ) ) . '" name="' . esc_attr( $this->get_field_name( $key ) ) . '" class="' . esc_attr( $key ) . '" type="number"' . $minmax . ' value="' . esc_attr( $value ) . '" autocomplete="off" />' . "\n" .
|
1287 |
+
"</label>\n";
|
1288 |
+
|
1289 |
+
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1290 |
+
}
|
1291 |
+
|
1292 |
+
/**
|
1293 |
+
* Generate a form P element containing a date input
|
1294 |
+
*
|
1295 |
+
* @since 4.9
|
1296 |
+
* @param array $instance The instance.
|
1297 |
+
* @param string $key The key in the instance array.
|
1298 |
+
* @param string $label The label to display and associate with the input.
|
1299 |
+
* expected to be escaped.
|
1300 |
+
* @param bool $visible Indicates if the element should be visible when rendered.
|
1301 |
+
*
|
1302 |
+
* @return string HTML a P element containing the input, its label, class based on the key
|
1303 |
+
* and style set to display:none if visibility is off.
|
1304 |
+
*/
|
1305 |
+
private function get_date_input_block_html( $instance, $key, $label, $visible ) {
|
1306 |
+
|
1307 |
+
$value = $instance[ $key ];
|
1308 |
+
|
1309 |
+
$ret = '<label for="' . $this->get_field_id( $key ) . "\">\n" .
|
1310 |
+
esc_html( $label ) . "\n" .
|
1311 |
+
'<input id="' . esc_attr( $this->get_field_id( $key ) ) . '" name="' . esc_attr( $this->get_field_name( $key ) ) . '" class="' . esc_attr( $key ) . '" type="date" value="' . esc_attr( $value ) . '" autocomplete="off" />' . "\n" .
|
1312 |
+
"</label>\n";
|
1313 |
+
|
1314 |
+
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1315 |
+
}
|
1316 |
+
|
1317 |
+
/**
|
1318 |
+
* Generate a form P element containing a checkbox input
|
1319 |
+
*
|
1320 |
+
* @since 4.8
|
1321 |
+
* @param array $instance The instance.
|
1322 |
+
* @param string $key The key in the instance array.
|
1323 |
+
* @param string $label The label to display and associate with the checkbox.
|
1324 |
+
* should be escaped string.
|
1325 |
+
* @param bool $visible Indicates if the element should be visible when rendered.
|
1326 |
+
*
|
1327 |
+
* @return string HTML a P element contaning the checkbox, its label, class based on the key
|
1328 |
+
* and style set to display:none if visibility is off.
|
1329 |
+
*/
|
1330 |
+
private function get_checkbox_block_html( $instance, $key, $label, $visible ) {
|
1331 |
+
|
1332 |
+
if ( array_key_exists( $key, $instance ) ) {
|
1333 |
+
if ( $instance[ $key ] ) {
|
1334 |
+
$value = true;
|
1335 |
+
} else {
|
1336 |
+
$value = false;
|
1337 |
+
}
|
1338 |
+
}
|
1339 |
+
$ret = '<label class="checkbox" for="' . esc_attr( $this->get_field_id( $key ) ) . "\">\n" .
|
1340 |
+
'<input id="' . esc_attr( $this->get_field_id( $key ) ) . '" name="' . esc_attr( $this->get_field_name( $key ) ) . '" type="checkbox" ' . checked( $value, true, false ) . '/>' . "\n" .
|
1341 |
+
$label .
|
1342 |
+
"</label>\n";
|
1343 |
+
|
1344 |
+
return $this->get_wrap_block_html( $ret, $key, $visible );
|
1345 |
+
}
|
1346 |
+
|
1347 |
+
/**
|
1348 |
+
* Generate a form button element containing
|
1349 |
+
*
|
1350 |
+
* @since 4.9
|
1351 |
+
* @param array $instance The instance.
|
1352 |
+
* @param string $key The key in the instance array.
|
1353 |
+
* @param string $label The label to display and associate with the button.
|
1354 |
+
* should be escaped string.
|
1355 |
+
*
|
1356 |
+
* @return string HTML a button element and class based on the key.
|
1357 |
+
*/
|
1358 |
+
private function get_button_thumb_size_html( $instance, $key, $label ) {
|
1359 |
+
|
1360 |
+
$datas = "";
|
1361 |
+
|
1362 |
+
switch ( $key ) {
|
1363 |
+
case "thumb":
|
1364 |
+
$datas = 'data-thumb-w="' . get_option( "thumbnail_size_w" ) . '" data-thumb-h="' . get_option( "thumbnail_size_h" ) . '"';
|
1365 |
+
break;
|
1366 |
+
case "medium":
|
1367 |
+
$datas = 'data-thumb-w="' . get_option( "medium_size_w" ) . '" data-thumb-h="' . get_option( "medium_size_h" ) . '"';
|
1368 |
+
break;
|
1369 |
+
case "large":
|
1370 |
+
$datas = 'data-thumb-w="' . get_option( "large_size_w" ) . '" data-thumb-h="' . get_option( "large_size_h" ) . '"';
|
1371 |
+
break;
|
1372 |
+
}
|
1373 |
+
$ret = '<button type="button" ' . $datas . ' class="' . $key . ' button">' . esc_html( $label ) . "</button>\n";
|
1374 |
+
|
1375 |
+
return $ret;
|
1376 |
+
}
|
1377 |
+
|
1378 |
+
/**
|
1379 |
+
* The widget configuration form back end.
|
1380 |
+
*
|
1381 |
+
* @param array $instance The parameters associated with the widget.
|
1382 |
+
* @return void
|
1383 |
+
*/
|
1384 |
+
public function form( $instance ) {
|
1385 |
+
if ( 0 === count( $instance ) ) { // new widget, use defaults.
|
1386 |
+
$instance = default_settings();
|
1387 |
+
} else { // updated widgets come from =< 4.6 excerpt filter is on.
|
1388 |
+
if ( ! isset( $instance['excerpt_filters'] ) ) {
|
1389 |
+
$instance['excerpt_filters'] = 'on';
|
1390 |
+
}
|
1391 |
+
}
|
1392 |
+
|
1393 |
+
$instance = upgrade_settings( $instance );
|
1394 |
+
|
1395 |
+
$hide_post_titles = $instance['hide_post_titles'];
|
1396 |
+
$excerpt_more_text = $instance['excerpt_more_text'];
|
1397 |
+
$excerpt_filters = $instance['excerpt_filters'];
|
1398 |
+
$date_format = $instance['date_format'];
|
1399 |
+
$disable_css = $instance['disable_css'];
|
1400 |
+
$disable_font_styles = $instance['disable_font_styles'];
|
1401 |
+
$preset_date_format = $instance['preset_date_format'];
|
1402 |
+
$thumb = ! empty( $instance['thumb'] );
|
1403 |
+
$thumb_w = $instance['thumb_w'];
|
1404 |
+
$thumb_fluid_width = $instance['thumb_fluid_width'];
|
1405 |
+
$thumb_h = $instance['thumb_h'];
|
1406 |
+
$default_thunmbnail = $instance['default_thunmbnail'];
|
1407 |
+
$use_css_cropping = $instance['use_css_cropping'];
|
1408 |
+
$text_do_not_wrap_thumb = $instance['text_do_not_wrap_thumb'];
|
1409 |
+
?>
|
1410 |
+
|
1411 |
+
<div class="category-widget-cont">
|
1412 |
+
<?php if ( ! class_exists( '\\termcategoryPostsPro\\Widget' ) ) { ?>
|
1413 |
+
<p><a target="_blank" href="http://tiptoppress.com/term-and-category-based-posts-widget/"><?php esc_html_e( 'Get the Pro version', 'category-posts' ); ?></a></p>
|
1414 |
+
<?php
|
1415 |
+
}
|
1416 |
+
$this->formTitlePanel( $instance );
|
1417 |
+
$this->formFilterPanel( $instance );
|
1418 |
+
?>
|
1419 |
+
<h4 data-panel="details"><?php esc_html_e( 'Post details', 'category-posts' ); ?></h4>
|
1420 |
+
<div class="cpwp-sub-panel">
|
1421 |
+
<?php
|
1422 |
+
$template = '';
|
1423 |
+
if ( ! isset( $instance['template'] ) ) {
|
1424 |
+
$template = convert_settings_to_template( $instance );
|
1425 |
+
} else {
|
1426 |
+
$template = $instance['template'];
|
1427 |
+
}
|
1428 |
+
?>
|
1429 |
+
<p><?php esc_html_e( 'Displayed parts', 'category-posts' ); ?></p>
|
1430 |
+
<div class="cpwp_ident">
|
1431 |
+
<?php
|
1432 |
+
$label = esc_html__( 'Template', 'category-posts' ) .
|
1433 |
+
' <a href="#" class="dashicons toggle-template-help dashicons-editor-help imgedit-help-toggle"><span class="screen-reader-text">' .
|
1434 |
+
esc_html__( 'Show template help', 'category-posts' ) . '</span></a>';
|
1435 |
+
$class_placement = "";
|
1436 |
+
if ( is_customize_preview() ) {
|
1437 |
+
$class_placement = "customizer";
|
1438 |
+
} else {
|
1439 |
+
$class_placement = "admin-panel";
|
1440 |
+
}
|
1441 |
+
$label .= '<span class="cat-post-add_premade_templates ' . $class_placement . '">' .
|
1442 |
+
'<button type="button" class="button cpwp-open-placholder-dropdown-menu"> + ' . esc_html__( 'Add Placeholder', 'category-posts' ) . '</button>' .
|
1443 |
+
'<span class="cpwp-placeholder-dropdown-menu">' .
|
1444 |
+
'<span data-value="NewLine">' . esc_html__( 'New line', 'category-posts' ) . '</span>' .
|
1445 |
+
'<span data-value="EmptyLine">' . esc_html__( 'Empty line', 'category-posts' ) . '</span>' .
|
1446 |
+
'<span data-value="title">' . esc_html__( '%title%', 'category-posts' ) . '</span>' .
|
1447 |
+
'<span data-value="thumb">' . esc_html__( '%thumb%', 'category-posts' ) . '</span>' .
|
1448 |
+
'<span data-value="date">' . esc_html__( '%date%', 'category-posts' ) . '</span>' .
|
1449 |
+
'<span data-value="excerpt">' . esc_html__( '%excerpt%', 'category-posts' ) . '</span>' .
|
1450 |
+
'<span data-value="author">' . esc_html__( '%author%', 'category-posts' ) . '</span>' .
|
1451 |
+
'<span data-value="commentnum">' . esc_html__( '%commentnum%', 'category-posts' ) . '</span>' .
|
1452 |
+
'<span data-value="post_tag">' . esc_html__( '%post_tag%', 'category-posts' ) . '</span>' .
|
1453 |
+
'<span data-value="category">' . esc_html__( '%category%', 'category-posts' ) . '</span>' .
|
1454 |
+
'</span>' .
|
1455 |
+
'</span>';
|
1456 |
+
?>
|
1457 |
+
<?php
|
1458 |
+
echo $this->get_textarea_html( $instance, 'template', $label , '', true, 8 );
|
1459 |
+
preg_match_all( get_template_regex(), $template, $matches );
|
1460 |
+
$tags = array();
|
1461 |
+
if ( ! empty( $matches[0] ) ) {
|
1462 |
+
$tags = array_flip( $matches[0] );
|
1463 |
+
}
|
1464 |
+
?>
|
1465 |
+
<div class="cat-post-template-help">
|
1466 |
+
<p><?php esc_html_e( 'The following text will be replaced with the relevant information. In addition you can use any text and html (if you have the permisions) anywhere you want', 'category-posts' ); ?>
|
1467 |
+
</p>
|
1468 |
+
<table>
|
1469 |
+
<tr>
|
1470 |
+
<th><?php esc_html_e( 'New line', 'category-posts' ); ?></th>
|
1471 |
+
<td><?php esc_html_e( 'Space', 'category-posts' ); ?></td>
|
1472 |
+
</tr>
|
1473 |
+
<tr>
|
1474 |
+
<th><?php esc_html_e( 'Empty line', 'category-posts' ); ?></th>
|
1475 |
+
<td><?php esc_html_e( 'Next line is a paragraph', 'category-posts' ); ?></td>
|
1476 |
+
</tr>
|
1477 |
+
<tr>
|
1478 |
+
<th>%title%</th>
|
1479 |
+
<td><?php esc_html_e( 'Post title', 'category-posts' ); ?></td>
|
1480 |
+
</tr>
|
1481 |
+
<tr>
|
1482 |
+
<th>%thumb%</th>
|
1483 |
+
<td><?php esc_html_e( 'Post thumbnail possibly wrapped by text', 'category-posts' ); ?></td>
|
1484 |
+
</tr>
|
1485 |
+
<tr>
|
1486 |
+
<th>%date%</th>
|
1487 |
+
<td><?php esc_html_e( 'Post publish date', 'category-posts' ); ?></td>
|
1488 |
+
</tr>
|
1489 |
+
<tr>
|
1490 |
+
<th>%excerpt%</th>
|
1491 |
+
<td><?php esc_html_e( 'Post excerpt', 'category-posts' ); ?></td>
|
1492 |
+
</tr>
|
1493 |
+
<tr>
|
1494 |
+
<th>%author%</th>
|
1495 |
+
<td><?php esc_html_e( 'Post author', 'category-posts' ); ?></td>
|
1496 |
+
</tr>
|
1497 |
+
<tr>
|
1498 |
+
<th>%commentnum%</th>
|
1499 |
+
<td><?php esc_html_e( 'The number of comments to the post', 'category-posts' ); ?></td>
|
1500 |
+
</tr>
|
1501 |
+
<tr>
|
1502 |
+
<th>%post_tag%</th>
|
1503 |
+
<td><?php esc_html_e( 'Post tags', 'category-posts' ); ?></td>
|
1504 |
+
</tr>
|
1505 |
+
<tr>
|
1506 |
+
<th>%category%</th>
|
1507 |
+
<td><?php esc_html_e( 'Post categories', 'category-posts' ); ?></td>
|
1508 |
+
</tr>
|
1509 |
+
</table>
|
1510 |
+
</div>
|
1511 |
+
<div class="cat-post-premade_templates">
|
1512 |
+
<p><label><?php esc_html_e( 'Select premade Template', 'category-posts' ); ?></label></p>
|
1513 |
+
<select>
|
1514 |
+
<option value="title"><?php esc_html_e( 'Only the title', 'category-posts' ); ?></option>
|
1515 |
+
<option value="title_excerpt"><?php esc_html_e( 'Title and Excerpt', 'category-posts' ); ?></option>
|
1516 |
+
<option value="title_thumb"><?php esc_html_e( 'Title and Thumbnail', 'category-posts' ); ?></option>
|
1517 |
+
<option value="title_thum_excerpt"><?php esc_html_e( 'Title, Thumbnail and Excerpt', 'category-posts' ); ?></option>
|
1518 |
+
<option value="everything"><?php esc_html_e( 'All with icons', 'category-posts' ); ?></option>
|
1519 |
+
</select>
|
1520 |
+
<p><button type="button" class="button"><?php esc_html_e( 'Select this template', 'category-posts' ); ?></button></p>
|
1521 |
+
</div>
|
1522 |
+
</div>
|
1523 |
+
<?php // Excerpt settings. ?>
|
1524 |
+
<div class="cpwp-sub-panel categoryposts-data-panel-excerpt" style="display:<?php echo ( isset( $tags['%excerpt%'] ) ) ? 'block' : 'none'; ?>">
|
1525 |
+
<p><?php esc_html_e( 'Excerpt settings', 'category-posts' ); ?></p>
|
1526 |
+
<div class="cpwp_ident">
|
1527 |
+
<?php
|
1528 |
+
echo $this->get_number_input_block_html( $instance, 'excerpt_lines', esc_html__( 'Lines (responsive):', 'category-posts' ), 0, '', '', true );
|
1529 |
+
echo $this->get_number_input_block_html( $instance, 'excerpt_length', esc_html__( 'Length (words):', 'category-posts' ), 0, '', '', true );
|
1530 |
+
echo $this->get_text_input_block_html( $instance, 'excerpt_more_text', esc_html__( '\'More ...\' text:', 'category-posts' ), esc_attr__( '...', 'category-posts' ), true );
|
1531 |
+
?>
|
1532 |
+
</div>
|
1533 |
+
</div>
|
1534 |
+
<?php // Data settings ?>
|
1535 |
+
<div class="cpwp-sub-panel categoryposts-data-panel-date" style="display:<?php echo ( isset( $tags['%date%'] ) ) ? 'block' : 'none'; ?>">
|
1536 |
+
<p><?php esc_html_e( 'Date format settings', 'category-posts' ); ?></p>
|
1537 |
+
<div class="cpwp_ident">
|
1538 |
+
<?php
|
1539 |
+
echo $this->get_select_block_html( $instance, 'preset_date_format', esc_html__( 'Date format', 'category-posts' ), array(
|
1540 |
+
'sitedateandtime' => esc_html__( 'Site date and time', 'category-posts' ),
|
1541 |
+
'sitedate' => esc_html__( 'Site date', 'category-posts' ),
|
1542 |
+
'sincepublished' => esc_html__( 'Time since published', 'category-posts' ),
|
1543 |
+
'localsitedateandtime' => esc_html__( 'Reader\'s local date and time', 'category-posts' ),
|
1544 |
+
'localsitedate' => esc_html__( 'Reader\'s local date', 'category-posts' ),
|
1545 |
+
'other' => esc_html__( 'PHP style format', 'category-posts' ),
|
1546 |
+
), 'sitedateandtime', true );
|
1547 |
+
echo $this->get_text_input_block_html( $instance, 'date_format', esc_html__( 'PHP Style Date format', 'category-posts' ), 'j M Y', 'other' === $preset_date_format );
|
1548 |
+
?>
|
1549 |
+
</div>
|
1550 |
+
</div>
|
1551 |
+
<?php // Thumbnail settings. ?>
|
1552 |
+
<div class="cpwp-sub-panel categoryposts-data-panel-thumb" style="display:<?php echo ( isset( $tags['%thumb%'] ) ) ? 'block' : 'none'; ?>">
|
1553 |
+
<p><?php esc_html_e( 'Thumbnail settings', 'category-posts' ); ?></p>
|
1554 |
+
<div class="cpwp_ident">
|
1555 |
+
<p><?php esc_html_e( 'Thumbnail dimensions (pixel)', 'category-posts' ); ?></p>
|
1556 |
+
<?php
|
1557 |
+
echo $this->get_number_input_block_html( $instance, 'thumb_w', esc_html__( 'Width:', 'category-posts' ), 1, '', '', true );
|
1558 |
+
echo $this->get_range_input_block_html( $instance, 'thumb_fluid_width', esc_html__( 'Max-width:', 'category-posts' ), 2, 100, 100, 2, true );
|
1559 |
+
echo $this->get_number_input_block_html( $instance, 'thumb_h', esc_html__( 'Height:', 'category-posts' ), 1, '', '', true );
|
1560 |
+
?>
|
1561 |
+
<div class="cat-post-thumb-change-size">
|
1562 |
+
<p>
|
1563 |
+
<label><?php esc_html_e( 'Change size', 'category-posts' ); ?>: </label>
|
1564 |
+
<span class="cpwp-right">
|
1565 |
+
<?php
|
1566 |
+
echo $this->get_button_thumb_size_html( $instance, 'smaller', esc_html__( '-', 'category-posts' ) );
|
1567 |
+
echo $this->get_button_thumb_size_html( $instance, 'quarter', esc_html__( '1/4', 'category-posts' ) );
|
1568 |
+
echo $this->get_button_thumb_size_html( $instance, 'half', esc_html__( '1/2', 'category-posts' ) );
|
1569 |
+
echo $this->get_button_thumb_size_html( $instance, 'double', esc_html__( '2x', 'category-posts' ) );
|
1570 |
+
echo $this->get_button_thumb_size_html( $instance, 'bigger', esc_html__( '+', 'category-posts' ) );
|
1571 |
+
?>
|
1572 |
+
</span>
|
1573 |
+
</p>
|
1574 |
+
<p>
|
1575 |
+
<label><?php esc_html_e( 'Ratio', 'category-posts' ); ?>: </label>
|
1576 |
+
<span class="cpwp-right">
|
1577 |
+
<?php
|
1578 |
+
echo $this->get_button_thumb_size_html( $instance, 'square', esc_html__( '1:1', 'category-posts' ) );
|
1579 |
+
echo $this->get_button_thumb_size_html( $instance, 'standard', esc_html__( '4:3', 'category-posts' ) );
|
1580 |
+
echo $this->get_button_thumb_size_html( $instance, 'wide', esc_html__( '16:9', 'category-posts' ) );
|
1581 |
+
echo $this->get_button_thumb_size_html( $instance, 'switch', esc_html__( 'switch', 'category-posts' ) );
|
1582 |
+
?>
|
1583 |
+
</span>
|
1584 |
+
</p>
|
1585 |
+
<p>
|
1586 |
+
<label><?php esc_html_e( 'Available', 'category-posts' ); ?>: </label>
|
1587 |
+
<span class="cpwp-right">
|
1588 |
+
<?php
|
1589 |
+
echo $this->get_button_thumb_size_html( $instance, 'thumb', esc_html__( 'Thumb', 'category-posts' ) );
|
1590 |
+
echo $this->get_button_thumb_size_html( $instance, 'medium', esc_html__( 'Medium', 'category-posts' ) );
|
1591 |
+
echo $this->get_button_thumb_size_html( $instance, 'large', esc_html__( 'Large', 'category-posts' ) );
|
1592 |
+
?>
|
1593 |
+
</span>
|
1594 |
+
</p>
|
1595 |
+
</div>
|
1596 |
+
<?php
|
1597 |
+
echo $this->get_checkbox_block_html( $instance, 'text_do_not_wrap_thumb', esc_html__( 'Do not wrap thumbnail with overflowing text', 'category-posts' ), true );
|
1598 |
+
echo $this->get_checkbox_block_html( $instance, 'use_css_cropping', esc_html__( 'CSS crop to requested size', 'category-posts' ), false );
|
1599 |
+
echo $this->get_select_block_html( $instance, 'thumb_hover', esc_html__( 'Animation on mouse hover:', 'category-posts' ), array(
|
1600 |
+
'none' => esc_html__( 'None', 'category-posts' ),
|
1601 |
+
'dark' => esc_html__( 'Darker', 'category-posts' ),
|
1602 |
+
'white' => esc_html__( 'Brighter', 'category-posts' ),
|
1603 |
+
'scale' => esc_html__( 'Zoom in', 'category-posts' ),
|
1604 |
+
'blur' => esc_html__( 'Blur', 'category-posts' ),
|
1605 |
+
'icon' => esc_html__( 'Icon', 'category-posts' ),
|
1606 |
+
), 'none', true);
|
1607 |
+
echo $this->get_select_block_html( $instance, 'show_post_format', esc_html__( 'Indicate post format and position', 'category-posts' ), array(
|
1608 |
+
'none' => esc_html__( 'None', 'category-posts' ),
|
1609 |
+
'topleft' => esc_html__( 'Top left', 'category-posts' ),
|
1610 |
+
'bottomleft' => esc_html__( 'Bottom left', 'category-posts' ),
|
1611 |
+
'ceter' => esc_html__( 'Center', 'category-posts' ),
|
1612 |
+
'topright' => esc_html__( 'Top right', 'category-posts' ),
|
1613 |
+
'bottomright' => esc_html__( 'Bottom right', 'category-posts' ),
|
1614 |
+
'nocss' => esc_html__( 'HTML without styling', 'category-posts' ),
|
1615 |
+
), 'none', true );
|
1616 |
+
?>
|
1617 |
+
<p>
|
1618 |
+
<label style="display:block">
|
1619 |
+
<?php esc_html_e( 'Default thumbnail: ', 'category-posts' ); ?>
|
1620 |
+
</label>
|
1621 |
+
<input type="hidden" class="default_thumb_id" id="<?php echo esc_attr( $this->get_field_id( 'default_thunmbnail' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'default_thunmbnail' ) ); ?>" value="<?php echo esc_attr( $default_thunmbnail ); ?>"/>
|
1622 |
+
<span class="default_thumb_img">
|
1623 |
+
<?php
|
1624 |
+
if ( ! $default_thunmbnail ) {
|
1625 |
+
esc_html_e( 'None', 'category-posts' );
|
1626 |
+
} else {
|
1627 |
+
$img = wp_get_attachment_image_src( $default_thunmbnail );
|
1628 |
+
echo '<img width="60" height="60" src="' . esc_url( $img[0] ) . '" />';
|
1629 |
+
}
|
1630 |
+
?>
|
1631 |
+
</span>
|
1632 |
+
</p>
|
1633 |
+
<p>
|
1634 |
+
<button type="button" class="cwp_default_thumb_select button upload-button">
|
1635 |
+
<?php esc_html_e( 'Select image', 'category-posts' ); ?>
|
1636 |
+
</button>
|
1637 |
+
<button type="button" class="cwp_default_thumb_remove button upload-button" <?php echo ( ! $default_thunmbnail ) ? 'style="display:none"' : ''; ?> >
|
1638 |
+
<?php esc_html_e( 'No default', 'category-posts' ); ?>
|
1639 |
+
</button>
|
1640 |
+
</p>
|
1641 |
+
<?php
|
1642 |
+
echo $this->get_checkbox_block_html( $instance, 'everything_is_link', esc_html__( 'Everything is a link', 'category-posts' ), true );
|
1643 |
+
?>
|
1644 |
+
</div>
|
1645 |
+
</div>
|
1646 |
+
</div>
|
1647 |
+
<h4 data-panel="general"><?php esc_html_e( 'General', 'category-posts' ); ?></h4>
|
1648 |
+
<div>
|
1649 |
+
<?php echo $this->get_checkbox_block_html( $instance, 'disable_css', esc_html__( 'Disable the built-in CSS', 'category-posts' ), true ); ?>
|
1650 |
+
<?php echo $this->get_checkbox_block_html( $instance, 'disable_font_styles', esc_html__( 'Disable only font styles', 'category-posts' ), true ); ?>
|
1651 |
+
<div class="cpwp_ident">
|
1652 |
+
<?php
|
1653 |
+
echo $this->get_select_block_html( $instance, 'no_match_handling', esc_html__( 'When there are no matches', 'category-posts' ), array(
|
1654 |
+
'nothing' => esc_html__( 'Display empty widget', 'category-posts' ),
|
1655 |
+
'hide' => esc_html__( 'Hide Widget', 'category-posts' ),
|
1656 |
+
'text' => esc_html__( 'Show text', 'category-posts' ),
|
1657 |
+
), 'nothing', true );
|
1658 |
+
?>
|
1659 |
+
<div class="categoryPosts-no-match-text" style="display:<?php echo ( 'text' === $instance['no_match_handling'] ) ? 'block' : 'none'; ?>">
|
1660 |
+
<?php echo $this->get_textarea_html( $instance, 'no_match_text', esc_html__( 'Text', 'category-posts' ), '', true, 4 ); ?>
|
1661 |
+
</div>
|
1662 |
+
</div>
|
1663 |
+
<div>
|
1664 |
+
<?php
|
1665 |
+
echo $this->get_checkbox_block_html( $instance, 'enable_loadmore', esc_html__( 'Enable Load More', 'category-posts' ), true );
|
1666 |
+
?>
|
1667 |
+
<div class="loadmore-settings" style="display:<?php echo ( $instance['enable_loadmore'] ) ? 'block' : 'none'; ?>">
|
1668 |
+
<?php echo $this->get_text_input_block_html( $instance, 'loadmore_text', esc_html__( 'Button text', 'category-posts' ), '', true ); ?>
|
1669 |
+
<?php echo $this->get_text_input_block_html( $instance, 'loading_text', esc_html__( 'Loading text', 'category-posts' ), '', true ); ?>
|
1670 |
+
</div>
|
1671 |
+
</div>
|
1672 |
+
</div>
|
1673 |
+
<h4 data-panel="footer"><?php esc_html_e( 'Footer', 'category-posts' ); ?></h4>
|
1674 |
+
<div>
|
1675 |
+
<?php echo $this->get_text_input_block_html( $instance, 'footer_link_text', esc_html__( 'Footer link text', 'category-posts' ), '', true ); ?>
|
1676 |
+
<?php echo $this->get_text_input_block_html( $instance, 'footer_link', esc_html__( 'Footer link URL', 'category-posts' ), '', true ); ?>
|
1677 |
+
</div>
|
1678 |
+
<p><a href="<?php echo esc_url( get_edit_user_link() ) . '#' . __NAMESPACE__; ?>"><?php esc_html_e( 'Widget admin behaviour settings', 'category-posts' ); ?></a></p>
|
1679 |
+
<p><a target="_blank" href="<?php echo esc_url( DOC_URL ); ?>"><?php esc_html_e( 'Documentation', 'category-posts' ); ?></a></p>
|
1680 |
+
<p><a target="_blank" href="<?php echo esc_url( SUPPORT_URL ); ?>"><?php esc_html_e( 'Support', 'category-posts' ); ?></a></p>
|
1681 |
+
<p><?php echo sprintf( wp_kses( __( 'We are on <a href="%1$s">Facebook</a> and <a href="%2$s">Twitter</a>.', 'category-posts' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://www.facebook.com/TipTopPress' ), esc_url( 'https://twitter.com/TipTopPress' ) ); ?></p>
|
1682 |
+
</div>
|
1683 |
+
<?php
|
1684 |
+
}
|
1685 |
+
}
|
gulpfile.js
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var gulp = require('gulp');
|
2 |
+
var uglify = require('gulp-uglify');
|
3 |
+
var rename = require("gulp-rename");
|
4 |
+
|
5 |
+
gulp.task( 'default', [ 'scripts' ] )
|
6 |
+
|
7 |
+
// Gulp task to minify JavaScript files
|
8 |
+
gulp.task('scripts', function() {
|
9 |
+
return gulp.src(['./js/**/*.js', '!./js/**/*.min.js'])
|
10 |
+
// Minify the file
|
11 |
+
.pipe(uglify())
|
12 |
+
.pipe(rename({suffix: '.min'}))
|
13 |
+
.pipe(gulp.dest(function(file) {
|
14 |
+
return file.base;
|
15 |
+
}));
|
16 |
+
});
|
js/admin/category-posts-widget.js
CHANGED
@@ -74,6 +74,37 @@
|
|
74 |
}
|
75 |
},
|
76 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
// Show template help
|
78 |
toggleTemplateHelp: function(item,event) {
|
79 |
event.preventDefault();
|
@@ -102,6 +133,16 @@
|
|
102 |
}
|
103 |
},
|
104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
105 |
selectPremadeTemplate: function(item) {
|
106 |
var panel = item.parentElement.parentElement.parentElement;
|
107 |
var div = item.parentElement.parentElement;
|
@@ -127,14 +168,13 @@
|
|
127 |
template += '%thumb%\n';
|
128 |
template += '<span class="dashicons dashicons-admin-comments"></span> %commentnum% ';
|
129 |
template += '<span class="dashicons dashicons-admin-users"></span> %author%\n';
|
130 |
-
template += '%excerpt
|
131 |
template += 'Categories: %category% ';
|
132 |
template += '<span class="dashicons dashicons-tag"></span> %post_tag%';
|
133 |
}
|
134 |
var textarea = jQuery(panel).find('textarea');
|
135 |
textarea.val(template);
|
136 |
-
textarea.trigger('input');
|
137 |
-
textarea.trigger('change');
|
138 |
},
|
139 |
|
140 |
// Close all open panels if open
|
@@ -189,11 +229,11 @@
|
|
189 |
var template = jQuery(elem).val();
|
190 |
var tags = tiptoppress[ this.php_settings_var ].template_tags;
|
191 |
var widget_cont = jQuery(elem.parentElement.parentElement.parentElement.parentElement);
|
192 |
-
for (var
|
193 |
-
if ( -1 !== template.indexOf( tags[
|
194 |
-
widget_cont.find(this.template_panel_prefix + tags[
|
195 |
} else {
|
196 |
-
widget_cont.find(this.template_panel_prefix + tags[
|
197 |
}
|
198 |
}
|
199 |
}
|
@@ -205,6 +245,142 @@
|
|
205 |
|
206 |
},
|
207 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
208 |
}
|
209 |
|
210 |
jQuery(document).ready( function () {
|
@@ -263,15 +439,27 @@ jQuery(document).ready( function () {
|
|
263 |
cwp_namespace.toggleAssignedCategoriesTop(this);
|
264 |
});
|
265 |
|
266 |
-
jQuery(document).on('click', class_namespace+' .hide_title', function () {
|
267 |
cwp_namespace.toggleHideTitle(this);
|
268 |
});
|
269 |
|
|
|
|
|
|
|
|
|
270 |
jQuery(document).on('change', class_namespace+' .categoryPosts-preset_date_format select', function () { // change date format
|
271 |
cwp_namespace.toggleDateFormat(this);
|
272 |
});
|
273 |
|
274 |
-
jQuery(document).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
cwp_namespace.toggleTemplateHelp(this, event);
|
276 |
});
|
277 |
|
@@ -287,6 +475,28 @@ jQuery(document).ready( function () {
|
|
287 |
jQuery(document).on('input', class_namespace+' .categoryPosts-template textarea', function () { // prevent refresh ontemplate selection
|
288 |
cwp_namespace.templateChange(this);
|
289 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
290 |
}
|
291 |
|
292 |
setChangeHandlers();
|
74 |
}
|
75 |
},
|
76 |
|
77 |
+
// Show hide other date range settings
|
78 |
+
toggleDateRange: function(item) {
|
79 |
+
var value = jQuery(item).val();
|
80 |
+
var panel = item.parentElement.parentElement;
|
81 |
+
jQuery(panel).find('.categoryPosts-date-range p').hide();
|
82 |
+
jQuery(panel).find('.categoryPosts-date-range').show();
|
83 |
+
switch ( value ) {
|
84 |
+
case 'off':
|
85 |
+
jQuery(panel).find('.categoryPosts-date-range').hide();
|
86 |
+
break;
|
87 |
+
case 'days_ago':
|
88 |
+
jQuery(panel).find('.categoryPosts-days_ago').show();
|
89 |
+
break;
|
90 |
+
case 'between_dates':
|
91 |
+
jQuery(panel).find('.categoryPosts-start_date').show();
|
92 |
+
jQuery(panel).find('.categoryPosts-end_date').show();
|
93 |
+
break;
|
94 |
+
}
|
95 |
+
},
|
96 |
+
|
97 |
+
// Show/hide no match related settings
|
98 |
+
toggleNoMatch: function(item) {
|
99 |
+
var value = jQuery(item).val();
|
100 |
+
var panel = item.parentElement.parentElement;
|
101 |
+
if ( 'text' == value ) {
|
102 |
+
jQuery(panel).find('.categoryPosts-no-match-text').show();
|
103 |
+
} else {
|
104 |
+
jQuery(panel).find('.categoryPosts-no-match-text').hide();
|
105 |
+
}
|
106 |
+
},
|
107 |
+
|
108 |
// Show template help
|
109 |
toggleTemplateHelp: function(item,event) {
|
110 |
event.preventDefault();
|
133 |
}
|
134 |
},
|
135 |
|
136 |
+
toggleLoadMore: function(item) {
|
137 |
+
var value = jQuery(item).attr('checked');
|
138 |
+
var panel = item.parentElement.parentElement.parentElement;
|
139 |
+
if (value != 'checked') {
|
140 |
+
jQuery(panel).find('.loadmore-settings').hide();
|
141 |
+
} else {
|
142 |
+
jQuery(panel).find('.loadmore-settings').show();
|
143 |
+
}
|
144 |
+
},
|
145 |
+
|
146 |
selectPremadeTemplate: function(item) {
|
147 |
var panel = item.parentElement.parentElement.parentElement;
|
148 |
var div = item.parentElement.parentElement;
|
168 |
template += '%thumb%\n';
|
169 |
template += '<span class="dashicons dashicons-admin-comments"></span> %commentnum% ';
|
170 |
template += '<span class="dashicons dashicons-admin-users"></span> %author%\n';
|
171 |
+
template += '%excerpt%';
|
172 |
template += 'Categories: %category% ';
|
173 |
template += '<span class="dashicons dashicons-tag"></span> %post_tag%';
|
174 |
}
|
175 |
var textarea = jQuery(panel).find('textarea');
|
176 |
textarea.val(template);
|
177 |
+
textarea.trigger('input', 'change');
|
|
|
178 |
},
|
179 |
|
180 |
// Close all open panels if open
|
229 |
var template = jQuery(elem).val();
|
230 |
var tags = tiptoppress[ this.php_settings_var ].template_tags;
|
231 |
var widget_cont = jQuery(elem.parentElement.parentElement.parentElement.parentElement);
|
232 |
+
for (var key in tags) {
|
233 |
+
if ( -1 !== template.indexOf( tags[key] ) ) {
|
234 |
+
widget_cont.find(this.template_panel_prefix + tags[key] ).show();
|
235 |
} else {
|
236 |
+
widget_cont.find(this.template_panel_prefix + tags[key] ).hide();
|
237 |
}
|
238 |
}
|
239 |
}
|
245 |
|
246 |
},
|
247 |
|
248 |
+
thumbnailSizeChange : function (elem) {
|
249 |
+
|
250 |
+
var _that = jQuery(elem),
|
251 |
+
thumb_h,
|
252 |
+
thumb_w,
|
253 |
+
_input_thumb_h = _that.closest('.categoryposts-data-panel-thumb').find('.thumb_h'),
|
254 |
+
_input_thumb_w = _that.closest('.categoryposts-data-panel-thumb').find('.thumb_w');
|
255 |
+
|
256 |
+
if (_that.hasClass('smaller')) {
|
257 |
+
thumb_w = _input_thumb_w.val() / 1.015;
|
258 |
+
thumb_h = _input_thumb_h.val() / 1.015;
|
259 |
+
} else if (_that.hasClass('quarter')) {
|
260 |
+
thumb_w = _input_thumb_w.val() / 4;
|
261 |
+
thumb_h = _input_thumb_h.val() / 4;
|
262 |
+
} else if (_that.hasClass('half')){
|
263 |
+
thumb_h = _input_thumb_h.val() / 2;
|
264 |
+
thumb_w = _input_thumb_w.val() / 2;
|
265 |
+
} else if (_that.hasClass('double')){
|
266 |
+
thumb_h = _input_thumb_h.val() * 2;
|
267 |
+
thumb_w = _input_thumb_w.val() * 2;
|
268 |
+
} else if (_that.hasClass('bigger')) {
|
269 |
+
thumb_w = _input_thumb_w.val() * 1.02;
|
270 |
+
thumb_h = _input_thumb_h.val() * 1.02;
|
271 |
+
} else if (_that.hasClass('square')) {
|
272 |
+
if (_input_thumb_w.val() >= _input_thumb_h.val() ) {
|
273 |
+
thumb_w = _input_thumb_h.val();
|
274 |
+
thumb_h = _input_thumb_h.val();
|
275 |
+
} else{
|
276 |
+
thumb_w = _input_thumb_w.val();
|
277 |
+
thumb_h = _input_thumb_w.val();
|
278 |
+
}
|
279 |
+
} else if (_that.hasClass('standard')) {
|
280 |
+
if (_input_thumb_w.val() >= _input_thumb_h.val() ) {
|
281 |
+
thumb_w = _input_thumb_h.val() * 4 / 3;
|
282 |
+
thumb_h = _input_thumb_h.val();
|
283 |
+
} else {
|
284 |
+
thumb_w = _input_thumb_h.val() / 4 * 3
|
285 |
+
thumb_h = _input_thumb_h.val();
|
286 |
+
}
|
287 |
+
} else if (_that.hasClass('wide')) {
|
288 |
+
if (_input_thumb_w.val() >= _input_thumb_h.val() ) {
|
289 |
+
thumb_w = _input_thumb_h.val() * 16 / 9;
|
290 |
+
thumb_h = _input_thumb_h.val();
|
291 |
+
} else {
|
292 |
+
thumb_w = _input_thumb_h.val() / 16 * 9;
|
293 |
+
thumb_h = _input_thumb_h.val();
|
294 |
+
}
|
295 |
+
} else if (_that.hasClass('switch')){
|
296 |
+
thumb_h = _input_thumb_w.val();
|
297 |
+
thumb_w = _input_thumb_h.val();
|
298 |
+
} else {
|
299 |
+
thumb_w = _that.data("thumb-w");
|
300 |
+
thumb_h = _that.data("thumb-h");
|
301 |
+
}
|
302 |
+
_input_thumb_w.val(Math.floor(thumb_w));
|
303 |
+
_input_thumb_h.val(Math.floor(thumb_h));
|
304 |
+
_input_thumb_w.trigger('input', 'change');
|
305 |
+
_input_thumb_h.trigger('input', 'change');
|
306 |
+
|
307 |
+
return false;
|
308 |
+
},
|
309 |
+
|
310 |
+
thumbnailFluidWidthChange : function (elem) {
|
311 |
+
|
312 |
+
var _that = jQuery(elem),
|
313 |
+
_input_thumb_h = _that.closest('.categoryposts-data-panel-thumb').find('.thumb_h');
|
314 |
+
|
315 |
+
_that.closest( 'label' ).find( 'span' ).html( _that.val() + '%' );
|
316 |
+
|
317 |
+
_input_thumb_h.val(0);
|
318 |
+
_input_thumb_h.trigger('input', 'change');
|
319 |
+
|
320 |
+
return false;
|
321 |
+
},
|
322 |
+
|
323 |
+
openAddPlaceholder : function (elem) {
|
324 |
+
|
325 |
+
var _that = jQuery(elem);
|
326 |
+
|
327 |
+
_that.closest( '.cat-post-add_premade_templates' ).find( '.cpwp-placeholder-dropdown-menu' ).toggle();
|
328 |
+
|
329 |
+
_that.closest( '.cat-post-add_premade_templates' ).find( '.cpwp-placeholder-dropdown-menu span' ).off('click').on('click', function() {
|
330 |
+
var text = jQuery( this ).data( 'value' );
|
331 |
+
switch( text ){
|
332 |
+
case 'NewLine':
|
333 |
+
text = '\n';
|
334 |
+
break;
|
335 |
+
case 'EmptyLine':
|
336 |
+
text = '\n\n';
|
337 |
+
break;
|
338 |
+
default:
|
339 |
+
text = '%' + text + '%';
|
340 |
+
break;
|
341 |
+
}
|
342 |
+
var _div = this.parentElement.parentElement.parentElement;
|
343 |
+
var textarea = jQuery( _div ).find( 'textarea' );
|
344 |
+
var textareaPos = textarea[0].selectionStart;
|
345 |
+
var textareaTxt = textarea.val();
|
346 |
+
textarea.val( textareaTxt.substring(0, textareaPos) + text + textareaTxt.substring(textareaPos) );
|
347 |
+
|
348 |
+
textarea[0].selectionStart = textareaPos + text.length;
|
349 |
+
textarea[0].selectionEnd = textareaPos + text.length;
|
350 |
+
textarea.focus();
|
351 |
+
textarea.trigger('input', 'change');
|
352 |
+
|
353 |
+
//_that.closest( '.cat-post-add_premade_templates' ).find( '.cpwp-placeholder-dropdown-menu' ).hide();
|
354 |
+
});
|
355 |
+
|
356 |
+
_that.closest( '.cat-post-add_premade_templates' ).find( '.cpwp-placeholder-dropdown-menu' ).on('mouseenter', function(){
|
357 |
+
jQuery(this).addClass('cpw-doNotClose');
|
358 |
+
});
|
359 |
+
_that.closest( '.cat-post-add_premade_templates' ).find( '.cpwp-placeholder-dropdown-menu' ).on('mouseleave', function(){
|
360 |
+
jQuery(this).removeClass('cpw-doNotClose');
|
361 |
+
});
|
362 |
+
|
363 |
+
return false;
|
364 |
+
},
|
365 |
+
|
366 |
+
selectPlaceholderHelper : function (elem) {
|
367 |
+
|
368 |
+
var textarea = jQuery(elem);
|
369 |
+
var textareaPos = textarea[0].selectionStart;
|
370 |
+
var textareaTxt = textarea.val();
|
371 |
+
|
372 |
+
var nStartSel = textareaTxt.substring(0, textareaPos).lastIndexOf( '%' );
|
373 |
+
var nEndSel = textareaPos + textareaTxt.substring(textareaPos).indexOf( '%' ) + 1;
|
374 |
+
|
375 |
+
var strSelTxt = textareaTxt.substring(nStartSel, nEndSel);
|
376 |
+
if( strSelTxt.indexOf( '\n' ) >= 0 || strSelTxt.indexOf( ' ' ) >= 0 || strSelTxt.length <=2 ) {
|
377 |
+
return false;
|
378 |
+
}
|
379 |
+
|
380 |
+
textarea[0].selectionStart = nStartSel;
|
381 |
+
textarea[0].selectionEnd = nEndSel;
|
382 |
+
return false;
|
383 |
+
},
|
384 |
}
|
385 |
|
386 |
jQuery(document).ready( function () {
|
439 |
cwp_namespace.toggleAssignedCategoriesTop(this);
|
440 |
});
|
441 |
|
442 |
+
jQuery(document).on('click', class_namespace+' .categoryPosts-hide_title input', function () {
|
443 |
cwp_namespace.toggleHideTitle(this);
|
444 |
});
|
445 |
|
446 |
+
jQuery(document).on('click', class_namespace+' .categoryPosts-enable_loadmore input', function () {
|
447 |
+
cwp_namespace.toggleLoadMore(this);
|
448 |
+
});
|
449 |
+
|
450 |
jQuery(document).on('change', class_namespace+' .categoryPosts-preset_date_format select', function () { // change date format
|
451 |
cwp_namespace.toggleDateFormat(this);
|
452 |
});
|
453 |
|
454 |
+
jQuery(document).on('change', class_namespace+' .categoryPosts-date_range select', function () { // change date range
|
455 |
+
cwp_namespace.toggleDateRange(this);
|
456 |
+
});
|
457 |
+
|
458 |
+
jQuery(document).on('change', class_namespace+' .categoryPosts-no_match_handling select', function () { // change date range
|
459 |
+
cwp_namespace.toggleNoMatch(this);
|
460 |
+
});
|
461 |
+
|
462 |
+
jQuery(class_namespace+' a.toggle-template-help').off('click').on('click', function (event) { // show template help
|
463 |
cwp_namespace.toggleTemplateHelp(this, event);
|
464 |
});
|
465 |
|
475 |
jQuery(document).on('input', class_namespace+' .categoryPosts-template textarea', function () { // prevent refresh ontemplate selection
|
476 |
cwp_namespace.templateChange(this);
|
477 |
});
|
478 |
+
|
479 |
+
jQuery(document).on('click', class_namespace+' .cat-post-thumb-change-size button', function () { // find a thumbnail size
|
480 |
+
cwp_namespace.thumbnailSizeChange(this);
|
481 |
+
});
|
482 |
+
|
483 |
+
jQuery(document).on('change', class_namespace+' .thumb_fluid_width', function () { // select a thumbnail fluid size
|
484 |
+
cwp_namespace.thumbnailFluidWidthChange(this);
|
485 |
+
});
|
486 |
+
|
487 |
+
jQuery(class_namespace+' .cpwp-open-placholder-dropdown-menu').off('click').on('click', function () { // open drop down and add placeholder
|
488 |
+
cwp_namespace.openAddPlaceholder(this);
|
489 |
+
});
|
490 |
+
|
491 |
+
jQuery(document).on('onfocusout, blur', class_namespace+' .cpwp-open-placholder-dropdown-menu,'+class_namespace+' .categoryPosts-template textarea', function () { // close drop down placeholder, if not used
|
492 |
+
jQuery(this).closest( class_namespace+' .categoryPosts-template' ).parent().find( '.cpwp-placeholder-dropdown-menu' ).not('.cpw-doNotClose').hide();
|
493 |
+
});
|
494 |
+
|
495 |
+
jQuery(document).on('mousedown', class_namespace+' .categoryPosts-template textarea', function () { // help to select the placeholder
|
496 |
+
var _that = this;
|
497 |
+
setTimeout(function(){ cwp_namespace.selectPlaceholderHelper(_that); }, 0);
|
498 |
+
;
|
499 |
+
});
|
500 |
}
|
501 |
|
502 |
setChangeHandlers();
|
js/admin/category-posts-widget.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
var cwp_namespace={php_settings_var:"categoryPosts",widget_class:".category-widget-cont",template_panel_prefix:".categoryposts-data-panel-",open_panels:{},template_change_timer:null,clickHandler:function(e){jQuery(e).toggleClass("open").next().stop().slideToggle();var t=jQuery(e).data("panel"),a=jQuery(e).parent().parent().parent().parent().parent().attr("id"),n={};this.open_panels.hasOwnProperty(a)&&(n=this.open_panels[a]),n.hasOwnProperty(t)?delete n[t]:n[t]=!0,this.open_panels[a]=n},toggleCatSelection:function(e){var t=jQuery(e).find("option:selected").attr("value"),a=e.parentElement.parentElement.parentElement.parentElement;"0"==t?(jQuery(a).find(".categoryPosts-title_link").hide(),jQuery(a).find(".categoryPosts-title_link_url").show(),jQuery(a).find(".categoryPosts-no_cat_childs").hide()):(jQuery(a).find(".categoryPosts-title_link").show(),jQuery(a).find(".categoryPosts-title_link_url").hide(),jQuery(a).find(".categoryPosts-no_cat_childs").show())},toggleDisableFontStyles:function(e){var t=jQuery(e).find("input").attr("checked"),a=e.parentElement.parentElement;"checked"==t?jQuery(a).find(".categoryposts-data-panel-general-disable-font-styles").hide():jQuery(a).find(".categoryposts-data-panel-general-disable-font-styles").show()},toggleDateFormat:function(e){var t=jQuery(e).val(),a=e.parentElement.parentElement;"other"!=t?jQuery(a).find(".categoryPosts-date_format").hide():jQuery(a).find(".categoryPosts-date_format").show()},toggleDateRange:function(e){var t=jQuery(e).val(),a=e.parentElement.parentElement;switch(jQuery(a).find(".categoryPosts-date-range p").hide(),jQuery(a).find(".categoryPosts-date-range").show(),t){case"off":jQuery(a).find(".categoryPosts-date-range").hide();break;case"days_ago":jQuery(a).find(".categoryPosts-days_ago").show();break;case"between_dates":jQuery(a).find(".categoryPosts-start_date").show(),jQuery(a).find(".categoryPosts-end_date").show()}},toggleNoMatch:function(e){var t=jQuery(e).val(),a=e.parentElement.parentElement;"text"==t?jQuery(a).find(".categoryPosts-no-match-text").show():jQuery(a).find(".categoryPosts-no-match-text").hide()},toggleTemplateHelp:function(e,t){t.preventDefault();var a=e.parentElement.parentElement.parentElement.parentElement;jQuery(a).find(".cat-post-template-help").toggle("slow")},toggleAssignedCategoriesTop:function(e){var t=jQuery(e).find("input").attr("checked"),a=e.parentElement.parentElement;"checked"==t?jQuery(a).find(".categoryposts-details-panel-assigned-cat-top").show():jQuery(a).find(".categoryposts-details-panel-assigned-cat-top").hide()},toggleHideTitle:function(e){var t=jQuery(e).attr("checked"),a=e.parentElement.parentElement.parentElement;"checked"!=t?jQuery(a).find(".categoryposts-data-panel-title-settings").show():jQuery(a).find(".categoryposts-data-panel-title-settings").hide()},toggleLoadMore:function(e){var t=jQuery(e).attr("checked"),a=e.parentElement.parentElement.parentElement;"checked"!=t?jQuery(a).find(".loadmore-settings").hide():jQuery(a).find(".loadmore-settings").show()},selectPremadeTemplate:function(e){var t=e.parentElement.parentElement.parentElement,a=e.parentElement.parentElement,n=jQuery(a).find("select"),o="%title%";switch(value=n.val(),value){case"title":o="%title%";break;case"title_excerpt":o="%title%\n\n%excerpt%";break;case"title_thumb":o="%title%\n\n%thumb%";break;case"title_thum_excerpt":o="%title%\n\n%thumb%\n%excerpt%";break;case"everything":o="%title%\n\n",o+="%date%\n\n",o+="%thumb%\n",o+='<span class="dashicons dashicons-admin-comments"></span> %commentnum% ',o+='<span class="dashicons dashicons-admin-users"></span> %author%\n',o+="%excerpt%",o+="Categories: %category% ",o+='<span class="dashicons dashicons-tag"></span> %post_tag%'}var l=jQuery(t).find("textarea");l.val(o),l.trigger("input","change")},autoCloseOpenPanels:function(e){if(tiptoppress[this.php_settings_var].accordion&&!jQuery(e).hasClass("open")){var t=jQuery(e).parent().find(".open");this.clickHandler(t)}},defaultThumbnailSelection:function(e,t,a){var n=wp.media({title:t,multiple:!1,library:{type:"image"},button:{text:a}});return n.on("close",function(){var t=n.state().get("selection").toJSON();if(1==t.length){var a=t[0],o='<img src="'+a.url+'" ';o+='width="60" ',o+='height="60" ',o+="/>",jQuery(e).parent().prev().find(".default_thumb_img").html(o),jQuery(e).parent().find(".cwp_default_thumb_remove").show(),jQuery(e).parent().prev().find(".default_thumb_id").val(a.id).change()}}),n.open(),!1},removeDefaultThumbnailSelection:function(e){return jQuery(e).parent().prev().find(".default_thumb_img").html(cwp_default_thumb_selection.none),jQuery(e).hide(),jQuery(e).parent().prev().find(".default_thumb_id").val(0).change(),!1},templateChange:function(e){function t(){var t=jQuery(e).val(),a=tiptoppress[this.php_settings_var].template_tags,n=jQuery(e.parentElement.parentElement.parentElement.parentElement);for(var o in a)-1!==t.indexOf(a[o])?n.find(this.template_panel_prefix+a[o]).show():n.find(this.template_panel_prefix+a[o]).hide()}null!=this.template_change_timer&&clearTimeout(this.template_change_timer),this.template_change_timer=setTimeout(t.bind(this),250)},thumbnailSizeChange:function(e){var t,a,n=jQuery(e),o=n.closest(".categoryposts-data-panel-thumb").find(".thumb_h"),l=n.closest(".categoryposts-data-panel-thumb").find(".thumb_w");return n.hasClass("smaller")?(a=l.val()/1.015,t=o.val()/1.015):n.hasClass("quarter")?(a=l.val()/4,t=o.val()/4):n.hasClass("half")?(t=o.val()/2,a=l.val()/2):n.hasClass("double")?(t=2*o.val(),a=2*l.val()):n.hasClass("bigger")?(a=1.02*l.val(),t=1.02*o.val()):n.hasClass("square")?l.val()>=o.val()?(a=o.val(),t=o.val()):(a=l.val(),t=l.val()):n.hasClass("standard")?l.val()>=o.val()?(a=4*o.val()/3,t=o.val()):(a=o.val()/4*3,t=o.val()):n.hasClass("wide")?l.val()>=o.val()?(a=16*o.val()/9,t=o.val()):(a=o.val()/16*9,t=o.val()):n.hasClass("switch")?(t=l.val(),a=o.val()):(a=n.data("thumb-w"),t=n.data("thumb-h")),l.val(Math.floor(a)),o.val(Math.floor(t)),l.trigger("input","change"),o.trigger("input","change"),!1},thumbnailFluidWidthChange:function(e){var t=jQuery(e),a=t.closest(".categoryposts-data-panel-thumb").find(".thumb_h");return t.closest("label").find("span").html(t.val()+"%"),a.val(0),a.trigger("input","change"),!1},openAddPlaceholder:function(e){var t=jQuery(e);return t.closest(".cat-post-add_premade_templates").find(".cpwp-placeholder-dropdown-menu").toggle(),t.closest(".cat-post-add_premade_templates").find(".cpwp-placeholder-dropdown-menu span").off("click").on("click",function(){var e=jQuery(this).data("value");switch(e){case"NewLine":e="\n";break;case"EmptyLine":e="\n\n";break;default:e="%"+e+"%"}var t=this.parentElement.parentElement.parentElement,a=jQuery(t).find("textarea"),n=a[0].selectionStart,o=a.val();a.val(o.substring(0,n)+e+o.substring(n)),a[0].selectionStart=n+e.length,a[0].selectionEnd=n+e.length,a.focus(),a.trigger("input","change")}),t.closest(".cat-post-add_premade_templates").find(".cpwp-placeholder-dropdown-menu").on("mouseenter",function(){jQuery(this).addClass("cpw-doNotClose")}),t.closest(".cat-post-add_premade_templates").find(".cpwp-placeholder-dropdown-menu").on("mouseleave",function(){jQuery(this).removeClass("cpw-doNotClose")}),!1},selectPlaceholderHelper:function(e){var t=jQuery(e),a=t[0].selectionStart,n=t.val(),o=n.substring(0,a).lastIndexOf("%"),l=a+n.substring(a).indexOf("%")+1,s=n.substring(o,l);return!(s.indexOf("\n")>=0||s.indexOf(" ")>=0||s.length<=2)&&(t[0].selectionStart=o,t[0].selectionEnd=l,!1)}};jQuery(document).ready(function(){function e(){jQuery(".cwp_default_thumb_select").off("click").on("click",function(){cwp_namespace.defaultThumbnailSelection(this,cwp_default_thumb_selection.frame_title,cwp_default_thumb_selection.button_title)}),jQuery(document).on("change",t+" .categoryposts-data-panel-filter-cat",function(){cwp_namespace.toggleCatSelection(this)}),jQuery(".cwp_default_thumb_remove").off("click").on("click",function(){cwp_namespace.removeDefaultThumbnailSelection(this)}),jQuery(t+"-assigned_categories").off("click").on("click",function(){cwp_namespace.toggleAssignedCategoriesTop(this)}),jQuery(document).on("click",t+" .categoryPosts-hide_title input",function(){cwp_namespace.toggleHideTitle(this)}),jQuery(document).on("click",t+" .categoryPosts-enable_loadmore input",function(){cwp_namespace.toggleLoadMore(this)}),jQuery(document).on("change",t+" .categoryPosts-preset_date_format select",function(){cwp_namespace.toggleDateFormat(this)}),jQuery(document).on("change",t+" .categoryPosts-date_range select",function(){cwp_namespace.toggleDateRange(this)}),jQuery(document).on("change",t+" .categoryPosts-no_match_handling select",function(){cwp_namespace.toggleNoMatch(this)}),jQuery(t+" a.toggle-template-help").off("click").on("click",function(e){cwp_namespace.toggleTemplateHelp(this,e)}),jQuery(document).on("click",t+" .cat-post-premade_templates button",function(){cwp_namespace.selectPremadeTemplate(this)}),jQuery(document).on("change",t+" .cat-post-premade_templates select",function(e){e.preventDefault(),e.stopPropagation()}),jQuery(document).on("input",t+" .categoryPosts-template textarea",function(){cwp_namespace.templateChange(this)}),jQuery(document).on("click",t+" .cat-post-thumb-change-size button",function(){cwp_namespace.thumbnailSizeChange(this)}),jQuery(document).on("change",t+" .thumb_fluid_width",function(){cwp_namespace.thumbnailFluidWidthChange(this)}),jQuery(t+" .cpwp-open-placholder-dropdown-menu").off("click").on("click",function(){cwp_namespace.openAddPlaceholder(this)}),jQuery(document).on("onfocusout, blur",t+" .cpwp-open-placholder-dropdown-menu,"+t+" .categoryPosts-template textarea",function(){jQuery(this).closest(t+" .categoryPosts-template").parent().find(".cpwp-placeholder-dropdown-menu").not(".cpw-doNotClose").hide()}),jQuery(document).on("mousedown",t+" .categoryPosts-template textarea",function(){var e=this;setTimeout(function(){cwp_namespace.selectPlaceholderHelper(e)},0)})}var t=".category-widget-cont";jQuery(".category-widget-cont h4").click(function(){cwp_namespace.autoCloseOpenPanels(this),cwp_namespace.clickHandler(this)}),jQuery(document).on("widget-added widget-updated panelsopen",function(t,a){jQuery(".category-widget-cont h4").off("click").on("click",function(){cwp_namespace.autoCloseOpenPanels(this),cwp_namespace.clickHandler(this)}),jQuery(".cwp_default_thumb_select").off("click").on("click",function(){cwp_namespace.defaultThumbnailSelection(this,cwp_default_thumb_selection.frame_title,cwp_default_thumb_selection.button_title)}),jQuery(".cwp_default_thumb_remove").off("click").on("click",function(){cwp_namespace.removeDefaultThumbnailSelection(this)});var n=jQuery(a).attr("id");if(cwp_namespace.open_panels.hasOwnProperty(n)){var o=cwp_namespace.open_panels[n];for(var l in o)jQuery(a).find("[data-panel="+l+"]").toggleClass("open").next().stop().show()}e()}),e()});
|
js/admin/tinymce.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(t){var e="categoryPosts",o="category-posts";tinymce.create("tinymce.plugins."+e,{init:function(n,t){n.addButton(e,{title:n.getLang(o+".tooltip"),cmd:"categoryPosts_shortcode",text:"+[CP]"}),n.addCommand("categoryPosts_shortcode",function(){n.windowManager.open({title:n.getLang(o+".title"),body:[{type:"textbox",name:"title",label:n.getLang(o+".name")},{type:"container",html:'<a style="color:blue;textdecoration:underline;cursor:pointer" href="'+n.getLang(o+".profiile_url")+'">'+n.getLang(o+".hide_message")+"</a>"}],onsubmit:function(t){var e="[catposts";""!=t.data.title&&(e+=' name="'+t.data.title+'"'),e+="]",n.selection.setContent(e)}})})},createControl:function(t,e){return null},getInfo:function(){return{longname:"Insert category post shortcode",author:"TipTopPress",version:"4.7"}}}),tinymce.PluginManager.add("categoryPosts",tinymce.plugins.categoryPosts)}(jQuery);
|
js/frontend/category-posts-frontend.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
"undefined"!=typeof jQuery&&jQuery(document).ready(function(){"objectFit"in document.documentElement.style==!1&&(jQuery(".cat-post-item figure").removeClass("cat-post-crop"),jQuery(".cat-post-item figure").addClass("cat-post-crop-not-supported")),(document.documentMode||/Edge/.test(navigator.userAgent))&&(jQuery(".cat-post-item figure img").height("+=1"),window.setTimeout(function(){jQuery(".cat-post-item figure img").height("-=1")},0))});
|
js/frontend/date.js
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Category Posts Widget
|
3 |
+
* https://github.com/tiptoppress/category-posts-widget
|
4 |
+
*
|
5 |
+
* JS for the localized date functionality.
|
6 |
+
*
|
7 |
+
* Released under the GPLv2 license or later - http://www.gnu.org/licenses/gpl-2.0.html
|
8 |
+
*/
|
9 |
+
|
10 |
+
if (typeof jQuery !== 'undefined') {
|
11 |
+
|
12 |
+
jQuery( document ).ready(function () {
|
13 |
+
var $elements = jQuery('.cat-post-item .cat-post-date[data-publishtime]');
|
14 |
+
if ( 0 !== $elements) {
|
15 |
+
/**
|
16 |
+
* Adjust the dates for the items indicated in the $elements
|
17 |
+
* array.
|
18 |
+
*
|
19 |
+
* @param array $elements array of dom elements.
|
20 |
+
*/
|
21 |
+
var adjustlocalizeddate = function ( $elements ) {
|
22 |
+
$elements.each(function ( ) {
|
23 |
+
var $this = jQuery( this );
|
24 |
+
var time = $this.data( 'publishtime' ) * 1000; // new Date() requires time in ms.
|
25 |
+
var format = $this.data( 'format' );
|
26 |
+
var orig_date = new Date( time );
|
27 |
+
switch ( format ) {
|
28 |
+
case 'date' :
|
29 |
+
$this.text( orig_date.toLocaleDateString() );
|
30 |
+
break;
|
31 |
+
case 'time' :
|
32 |
+
$this.text( orig_date.toLocaleDateString() + ' '
|
33 |
+
+ orig_date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) // Eliminate seconds.
|
34 |
+
);
|
35 |
+
break;
|
36 |
+
}
|
37 |
+
});
|
38 |
+
}
|
39 |
+
|
40 |
+
adjustlocalizeddate( $elements );
|
41 |
+
|
42 |
+
// Wait for catposts.load_more event that load more triggers when for
|
43 |
+
// mewly added item, and localize the date if needed.
|
44 |
+
jQuery( 'ul' ).on('catposts.load_more', '.cat-post-item', function () {
|
45 |
+
adjustlocalizeddate( jQuery( this ).find( '.cat-post-date[data-publishtime]' ) );
|
46 |
+
});
|
47 |
+
}
|
48 |
+
});
|
49 |
+
}
|
js/frontend/date.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
"undefined"!=typeof jQuery&&jQuery(document).ready(function(){var t=jQuery(".cat-post-item .cat-post-date[data-publishtime]");if(0!==t){var e=function(t){t.each(function(){var t=jQuery(this),e=1e3*t.data("publishtime"),a=t.data("format"),i=new Date(e);switch(a){case"date":t.text(i.toLocaleDateString());break;case"time":t.text(i.toLocaleDateString()+" "+i.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"}))}})};e(t),jQuery("ul").on("catposts.load_more",".cat-post-item",function(){e(jQuery(this).find(".cat-post-date[data-publishtime]"))})}});
|
js/frontend/loadmore.js
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/**
|
2 |
+
* Category Posts Widget
|
3 |
+
* https://github.com/tiptoppress/category-posts-widget
|
4 |
+
*
|
5 |
+
* JS for the "load more" functionality.
|
6 |
+
*
|
7 |
+
* Released under the GPLv2 license or later - http://www.gnu.org/licenses/gpl-2.0.html
|
8 |
+
*/
|
9 |
+
|
10 |
+
if (typeof jQuery !== 'undefined') {
|
11 |
+
|
12 |
+
var php_settings_var = 'categoryPosts'; // should be identical to namespace.
|
13 |
+
|
14 |
+
jQuery( document ).ready(function () {
|
15 |
+
|
16 |
+
// Handle the click of load more.
|
17 |
+
jQuery(document).on('click', '.' + php_settings_var + '-loadmore button', function() {
|
18 |
+
var $this = jQuery(this);
|
19 |
+
var id = $this.data( 'id' );
|
20 |
+
var number = $this.data( 'number' );
|
21 |
+
var start = $this.data( 'start' );
|
22 |
+
var context = $this.data( 'context' );
|
23 |
+
var url = tiptoppress[php_settings_var].json_root_url;
|
24 |
+
var $ul = jQuery(this.parentElement.parentElement).find('ul'); // The UL of the widget.
|
25 |
+
var orig_text = $this.text();
|
26 |
+
var loading_text = $this.data( 'loading' );
|
27 |
+
|
28 |
+
// Change the button text to indicate loading.
|
29 |
+
$this.text( loading_text );
|
30 |
+
// Get the data from the server
|
31 |
+
jQuery.getJSON(url + '/' + id + '/' + start + '/' + number + '/' + context + '/', function ( data ) {
|
32 |
+
// appened the returned data to the UL in the returned order.
|
33 |
+
jQuery.each(data, function (key, li) {
|
34 |
+
$ul.append(li);
|
35 |
+
// apend returns the $ul, therefor we need to actualy find
|
36 |
+
// the newly added item.
|
37 |
+
$ul.children().last().trigger('catposts.load_more');
|
38 |
+
});
|
39 |
+
if (data.length != number) {
|
40 |
+
$this.hide();
|
41 |
+
} else {
|
42 |
+
$this.data( 'start', start+number );
|
43 |
+
}
|
44 |
+
}).always( function () {
|
45 |
+
// Revert to original text.
|
46 |
+
$this.text( orig_text );
|
47 |
+
});
|
48 |
+
});
|
49 |
+
});
|
50 |
+
}
|
js/frontend/loadmore.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
if("undefined"!=typeof jQuery){var php_settings_var="categoryPosts";jQuery(document).ready(function(){jQuery(document).on("click","."+php_settings_var+"-loadmore button",function(){var e=jQuery(this),t=e.data("id"),a=e.data("number"),n=e.data("start"),r=e.data("context"),o=tiptoppress[php_settings_var].json_root_url,i=jQuery(this.parentElement.parentElement).find("ul"),d=e.text(),s=e.data("loading");e.text(s),jQuery.getJSON(o+"/"+t+"/"+n+"/"+a+"/"+r+"/",function(t){jQuery.each(t,function(t,e){i.append(e),i.children().last().trigger("catposts.load_more")}),t.length!=a?e.hide():e.data("start",n+a)}).always(function(){e.text(d)})})})}
|
loadmore.php
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Server side implementation of load more handling.
|
4 |
+
*
|
5 |
+
* @package categoryposts.
|
6 |
+
*
|
7 |
+
* @since 4.9
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace categoryPosts;
|
11 |
+
|
12 |
+
// Don't call the file directly.
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Embed the front end JS for load more.
|
19 |
+
*
|
20 |
+
* @since 4.9
|
21 |
+
*/
|
22 |
+
function embed_loadmore_scripts() {
|
23 |
+
echo '<script>{';
|
24 |
+
$suffix = 'min.js';
|
25 |
+
if ( defined( 'WP_DEBUG' ) && WP_DEBUG === true ) {
|
26 |
+
$suffix = 'js';
|
27 |
+
}
|
28 |
+
echo 'var tiptoppress = Array();';
|
29 |
+
echo 'tiptoppress["' . esc_js( __NAMESPACE__ ) . '"] = { json_root_url : "' . esc_js( rest_url( __NAMESPACE__ . '/loadmore' ) ) . '"};';
|
30 |
+
include __DIR__ . '/js/frontend/loadmore.' . $suffix;
|
31 |
+
echo '}</script>';
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Generate the JSON response which includes additional element as a response
|
36 |
+
* to a "load more" request.
|
37 |
+
*
|
38 |
+
* @param \WP_REST_Request $request The rest request with widget aand start point info.
|
39 |
+
*/
|
40 |
+
function get_next_elements( \WP_REST_Request $request ) {
|
41 |
+
$id = (string) $request['id'];
|
42 |
+
$start = (int) $request['start'];
|
43 |
+
$number = (int) $request['number'];
|
44 |
+
$context = (string) $request['context'];
|
45 |
+
|
46 |
+
$ret = [];
|
47 |
+
|
48 |
+
$id_components = explode( '-', $id );
|
49 |
+
if ( 2 <= count( $id_components ) ) {
|
50 |
+
switch ( $id_components[0] ) {
|
51 |
+
case 'shortcode':
|
52 |
+
if ( 3 === count( $id_components ) ) {
|
53 |
+
$pid = $id_components[1]; // The ID of the relevant post.
|
54 |
+
$name = $id_components[2]; // The shortcode "name".
|
55 |
+
$settings = shortcode_settings( $pid, $name );
|
56 |
+
if ( ! empty( $settings ) ) {
|
57 |
+
$virtual_widget = new Virtual_Widget( '', '', $settings );
|
58 |
+
$ret = $virtual_widget->get_elements_HTML( $start, $number, $context );
|
59 |
+
}
|
60 |
+
}
|
61 |
+
break;
|
62 |
+
case 'widget':
|
63 |
+
if ( 2 === count( $id_components ) ) {
|
64 |
+
$id = $id_components[1]; // The ID of the widget.
|
65 |
+
$class = __NAMESPACE__ . '\Widget';
|
66 |
+
$widgetclass = new $class();
|
67 |
+
$allsettings = $widgetclass->get_settings();
|
68 |
+
if ( isset( $allsettings[ $id ] ) ) {
|
69 |
+
$virtual_widget = new Virtual_Widget( '', '', $allsettings[ $id ] );
|
70 |
+
$ret = $virtual_widget->get_elements_HTML( $start, $number, $context );
|
71 |
+
}
|
72 |
+
}
|
73 |
+
break;
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
return new \WP_REST_Response( $ret );
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* This function is where we register our routes for our example endpoint.
|
82 |
+
*/
|
83 |
+
function register_route() {
|
84 |
+
register_rest_route( __NAMESPACE__, '/loadmore/(?P<id>[\w-]+)/(?P<start>[\d]+)/(?P<number>[\d]+)/(?P<context>[\w]+)', array(
|
85 |
+
'methods' => 'GET',
|
86 |
+
'callback' => __NAMESPACE__ . '\get_next_elements',
|
87 |
+
) );
|
88 |
+
}
|
89 |
+
|
90 |
+
add_action( 'rest_api_init', __NAMESPACE__ . '\register_route' );
|
localizeddate.php
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Server side implementation of localized dates handling.
|
4 |
+
*
|
5 |
+
* @package categoryposts.
|
6 |
+
*
|
7 |
+
* @since 4.9
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace categoryPosts;
|
11 |
+
|
12 |
+
// Don't call the file directly.
|
13 |
+
if ( ! defined( 'ABSPATH' ) ) {
|
14 |
+
exit;
|
15 |
+
}
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Embed the front end JS for load more.
|
19 |
+
*
|
20 |
+
* @since 4.9
|
21 |
+
*/
|
22 |
+
function embed_date_scripts() {
|
23 |
+
echo '<script>{';
|
24 |
+
$suffix = 'min.js';
|
25 |
+
if ( defined( 'WP_DEBUG' ) && WP_DEBUG === true ) {
|
26 |
+
$suffix = 'js';
|
27 |
+
}
|
28 |
+
include __DIR__ . '/js/frontend/date.' . $suffix;
|
29 |
+
echo '}</script>';
|
30 |
+
}
|
readme.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
=== Category Posts Widget ===
|
2 |
Contributors: mark-k, kometschuh, mkrdip
|
3 |
-
Donate link:
|
4 |
Tags: category, categories, posts, widget, posts widget, recent posts, category recent posts, shortcode, sidebar, excerpt, multiple widgets
|
5 |
Requires at least: 2.8
|
6 |
-
Tested up to:
|
7 |
-
Stable tag: 4.
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
@@ -14,68 +14,52 @@ Adds a widget that shows the most recent posts from a single category.
|
|
14 |
Category Posts Widget is a light widget designed to do one thing and do it well: display the most recent posts from a certain category.
|
15 |
|
16 |
= Term and Category based Posts Widget =
|
17 |
-
A premium version of
|
18 |
-
We've also started creating free widget Add-ons for the Premium Widget here: [Widget extensions](http://tiptoppress.com/extensions/?utm_source=wordpress_org&utm_campaign=premium_widget_cpw&utm_medium=web).
|
19 |
|
20 |
= Premium features =
|
21 |
-
*
|
22 |
-
* Post
|
23 |
* Full background post images
|
24 |
-
*
|
25 |
-
*
|
26 |
-
*
|
27 |
-
*
|
28 |
-
* Multi selection
|
29 |
-
* More complex ways to filter (OR, AND, Exclude, ALL, Childes)
|
30 |
-
* Mouse hover effects
|
31 |
-
* Widget Extensions
|
32 |
-
* Custom filter- and action hooks (for development)
|
33 |
* All free features
|
34 |
* E-Mail support
|
35 |
-
* Free
|
36 |
-
* More examples on the [demo pages](http://demo.tiptoppress.com
|
37 |
|
38 |
= Features =
|
39 |
-
*
|
40 |
-
*
|
41 |
-
*
|
42 |
-
*
|
43 |
-
* Mouse hover effects for post thumbnail, e.g, zoom, SVG font-icon
|
44 |
* Shortcode (Easily change all Shortcode options in the customizer).
|
45 |
-
*
|
46 |
-
*
|
47 |
-
*
|
|
|
|
|
|
|
|
|
48 |
* Option to touch device friendly "everything is a link".
|
49 |
-
*
|
50 |
-
*
|
51 |
-
* Fluid images (
|
52 |
-
*
|
53 |
-
* Option to
|
54 |
-
*
|
55 |
-
*
|
56 |
-
* Option to hide widget, if category have currently no posts.
|
57 |
-
* Add option to disable subcategories.
|
58 |
* Option to hide posts which have no thumbnail.
|
59 |
* Option exclude current post.
|
60 |
-
* Option
|
61 |
-
*
|
62 |
-
*
|
63 |
-
* Option show post author.
|
64 |
-
* Option to show the comment count.
|
65 |
-
* Option to show the post date and set the date format, e.g. "Time since published"
|
66 |
-
* Filter by post status: Published, scheduled, private (like events)
|
67 |
-
* Option to make the widget date link to the category page.
|
68 |
-
* Option to format the outputted date string.
|
69 |
-
* Option to link to the category page below posts list.
|
70 |
-
* Option to disable the widget CSS or more granular control of default styling with not apply the font styles.
|
71 |
-
* Multiple widgets.
|
72 |
* Multi sites support.
|
73 |
-
* Support localization with translate.wordpress.org
|
74 |
-
* Use WP user profile for settings ('auto close' and if the shortcode button appears in the editor toolbar).
|
75 |
|
76 |
= Documentation =
|
77 |
-
* Full [documentation](http://tiptoppress.com/category-posts-widget/documentation-4-
|
78 |
-
* Shortcode: Use [catposts]
|
79 |
* Formatting date and time: See <a target="_blank" href="https://codex.wordpress.org/Formatting_Date_and_Time">Formatting Date and Time</a>
|
80 |
|
81 |
= Contribute =
|
@@ -105,7 +89,7 @@ Automatic installation is the easiest option as WordPress handles the file trans
|
|
105 |
|
106 |
== Frequently Asked Questions ==
|
107 |
= Template, placeholder and post detail =
|
108 |
-
Here You can control the [Post Detail parts](http://tiptoppress.com/category-posts-widget/documentation-4-
|
109 |
|
110 |
[How it works? and examples.](http://tiptoppress.com/template-arrange-post-details/)
|
111 |
|
@@ -114,23 +98,8 @@ For more layout options please try our premium widget: [Term and Category based
|
|
114 |
= Use SVG icons =
|
115 |
For SVG font-icon HTML we recommend the [WordPress Dashicons](https://developer.wordpress.org/resource/dashicons/), which are included as default and can be used without any font-icon including.
|
116 |
|
117 |
-
= How
|
118 |
-
Please
|
119 |
-
We also create a YouTube video: [How Category Posts Widget work with SiteOrigin Page Builder](http://tiptoppress.com/how-category-posts-widget-work-with-siteorigin-page-builder/)
|
120 |
-
|
121 |
-
= How Category Posts Widget work with Divi Builder =
|
122 |
-
You can create a new Divi widget area and put our widgets into a Divi Sidebar Module: [How to put a widget into Divi Module](https://divibooster.com/how-to-put-a-widget-into-divi-module/).
|
123 |
-
|
124 |
-
= How our widgets works with other page builder plugins like Elementor, Thrive Architect etc. =
|
125 |
-
We recommend for all other page builder plugins like Elementor or Thrive Architect to use the [WP Custom Widget Area](https://wordpress.org/plugins/wp-custom-widget-area/) plugin in additional.
|
126 |
-
|
127 |
-
Use the [WP Custom Widget Area](https://wordpress.org/plugins/wp-custom-widget-area/) plugin and create a new custom area with this plugin and place the shortcode (from the new created widget area) to a post or page. Then add our widget to the new created custom widget area the widgets admin site (Dashboard > Appearance > Widgets > … ).
|
128 |
-
|
129 |
-
= The font-size is different from that of other widgets or Theme elements? =
|
130 |
-
Please use the option: "Disable widget CSS".
|
131 |
-
|
132 |
-
= I want the title as a link pointing to the selected Categorie page? =
|
133 |
-
Enable the check box "Make widget title link".
|
134 |
|
135 |
= Parse error: syntax error, unexpected T_FUNCTION in /home/www/blog/wp-content/plugins/category-posts/cat-posts.php on line 58 =
|
136 |
Some of the features that were used in that version needs PHP 5.3+.
|
@@ -141,6 +110,11 @@ We know there are peopel how use PHP 5.2 [wordpress.org/about/stats](https://wor
|
|
141 |
= You check the PHP version with phpversion(), but the widget don't work =
|
142 |
Check also the .htaccess file, if there is an entry for an older PHP version.
|
143 |
|
|
|
|
|
|
|
|
|
|
|
144 |
== Screenshots ==
|
145 |
1. Front end of the widget with SVG font-icon support for post formats, hover effects and the Template text-area.
|
146 |
2. Template to arrange the post details with placeholders.
|
@@ -150,7 +124,18 @@ Check also the .htaccess file, if there is an entry for an older PHP version.
|
|
150 |
6. Widget behaviour settings for each user.
|
151 |
|
152 |
== Changelog ==
|
153 |
-
[Read more on our blog ...](http://tiptoppress.com/category/category-posts-widget
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
154 |
|
155 |
= 4.8.5 - April 02nd 2018 =
|
156 |
* Fixed Tabs not working
|
1 |
=== Category Posts Widget ===
|
2 |
Contributors: mark-k, kometschuh, mkrdip
|
3 |
+
Donate link: https://wordpress.org/support/plugin/category-posts/reviews/
|
4 |
Tags: category, categories, posts, widget, posts widget, recent posts, category recent posts, shortcode, sidebar, excerpt, multiple widgets
|
5 |
Requires at least: 2.8
|
6 |
+
Tested up to: 5.2
|
7 |
+
Stable tag: 4.9.1
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
10 |
|
14 |
Category Posts Widget is a light widget designed to do one thing and do it well: display the most recent posts from a certain category.
|
15 |
|
16 |
= Term and Category based Posts Widget =
|
17 |
+
A premium version of that free widget available at [tiptoppress.com](http://tiptoppress.com/) created for big Wordpress sites.
|
|
|
18 |
|
19 |
= Premium features =
|
20 |
+
* Image-Slider
|
21 |
+
* Post List "Alterations"
|
22 |
* Full background post images
|
23 |
+
* Masonry (responsive layouts), Grid and Column full page layouts
|
24 |
+
* More complex ways to filter (ANY, NOT, AND, not include children)
|
25 |
+
* Custom Post Types, Events, Products support
|
26 |
+
* Add-ons
|
|
|
|
|
|
|
|
|
|
|
27 |
* All free features
|
28 |
* E-Mail support
|
29 |
+
* Free trial on localhost
|
30 |
+
* More examples on the [demo pages](http://demo.tiptoppress.com/)
|
31 |
|
32 |
= Features =
|
33 |
+
* [Template](http://tiptoppress.com/template-arrange-post-details/) to arrange the post details.
|
34 |
+
* The Template text can be a post details placeholder, plain text, HTML or a font-icons.
|
35 |
+
* Font-icon support.
|
36 |
+
* 'Load more' button / Ajax API
|
|
|
37 |
* Shortcode (Easily change all Shortcode options in the customizer).
|
38 |
+
* Date range filter
|
39 |
+
* New date format: Time since plublished
|
40 |
+
* Filter by post status: Published, scheduled, private.
|
41 |
+
* Multiple shortcodes at the same site or post.
|
42 |
+
* Add option for post offset (use two or more widgets after another).
|
43 |
+
* Admin UI: Buttons in the editor toolbar to insert shortcode.
|
44 |
+
* Excerpt length in lines (line-clamp)
|
45 |
* Option to touch device friendly "everything is a link".
|
46 |
+
* For editing shortcode adds a Customizer link to the admin-bar ("With one click to the Customizer").
|
47 |
+
* Set thumbnail width & height / image crop with CSS (object-fit).
|
48 |
+
* Fluid images (max-width in %).
|
49 |
+
* One thumb dimension can be left empty.
|
50 |
+
* Option to set mouse hover effects for post thumbnail.
|
51 |
+
* Set a default thumbnail.
|
52 |
+
* Hide widget text or text, if there is no post.
|
|
|
|
|
53 |
* Option to hide posts which have no thumbnail.
|
54 |
* Option exclude current post.
|
55 |
+
* Option show post author, comment's count, post date.
|
56 |
+
* Admin UI: Set / find thumbnail size buttons: +, ¼, ½, 2x, -, ratio and Media sizes
|
57 |
+
* Admin UI: Buttons to easy add post details placeholder.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
* Multi sites support.
|
|
|
|
|
59 |
|
60 |
= Documentation =
|
61 |
+
* Full [documentation](http://tiptoppress.com/category-posts-widget/documentation-4-9)
|
62 |
+
* Shortcode: Use [catposts] in the content and [edit in the customizer](http://tiptoppress.com/use-shortcode-to-add-category-posts-widget-to-the-content/)
|
63 |
* Formatting date and time: See <a target="_blank" href="https://codex.wordpress.org/Formatting_Date_and_Time">Formatting Date and Time</a>
|
64 |
|
65 |
= Contribute =
|
89 |
|
90 |
== Frequently Asked Questions ==
|
91 |
= Template, placeholder and post detail =
|
92 |
+
Here You can control the [Post Detail parts](http://tiptoppress.com/category-posts-widget/documentation-4-9/#Post_details), which appears as part of the post item. All post detail will placed as placeholder. The text in the Template area can be a post details placeholder, plain text, HTML or HTML for SVG icons.
|
93 |
|
94 |
[How it works? and examples.](http://tiptoppress.com/template-arrange-post-details/)
|
95 |
|
98 |
= Use SVG icons =
|
99 |
For SVG font-icon HTML we recommend the [WordPress Dashicons](https://developer.wordpress.org/resource/dashicons/), which are included as default and can be used without any font-icon including.
|
100 |
|
101 |
+
= How to use Page Bilder plugins like Divi, SiteOrigin Page Builder or Elementor =
|
102 |
+
Please read more about Page Builder plugins at our [FAQs](http://tiptoppress.com/faqs/)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
|
104 |
= Parse error: syntax error, unexpected T_FUNCTION in /home/www/blog/wp-content/plugins/category-posts/cat-posts.php on line 58 =
|
105 |
Some of the features that were used in that version needs PHP 5.3+.
|
110 |
= You check the PHP version with phpversion(), but the widget don't work =
|
111 |
Check also the .htaccess file, if there is an entry for an older PHP version.
|
112 |
|
113 |
+
= Excerpt length in lines don't work with FireFox and IE =
|
114 |
+
We use for Excerpt length in lines a CSS feature called "line-clamp" which isn't supported in FireFox and IE at the moment.
|
115 |
+
But since it is supported by all other browsers, we think it will be supported in FireFox and IE soon.
|
116 |
+
The FireFox browser has a coverage of 5%, which we find little. For this 5%, we have included a polyfill in our [Excerpt Extension add-on](https://wordpress.org/plugins/excerpt-extension/).
|
117 |
+
|
118 |
== Screenshots ==
|
119 |
1. Front end of the widget with SVG font-icon support for post formats, hover effects and the Template text-area.
|
120 |
2. Template to arrange the post details with placeholders.
|
124 |
6. Widget behaviour settings for each user.
|
125 |
|
126 |
== Changelog ==
|
127 |
+
[Read more on our blog ...](http://tiptoppress.com/category/category-posts-widget)
|
128 |
+
|
129 |
+
= 4.9.1 - Mai 17th 2019 =
|
130 |
+
* 'Load more' button / Ajax API
|
131 |
+
* Data range filter
|
132 |
+
* Text, if there is no post
|
133 |
+
* Excerpt length in lines (line-clamp)
|
134 |
+
* Image crop with CSS (object-fit)
|
135 |
+
* Fluid images (max-width in %).
|
136 |
+
* One thumb dimension can be left empty
|
137 |
+
* Admin UI: Button to easy add post details placeholder
|
138 |
+
* Admin UI: Set / find thumbnail size buttons: +, ¼, ½, 2x, -, ratio and Media sizes
|
139 |
|
140 |
= 4.8.5 - April 02nd 2018 =
|
141 |
* Fixed Tabs not working
|
styles/admin/category-posts-widget.css
ADDED
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
|
3 |
+
.cpwp_ident {
|
4 |
+
color: #6A6A6A;
|
5 |
+
background: #efefef;
|
6 |
+
padding: 5px;
|
7 |
+
}
|
8 |
+
.cpwp_ident ~ .cpwp_ident {
|
9 |
+
margin-top: 10px;
|
10 |
+
}
|
11 |
+
.cpwp_ident:last-child {
|
12 |
+
display: block;
|
13 |
+
}
|
14 |
+
/* .cpwp_ident div:last-child {
|
15 |
+
display: block;
|
16 |
+
} */
|
17 |
+
.cpwp_ident > .cpwp_ident {
|
18 |
+
border-left:5px solid #B3B3B3;
|
19 |
+
padding: 0 10px;
|
20 |
+
}
|
21 |
+
.cpwp_ident p {
|
22 |
+
margin: 5px 0;
|
23 |
+
clear: both;
|
24 |
+
}
|
25 |
+
.cpwp_ident > label {
|
26 |
+
line-height: 2.75;
|
27 |
+
display: inline-block;
|
28 |
+
}
|
29 |
+
.cpwp_ident_top {
|
30 |
+
margin-top:-1em;
|
31 |
+
padding-top:1em;
|
32 |
+
}
|
33 |
+
.cpwp-sub-panel > p {
|
34 |
+
font-weight: lighter;
|
35 |
+
padding-bottom: 10px;
|
36 |
+
margin-bottom: 0px;
|
37 |
+
text-align: center;
|
38 |
+
}
|
39 |
+
.cpwp-sub-panel > .cpwp_ident {
|
40 |
+
background: #efefef;
|
41 |
+
color: #6A6A6A;
|
42 |
+
padding: 5px;
|
43 |
+
}
|
44 |
+
.category-widget-cont label.checkbox {
|
45 |
+
margin-left: -25px;
|
46 |
+
left: 25px;
|
47 |
+
position: relative;
|
48 |
+
}
|
49 |
+
.category-widget-cont [data-panel] + div label {
|
50 |
+
vertical-align: sub;
|
51 |
+
}
|
52 |
+
.category-widget-cont [data-panel="filter"] + div select,
|
53 |
+
.category-widget-cont input[type="number"],
|
54 |
+
.category-widget-cont input[type="text"],
|
55 |
+
.category-widget-cont input[type="range"] {
|
56 |
+
text-align:center;
|
57 |
+
float: right;
|
58 |
+
clear: both;
|
59 |
+
margin-top: 2px;
|
60 |
+
margin-bottom: 2px;
|
61 |
+
width: auto;
|
62 |
+
}
|
63 |
+
.category-widget-cont input[type="range"] {
|
64 |
+
padding-left: 0;
|
65 |
+
padding-right: 0;
|
66 |
+
}
|
67 |
+
.category-widget-cont .cpwp-right {
|
68 |
+
float: right;
|
69 |
+
}
|
70 |
+
.category-widget-cont input[type="number"] {
|
71 |
+
width:5em;
|
72 |
+
}
|
73 |
+
.category-widget-cont textarea {
|
74 |
+
width:100%;
|
75 |
+
margin-top: 5px;
|
76 |
+
}
|
77 |
+
|
78 |
+
.category-widget-cont .dashicons-editor-help {
|
79 |
+
vertical-align: sub;
|
80 |
+
}
|
81 |
+
|
82 |
+
.category-widget-cont h4 {
|
83 |
+
padding: 12px 15px;
|
84 |
+
cursor: pointer;
|
85 |
+
margin: 5px 0;
|
86 |
+
border: 1px solid #E5E5E5;
|
87 |
+
background: #f9f9f9;
|
88 |
+
}
|
89 |
+
.category-widget-cont h4:first-child {
|
90 |
+
margin-top: 10px;
|
91 |
+
}
|
92 |
+
.category-widget-cont h4:last-of-type {
|
93 |
+
margin-bottom: 10px;
|
94 |
+
}
|
95 |
+
.category-widget-cont h4:after {
|
96 |
+
float:right;
|
97 |
+
font-family: "dashicons";
|
98 |
+
content: '\f140';
|
99 |
+
-ms-transform: translate(-1px,1px);
|
100 |
+
-webkit-transform: translate(-1px,1px);
|
101 |
+
-moz-transform: translate(-1px,1px);
|
102 |
+
transform: translate(-1px,1px);
|
103 |
+
-ms-transition: all 600ms;
|
104 |
+
-webkit-transition: all 600ms;
|
105 |
+
-moz-transition: all 600ms;
|
106 |
+
transition: all 600ms;
|
107 |
+
}
|
108 |
+
.category-widget-cont h4.open:after {
|
109 |
+
-ms-transition: all 600ms;
|
110 |
+
-webkit-transition: all 600ms;
|
111 |
+
-moz-transition: all 600ms;
|
112 |
+
transition: all 600ms;
|
113 |
+
-ms-transform: rotate(180deg);
|
114 |
+
-webkit-transform: rotate(180deg);
|
115 |
+
-moz-transform: rotate(180deg);
|
116 |
+
transform: rotate(180deg);
|
117 |
+
}
|
118 |
+
.category-widget-cont > div {
|
119 |
+
display:none;
|
120 |
+
}
|
121 |
+
.category-widget-cont > div.open {
|
122 |
+
display:block;
|
123 |
+
}
|
124 |
+
.category-widget-cont th,
|
125 |
+
.category-widget-cont tr {
|
126 |
+
vertical-align: baseline;
|
127 |
+
text-align:start;
|
128 |
+
}
|
129 |
+
|
130 |
+
.categoryposts-template-help th {
|
131 |
+
text-align:start;
|
132 |
+
font-weight:bold;
|
133 |
+
}
|
134 |
+
|
135 |
+
.categoryposts-template-help td {
|
136 |
+
padding:2px;
|
137 |
+
}
|
138 |
+
|
139 |
+
.cat-post-template-help {display:none;}
|
140 |
+
|
141 |
+
.category-widget-cont .open-template-help {
|
142 |
+
border:0;
|
143 |
+
padding:0;
|
144 |
+
cursor: pointer;
|
145 |
+
}
|
146 |
+
|
147 |
+
.cat-post-thumb-change-size button.button {
|
148 |
+
line-height: normal;
|
149 |
+
height: auto;
|
150 |
+
padding: 2px 7px;
|
151 |
+
vertical-align: sub;
|
152 |
+
}
|
153 |
+
/* placeholder dropdown */
|
154 |
+
.categoryPosts-template {
|
155 |
+
float: left;
|
156 |
+
}
|
157 |
+
.cat-post-add_premade_templates {
|
158 |
+
position: relative;
|
159 |
+
}
|
160 |
+
.cat-post-add_premade_templates > button {
|
161 |
+
float: right;
|
162 |
+
}
|
163 |
+
.cat-post-add_premade_templates > .cpwp-placeholder-dropdown-menu {
|
164 |
+
display: none;
|
165 |
+
}
|
166 |
+
.cat-post-add_premade_templates > .cpwp-placeholder-dropdown-menu {
|
167 |
+
position: absolute;
|
168 |
+
right: 0;
|
169 |
+
top: 0;
|
170 |
+
z-index: 1000;
|
171 |
+
background-color: #fff;
|
172 |
+
padding: 15px 0;
|
173 |
+
border-radius: .25rem;
|
174 |
+
border: 1px solid rgba(0,0,0,.15);
|
175 |
+
white-space: nowrap;
|
176 |
+
}
|
177 |
+
.cat-post-add_premade_templates.customizer > .cpwp-placeholder-dropdown-menu {
|
178 |
+
transform: translate3d(56px, -277px, 0px);
|
179 |
+
}
|
180 |
+
.cat-post-add_premade_templates.admin-panel > .cpwp-placeholder-dropdown-menu {
|
181 |
+
transform: translate3d(322px, -4px, 0px);
|
182 |
+
}
|
183 |
+
.cpwp-placeholder-dropdown-menu > span {
|
184 |
+
display: block;
|
185 |
+
padding: 4px 24px;
|
186 |
+
}
|
187 |
+
.cpwp-placeholder-dropdown-menu > span:hover {
|
188 |
+
background-color: #f8f9fa;
|
189 |
+
cursor: pointer;
|
190 |
+
}
|