Skip to content

Commit ecc3509

Browse files
feat: improve feed group UX
1 parent e3949c4 commit ecc3509

File tree

6 files changed

+266
-5
lines changed

6 files changed

+266
-5
lines changed

css/settings.css

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

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1626,7 +1626,7 @@ private function get_feed_item_filter( $sc, $sizes, $item, $feed_url, $index, $i
16261626
'item_url_follow' => isset( $sc['follow'] ) && 'yes' === $sc['follow'] ? 'nofollow' : '',
16271627
'item_url_title' => $item->get_title(),
16281628
'item_img' => $content_thumb,
1629-
'item_img_path' => $this->feedzy_retrieve_image( $item, $sc ),
1629+
'item_img_path' => isset( $sc['thumb'] ) && ( 'yes' === $sc['thumb'] || 'auto' === $sc['thumb'] ) ? $this->feedzy_retrieve_image( $item, $sc ) : '',
16301630
'item_title' => $content_title,
16311631
'item_content_class' => 'rss_content',
16321632
'item_content_style' => '',

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

Lines changed: 172 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,19 @@ public function add_feedzy_post_type_metaboxes() {
708708
'low'
709709
);
710710
}
711+
712+
if ( 'publish' === get_post_status() ) {
713+
add_meta_box(
714+
'feedzy_category_feeds_preview',
715+
__( 'Feed Preview', 'feedzy-rss-feeds' ),
716+
array(
717+
$this,
718+
'render_feed_preview',
719+
),
720+
'feedzy_categories',
721+
'side'
722+
);
723+
}
711724
}
712725

713726
/**
@@ -750,12 +763,118 @@ public function feedzy_category_feed() {
750763
)
751764
. '</strong><br/><br/>'
752765
. $invalid
753-
. '<textarea name="feedzy_category_feed" rows="15" class="widefat" placeholder="' . __( 'Place your URL\'s here followed by a comma.', 'feedzy-rss-feeds' ) . '" >' . $feed . '</textarea>
754-
<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>
766+
. '<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>
767+
<div class="validate-feeds-actions">
768+
<span class="spinner"></span>
769+
<button class="button validate-feeds" ' . esc_attr( empty( $feed ) ? 'disabled' : '' ) . '>' . __( 'Validate & Remove Invalid Feeds', 'feedzy-rss-feeds' ) . '</button>
770+
</div>
755771
';
756772
echo wp_kses( $output, apply_filters( 'feedzy_wp_kses_allowed_html', array() ) );
757773
}
758774

775+
/**
776+
* Render the feed preview metabox.
777+
*
778+
* @return void
779+
*/
780+
public function render_feed_preview() {
781+
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
782+
if ( isset( $_GET['action'] ) && 'edit' !== $_GET['action'] ) {
783+
return;
784+
}
785+
$feeds = get_post_meta( get_the_ID(), 'feedzy_category_feed', true );
786+
$feed_urls = $this->normalize_urls( $feeds );
787+
if ( empty( $feed_urls ) ) {
788+
echo '<p>' . esc_html__( 'No feeds available for preview.', 'feedzy-rss-feeds' ) . '</p>';
789+
return;
790+
}
791+
$shortcode = array(
792+
'sort' => 'date_desc',
793+
'thumb' => 'no',
794+
'max' => 0,
795+
);
796+
$atts = $this->get_short_code_attributes( $shortcode );
797+
$atts = $this->sanitize_attr( $atts, $feed_urls );
798+
$sizes = array(
799+
'width' => 0,
800+
'height' => 0,
801+
);
802+
$feed = $this->fetch_feed( $feed_urls, $atts['refresh'], $atts );
803+
$feed_items = apply_filters( 'feedzy_get_feed_array', array(), $atts, $feed, $feed_urls, $sizes );
804+
$total_items = count( $feed_items );
805+
$count = 0;
806+
807+
echo wp_kses(
808+
sprintf(
809+
// translators: %s is the total number of items available in the feed.
810+
'<strong>' . __( 'Latest 5 feed items out of %s available from', 'feedzy-rss-feeds' ) . '</strong>',
811+
$total_items
812+
),
813+
array(
814+
'strong' => array(),
815+
)
816+
);
817+
818+
echo '<div class="feedzy-preview">';
819+
$content = '<ul class="feedzy-preview-list">';
820+
821+
foreach ( $feed_items as $item ) {
822+
if ( $count > 4 ) {
823+
break;
824+
}
825+
$content .= sprintf(
826+
'<li %s><a href="%s" target="_blank">%s</a><br/><time datetime="%s" content="%s">%s</time></li>',
827+
esc_attr( $item['itemAttr'] ),
828+
esc_attr( $item['item_url'] ),
829+
esc_html( $item['item_title'] ),
830+
esc_attr( date_i18n( 'c', $item['item_date'] ) ),
831+
esc_attr( date_i18n( 'Y-m-d', $item['item_date'] ) ),
832+
esc_html( $this->get_humman_readable_time_diff( $item['item_date'] ) )
833+
);
834+
++$count;
835+
}
836+
$content .= '</ul>';
837+
echo wp_kses(
838+
$content,
839+
array(
840+
'ul' => array(
841+
'class' => array(),
842+
),
843+
'li' => array(
844+
'class' => array(),
845+
),
846+
'a' => array(
847+
'href' => array(),
848+
'target' => array(),
849+
),
850+
'time' => array(
851+
'datetime' => array(),
852+
'content' => array(),
853+
),
854+
'br' => array(),
855+
)
856+
);
857+
echo '</div>';
858+
}
859+
860+
/**
861+
* Get human readable time difference.
862+
*
863+
* @param int $item_publish_time The item publish time.
864+
*
865+
* @return string
866+
*/
867+
private function get_humman_readable_time_diff( $item_publish_time ) {
868+
$array = current_datetime();
869+
$localtime = $array->getTimestamp() + $array->getOffset();
870+
871+
return sprintf(
872+
// translators: %s is the time difference.
873+
__( '%s ago', 'feedzy-rss-feeds' ),
874+
human_time_diff( $item_publish_time, $localtime )
875+
);
876+
}
877+
759878
/**
760879
* Utility method to save metabox data to
761880
* custom post type.
@@ -841,6 +960,13 @@ public function feedzy_category_columns( $columns ) {
841960
$columns['actions'] = __( 'Actions', 'feedzy-rss-feeds' );
842961
}
843962

963+
$new_columns = $this->array_insert_before( 'slug', $columns, 'source', __( 'Source', 'feedzy-rss-feeds' ) );
964+
if ( $new_columns ) {
965+
$columns = $new_columns;
966+
} else {
967+
$columns['Source'] = __( 'source', 'feedzy-rss-feeds' );
968+
}
969+
844970
return $columns;
845971
}
846972

@@ -885,6 +1011,33 @@ public function manage_feedzy_category_columns( $column, $post_id ) {
8851011
case 'actions':
8861012
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' ) ) );
8871013
break;
1014+
case 'source':
1015+
$src = get_post_meta( $post_id, 'feedzy_category_feed', true );
1016+
if ( empty( $src ) ) {
1017+
$src = __( 'No Source Configured', 'feedzy-rss-feeds' );
1018+
} else {
1019+
$urls = $this->normalize_urls( $src );
1020+
$src = '';
1021+
if ( is_array( $urls ) ) {
1022+
1023+
foreach ( $urls as $key => $url ) {
1024+
$too_long = 130;
1025+
if ( strlen( $src ) > $too_long ) {
1026+
$src .= '...';
1027+
break;
1028+
} else {
1029+
$src .= '<a href="' . $url . '" target="_blank" title="' . __( 'Click to view', 'feedzy-rss-feeds' ) . '">' . $url . '</a>';
1030+
if ( count( $urls ) > $key + 1 ) {
1031+
$src .= ', ';
1032+
}
1033+
}
1034+
}
1035+
} else {
1036+
$src .= '<a href="' . esc_url( $urls ) . '" target="_blank" title="' . __( 'Click to view', 'feedzy-rss-feeds' ) . '">' . esc_html( $urls ) . '</a>';
1037+
}
1038+
}
1039+
echo wp_kses_post( $src );
1040+
break;
8881041
default:
8891042
break;
8901043
}
@@ -1477,6 +1630,23 @@ public function ajax() {
14771630
}
14781631
wp_send_json_success( array( 'invalid' => count( $invalid ) ) );
14791632
break;
1633+
case 'validate_feeds_group':
1634+
$feeds = isset( $_POST['feeds'] ) ? sanitize_text_field( wp_unslash( $_POST['feeds'] ) ) : '';
1635+
if ( empty( $feeds ) ) {
1636+
wp_send_json_error( __( 'No feeds provided for validation.', 'feedzy-rss-feeds' ) );
1637+
}
1638+
$feeds = $this->normalize_urls( $feeds );
1639+
if ( ! is_array( $feeds ) ) {
1640+
$feeds = array( $feeds );
1641+
}
1642+
$valid = $this->get_valid_source_urls( $feeds, '1_mins', false );
1643+
$invalid = array_diff( $feeds, $valid );
1644+
wp_send_json_success(
1645+
array(
1646+
'valid' => $valid,
1647+
'invalid' => $invalid,
1648+
)
1649+
);
14801650
}
14811651
}
14821652

includes/feedzy-rss-feeds-activator.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,35 @@ 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+
$feed_groups = 'https://themeisle.com/blog/feed/, https://wptavern.com/feed/, https://www.wpbeginner.com/feed/, https://wpshout.com/feed/, https://planet.wordpress.org/feed/';
86+
87+
add_post_meta( $news_group, 'feedzy_category_feed', $feed_groups );
88+
89+
update_option( '_feedzy_news_group_id', $news_group );
6090
}
6191
}

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: 35 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,38 @@
3334
});
3435
}
3536

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

0 commit comments

Comments
 (0)