Skip to content

Commit 5a09533

Browse files
feat: improve UX for Feed Group (#1108)
1 parent baea309 commit 5a09533

File tree

6 files changed

+253
-5
lines changed

6 files changed

+253
-5
lines changed

css/settings.css

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2620,6 +2620,29 @@ li.draggable-item .components-panel__body-toggle.components-button{
26202620
color: #050505;
26212621
}
26222622

2623+
.validate-feeds-actions {
2624+
display: flex;;
2625+
}
2626+
.validate-feeds-actions .spinner:not(.is-active) {
2627+
display: none;
2628+
}
2629+
.validate-feeds-actions .spinner.is-active {
2630+
display: inline-block;
2631+
}
2632+
.feedzy-preview-list {
2633+
padding-left: 15px;
2634+
}
2635+
.feedzy-preview-list li {
2636+
list-style: disc;
2637+
}
2638+
.feedzy-preview-list li a {
2639+
text-decoration: none;
2640+
}
2641+
.feedzy-preview-list li time {
2642+
font-size: 11px;
2643+
font-weight: 500;
2644+
color: #757575;
2645+
}
26232646
@-webkit-keyframes spin {
26242647
100% { -webkit-transform: rotate(360deg); }
26252648
}

includes/abstract/feedzy-rss-feeds-admin-abstract.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1663,7 +1663,7 @@ private function get_feed_item_filter( $sc, $sizes, $item, $feed_url, $index, $i
16631663
'item_url_follow' => isset( $sc['follow'] ) && 'yes' === $sc['follow'] ? 'nofollow' : '',
16641664
'item_url_title' => $item->get_title(),
16651665
'item_img' => $content_thumb,
1666-
'item_img_path' => $this->feedzy_retrieve_image( $item, $sc ),
1666+
'item_img_path' => isset( $sc['thumb'] ) && ( 'yes' === $sc['thumb'] || 'auto' === $sc['thumb'] ) ? $this->feedzy_retrieve_image( $item, $sc ) : '',
16671667
'item_title' => $content_title,
16681668
'item_content_class' => 'rss_content',
16691669
'item_content_style' => '',

includes/admin/feedzy-rss-feeds-admin.php

Lines changed: 155 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,19 @@ public function add_feedzy_post_type_metaboxes() {
897897
'low'
898898
);
899899
}
900+
901+
if ( 'publish' === get_post_status() ) {
902+
add_meta_box(
903+
'feedzy_category_feeds_preview',
904+
__( 'Feed Preview', 'feedzy-rss-feeds' ),
905+
array(
906+
$this,
907+
'render_feed_preview',
908+
),
909+
'feedzy_categories',
910+
'side'
911+
);
912+
}
900913
}
901914

902915
/**
@@ -939,12 +952,106 @@ public function feedzy_category_feed() {
939952
)
940953
. '</strong><br/><br/>'
941954
. $invalid
942-
. '<textarea name="feedzy_category_feed" rows="15" class="widefat" placeholder="' . __( 'Place your URL\'s here followed by a comma.', 'feedzy-rss-feeds' ) . '" >' . $feed . '</textarea>
943-
<p><a href="' . esc_url( 'https://docs.themeisle.com/article/1119-feedzy-rss-feeds-documentation#categories' ) . '" target="_blank">' . __( 'Learn how to organize feeds in Groups', 'feedzy-rss-feeds' ) . '</a></p>
955+
. '<textarea name="feedzy_category_feed" rows="10" class="widefat" placeholder="themeisle.com/blog/feed/, https://wptavern.com/feed/, https://www.wpbeginner.com/feed/, https://wpshout.com/feed/, https://planet.wordpress.org/feed/" >' . $feed . '</textarea>
956+
<div class="validate-feeds-actions">
957+
<span class="spinner"></span>
958+
<button class="button validate-feeds" ' . esc_attr( empty( $feed ) ? 'disabled' : '' ) . '>' . __( 'Validate & Remove Invalid Feeds', 'feedzy-rss-feeds' ) . '</button>
959+
</div>
944960
';
945961
echo wp_kses( $output, apply_filters( 'feedzy_wp_kses_allowed_html', array() ) );
946962
}
947963

964+
/**
965+
* Render the feed preview metabox.
966+
*
967+
* @return void
968+
*/
969+
public function render_feed_preview() {
970+
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
971+
if ( isset( $_GET['action'] ) && 'edit' !== $_GET['action'] ) {
972+
return;
973+
}
974+
$feeds = get_post_meta( get_the_ID(), 'feedzy_category_feed', true );
975+
$feed_urls = $this->normalize_urls( $feeds );
976+
if ( empty( $feed_urls ) ) {
977+
echo '<p>' . esc_html__( 'No feeds available for preview.', 'feedzy-rss-feeds' ) . '</p>';
978+
return;
979+
}
980+
$shortcode = array(
981+
'sort' => 'date_desc',
982+
'thumb' => 'no',
983+
'max' => 0,
984+
);
985+
$atts = $this->get_short_code_attributes( $shortcode );
986+
$atts = $this->sanitize_attr( $atts, $feed_urls );
987+
$sizes = array(
988+
'width' => 0,
989+
'height' => 0,
990+
);
991+
$feed = $this->fetch_feed( $feed_urls, $atts['refresh'], $atts );
992+
$feed_items = apply_filters( 'feedzy_get_feed_array', array(), $atts, $feed, $feed_urls, $sizes );
993+
$total_items = count( $feed_items );
994+
995+
$max_items_preview_count = 5;
996+
$preview_feed_items = array_slice( $feed_items, 0, $max_items_preview_count );
997+
?>
998+
<strong>
999+
<?php
1000+
echo esc_html(
1001+
sprintf(
1002+
// translators: %1$s the number of maximum displayed items, %2$s is the total number of items available in the feed.
1003+
__( 'Latest %1$s feed items out of %2$s available from', 'feedzy-rss-feeds' ),
1004+
$max_items_preview_count,
1005+
$total_items
1006+
)
1007+
);
1008+
?>
1009+
</strong>
1010+
<div>
1011+
<ul class="feedzy-preview-list">
1012+
<?php
1013+
foreach ( $preview_feed_items as $item ) {
1014+
$datetime = date_i18n( 'c', $item['item_date'] );
1015+
$time_content = date_i18n( 'Y-m-d', $item['item_date'] );
1016+
?>
1017+
<li <?php echo esc_attr( $item['itemAttr'] ); ?>>
1018+
<a href="<?php echo esc_url( $item['item_url'] ); ?>" target="_blank">
1019+
<?php echo esc_html( $item['item_title'] ); ?>
1020+
</a>
1021+
<br/>
1022+
<time
1023+
datetime="<?php echo esc_attr( $datetime ); ?>"
1024+
content="<?php echo esc_attr( $time_content ); ?>"
1025+
>
1026+
<?php echo esc_html( $this->get_humman_readable_time_diff( $item['item_date'] ) ); ?>
1027+
</time>
1028+
</li>
1029+
<?php
1030+
}
1031+
?>
1032+
</ul>
1033+
</div>
1034+
<?php
1035+
}
1036+
1037+
/**
1038+
* Get human readable time difference.
1039+
*
1040+
* @param int $item_publish_time The item publish time.
1041+
*
1042+
* @return string
1043+
*/
1044+
private function get_humman_readable_time_diff( $item_publish_time ) {
1045+
$array = current_datetime();
1046+
$localtime = $array->getTimestamp() + $array->getOffset();
1047+
1048+
return sprintf(
1049+
// translators: %s is the time difference.
1050+
__( '%s ago', 'feedzy-rss-feeds' ),
1051+
human_time_diff( $item_publish_time, $localtime )
1052+
);
1053+
}
1054+
9481055
/**
9491056
* Utility method to save metabox data to
9501057
* custom post type.
@@ -1030,6 +1137,8 @@ public function feedzy_category_columns( $columns ) {
10301137
$columns['actions'] = __( 'Actions', 'feedzy-rss-feeds' );
10311138
}
10321139

1140+
$new_columns = $this->array_insert_before( 'slug', $columns, 'source', __( 'Source', 'feedzy-rss-feeds' ) );
1141+
10331142
return $columns;
10341143
}
10351144

@@ -1074,6 +1183,33 @@ public function manage_feedzy_category_columns( $column, $post_id ) {
10741183
case 'actions':
10751184
echo wp_kses_post( sprintf( '<button class="button button-primary validate-category" title="%s" data-category-id="%d">%s</button>', __( 'Click to remove invalid URLs from this category', 'feedzy-rss-feeds' ), $post_id, __( 'Validate & Clean', 'feedzy-rss-feeds' ) ) );
10761185
break;
1186+
case 'source':
1187+
$src = get_post_meta( $post_id, 'feedzy_category_feed', true );
1188+
if ( empty( $src ) ) {
1189+
$src = __( 'No Source Configured', 'feedzy-rss-feeds' );
1190+
} else {
1191+
$urls = $this->normalize_urls( $src );
1192+
$src = '';
1193+
if ( is_array( $urls ) ) {
1194+
1195+
foreach ( $urls as $key => $url ) {
1196+
$too_long = 130;
1197+
if ( strlen( $src ) > $too_long ) {
1198+
$src .= '...';
1199+
break;
1200+
} else {
1201+
$src .= '<a href="' . $url . '" target="_blank" title="' . __( 'Click to view', 'feedzy-rss-feeds' ) . '">' . $url . '</a>';
1202+
if ( count( $urls ) > $key + 1 ) {
1203+
$src .= ', ';
1204+
}
1205+
}
1206+
}
1207+
} else {
1208+
$src .= '<a href="' . esc_url( $urls ) . '" target="_blank" title="' . __( 'Click to view', 'feedzy-rss-feeds' ) . '">' . esc_html( $urls ) . '</a>';
1209+
}
1210+
}
1211+
echo wp_kses_post( $src );
1212+
break;
10771213
default:
10781214
break;
10791215
}
@@ -1709,6 +1845,23 @@ public function ajax() {
17091845
}
17101846
wp_send_json_success( array( 'invalid' => count( $invalid ) ) );
17111847
break;
1848+
case 'validate_feeds_group':
1849+
$feeds = isset( $_POST['feeds'] ) ? sanitize_text_field( wp_unslash( $_POST['feeds'] ) ) : '';
1850+
if ( empty( $feeds ) ) {
1851+
wp_send_json_error( __( 'No feeds provided for validation.', 'feedzy-rss-feeds' ) );
1852+
}
1853+
$feeds = $this->normalize_urls( $feeds );
1854+
if ( ! is_array( $feeds ) ) {
1855+
$feeds = array( $feeds );
1856+
}
1857+
$valid = $this->get_valid_source_urls( $feeds, '1_mins', false );
1858+
$invalid = array_diff( $feeds, $valid );
1859+
wp_send_json_success(
1860+
array(
1861+
'valid' => $valid,
1862+
'invalid' => $invalid,
1863+
)
1864+
);
17121865
}
17131866
}
17141867

includes/feedzy-rss-feeds-activator.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,43 @@ public static function activate() {
5757
)
5858
);
5959
}
60+
self::add_feeds_group();
61+
}
62+
63+
/**
64+
* Adds a default feeds group with some popular WordPress-related feeds.
65+
*
66+
* This method checks if a feeds group already exists, and if not, creates one
67+
* with a set of predefined feeds.
68+
*
69+
* @return void
70+
*/
71+
public static function add_feeds_group() {
72+
if ( get_option( '_feedzy_news_group_id', false ) ) {
73+
return;
74+
}
75+
76+
$group_args = array(
77+
'post_title' => __( 'News sites', 'feedzy-rss-feeds' ),
78+
'post_type' => 'feedzy_categories',
79+
'post_status' => 'publish',
80+
'post_content' => '',
81+
);
82+
83+
$news_group = wp_insert_post( $group_args );
84+
85+
$default_feed_urls = array(
86+
'https://themeisle.com/blog/feed/',
87+
'https://wptavern.com/feed/',
88+
'https://www.wpbeginner.com/feed/',
89+
'https://wpshout.com/feed/',
90+
'https://planet.wordpress.org/feed/',
91+
);
92+
93+
$feed_groups = implode( ', ', array_map( 'esc_url', $default_feed_urls ) );
94+
95+
add_post_meta( $news_group, 'feedzy_category_feed', $feed_groups );
96+
97+
update_option( '_feedzy_news_group_id', $news_group );
6098
}
6199
}

includes/feedzy-rss-feeds-feed-tweaks.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,10 +466,13 @@ function ( $allowed_html = array() ) {
466466
'value' => array(),
467467
'class' => array(),
468468
'data-feedzy' => array(),
469+
'placeholder' => array(),
470+
'rows' => array(),
469471
),
470472
'button' => array(
471-
'class' => array(),
472-
'id' => array(),
473+
'class' => array(),
474+
'id' => array(),
475+
'disabled' => array(),
473476
),
474477
'p' => array(
475478
'class' => array(),

js/categories.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
$(document).ready(function(){
66
init();
7+
validateFeeds();
78
});
89

910
function init(){
@@ -33,4 +34,34 @@
3334
});
3435
}
3536

37+
// validate feeds group.
38+
function validateFeeds() {
39+
$('#feedzy_category_feeds textarea[name="feedzy_category_feed"]').on('input', function() {
40+
$('.validate-feeds').attr('disabled', 1 > $(this).val().length );
41+
});
42+
43+
$('#feedzy_category_feeds .button.validate-feeds').on('click', function(e) {
44+
e.preventDefault();
45+
const button = $(this);
46+
button.attr('disabled', true);
47+
$('#feedzy_category_feeds .spinner').addClass('is-active');
48+
$.ajax({
49+
url: ajaxurl,
50+
method: 'POST',
51+
data: {
52+
action: 'feedzy_categories',
53+
_action: 'validate_feeds_group',
54+
security: feedzy.ajax.security,
55+
feeds: $('textarea[name="feedzy_category_feed"]').val()
56+
},
57+
success: function(data) {
58+
if (data.success) {
59+
$('textarea[name="feedzy_category_feed"]').val(data.data.valid.join(', '));
60+
$('#feedzy_category_feeds .spinner').removeClass('is-active');
61+
}
62+
}
63+
})
64+
});
65+
}
66+
3667
})(jQuery, feedzy);

0 commit comments

Comments
 (0)