Skip to content

Release/3.15.0-alpha.2 - Add episode list enhancements: cards layout, colors, pagination styles#888

Merged
zahardev merged 8 commits intodevelopfrom
release/3.15.0
Apr 1, 2026
Merged

Release/3.15.0-alpha.2 - Add episode list enhancements: cards layout, colors, pagination styles#888
zahardev merged 8 commits intodevelopfrom
release/3.15.0

Conversation

@zahardev
Copy link
Copy Markdown
Collaborator

@zahardev zahardev commented Apr 1, 2026

Title: Add episode list enhancements: cards layout, colors, pagination styles

Summary

  • Cards layout mode (Version 3.9.0.alpha #833): New layout="cards" with clickable modes (button, card, title), image+title header row, full-width image support for image_size="full", "Listen Now" button, card hover effects, compact player in 2-column cards
  • Color settings (Version 3.9.0.alpha #833): Title, text, link, card background, button color/background, pagination link, pagination active — all via CSS variables and Gutenberg PanelColorSettings (theme palette aware). Text color scoped to content elements only to avoid link inheritance issues
  • Pagination styles (Version 3.9.0.alpha #833): Configurable simple (prev/next) or full (numbered) pagination with dedicated color settings. Backward compatible — existing blocks keep simple, new blocks default to full via block variation
  • CSS scoping (Version 3.9.0.alpha #833): Unique instance class per render (ssp-el-N) prevents style collision when multiple shortcodes appear on the same page
  • Shortcode defaults (Version 3.9.0.alpha #833): Aligned with archive page — display_player=true, display_excerpt=true, display_image=false, title_size=24, image_size=medium
  • Block defaults (Version 3.9.0.alpha #833): New blocks get medium image size via block variation; existing blocks keep full (Gutenberg does not serialize default attribute values)
  • Fix (default) label appearing twice in Publishing tab (Version 3.10.0-alpha #836)

Summary by CodeRabbit

  • New Features

    • Card-based layout option for podcast lists with enhanced visual design
    • Full pagination styling with customizable page numbers and colors
    • Color customization controls for titles, text, links, buttons, and pagination
    • Configurable click behavior (button, card, or title)
    • Custom button text support
    • Enhanced editor controls for layout and styling options
  • Changes

    • Updated default episode display settings (player and excerpts now shown by default; featured image hidden)
    • Archive page title changed to "Episode List"

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 1, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0e914078-8b59-4bdc-a595-86c8117fad0f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR extends the podcast-list Gutenberg block and shortcode with configurable pagination types, layout modes (list/cards), clickable behaviors, color customization, and responsive styling. It migrates CSS variables from global scope to per-instance scope and restructures template rendering to support card-based layouts.

Changes

Cohort / File(s) Summary
CSS Styling Overhaul
assets/css/blocks/podcast-list.css, src/scss/podcast-list.scss, assets/css/block-editor-styles.css
Migrated CSS custom properties from :root global scope to instance-scoped .ssp-podcast-list variables using --ssp-episode-list-* naming. Added comprehensive pagination styling (simple and full modes) with color/hover states. Introduced new .ssp-podcast-list--cards modifier for card-based layout (background, radius, shadow, clickable overlays) and responsive .ssp-podcast-list--col-2 compact-player overrides. Disabled pointer events for links/buttons in podcast-list wrapper.
Block Registration & Editor Controls
php/classes/integrations/blocks/class-podcast-list-block.php, src/index.js, src/components/EditPodcastList.js
Extended Gutenberg block attributes with paginationType, layout, clickable, buttonText, and color fields (titleColor, textColor, linkColor, cardBackground, buttonColor, buttonBackground, paginationColor, paginationActiveColor). Added block variation with paginationType: 'full' default. Introduced conditional editor controls: cards-specific options shown/hidden based on layout selection; color picker panel always visible with card-specific fields toggled per layout; constrained column count max from 6 to 2.
Presenter & Rendering Logic
php/classes/presenters/class-episode-list-presenter.php, templates/blocks/podcast-list.php
Added validated paginationType (simple/full) attribute handling; updated paginate() method to accept optional pagination_type parameter controlling link filtering. Enhanced prepare_template_args() to pass layout (list/cards), clickable (button/card/title), button text, and sanitized color values to template. Restructured template rendering: replaced hardcoded title styling with conditional .ssp-episode-title markup; added cards layout path with optional full-header image, title linking, clickable overlay, and "listen now" button; instance-scoped CSS variables replace :root definitions; pagination output conditional on non-empty array.
Shortcode Attribute Expansion
php/classes/shortcodes/class-episode-list.php
Extended ATTRIBUTE_MAP with new pagination and layout-related shortcode attributes (pagination, layout, title_color, text_color, link_color, card_background, button_color, button_background, pagination_color, pagination_active_color, clickable, button_text). Updated default values: display_player and display_excerpt now true, display_image now false, image_size changed to medium, title_size increased to 24. Pagination defaults to full, layout to list, clickable to button.
Archive & Settings Handlers
php/classes/handlers/class-archive-page-handler.php, php/classes/handlers/class-settings-handler.php
Changed archive page creation title from 'Podcast' to 'Episode List'. Refactored get_podcasts_list() to compute default series name inline via array_map() instead of mutating source podcast objects, improving immutability.
Tests & CI
tests/WPUnit/EpisodeListShortcodeTest.php, tests/WPUnit/PodcastListBlockTest.php, tests/WPUnit/SettingsHandlerTest.php, tests/WPUnit/ArchivePageTest.php, tests/WPUnit/FeedControllerTest.php, .github/workflows/run_tests.yml
Added new SettingsHandlerTest class verifying get_podcasts_list() includes default podcast label and doesn't mutate term names. Updated EpisodeListShortcodeTest to normalize render output (strip instance styles, blank volatile IDs) and align presenter defaults with new feature parameters. Updated PodcastListBlockTest CSS variable assertions to reflect --ssp-episode-list-* naming and changed pagination presence expectations. Added request-state reset in ArchivePageTest::tearDown(). Fixed FeedControllerTest atom:link assertion. Updated CI PHP version from 8.1 to 8.2.
Version Bump
seriously-simple-podcasting.php
Incremented plugin version from 3.15.0-alpha to 3.15.0-alpha.2 in both file header and SSP_VERSION constant.

Sequence Diagram

sequenceDiagram
    participant Editor as Block Editor (JS)
    participant Block as Block Registry
    participant Handler as Podcast_List_Block Handler
    participant Presenter as Episode_List_Presenter
    participant Template as podcast-list.php Template

    Editor->>Block: registerBlockType with new attributes<br/>(layout, paginationType, colors)
    Block->>Handler: render_callback triggered with attributes
    Handler->>Presenter: render(attributes)
    Presenter->>Presenter: validate layout & paginationType
    Presenter->>Presenter: prepare_template_args()<br/>(format colors, determine clickable behavior)
    Presenter->>Presenter: paginate(pagination_type)
    Presenter-->>Template: pass template args
    Template->>Template: generate instance CSS variables
    Template->>Template: conditional render<br/>(cards layout vs list)
    Template->>Template: render pagination<br/>(simple or full mode)
    Template-->>Editor: HTML output with<br/>instance-scoped styles
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Version 3.14.0 #875: Introduced the original podcast-list Gutenberg block; this PR significantly extends its attribute schema, presenter logic, and template rendering.
  • Version 3.15.0 #887: Modified Archive_Page_Handler to create podcast archive pages; this PR changes the page title argument in that handler's find_or_create_podcast_page() method.
  • Release/3.14.3 #880: Modified templates/blocks/podcast-list.php for title output sanitization; this PR restructures the entire template with new cards layout and conditional rendering logic.

Poem

🐰 Hop along through cards so bright,
Instance colors, styled just right,
Pagination full or simple mode,
Down the podcast-list code road,
Listen buttons, clickable cheer,
Responsive layouts, crisp and clear! 🎙️

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: adding a cards layout, color settings, and pagination style enhancements to the episode list block.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/3.15.0

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
src/components/EditPodcastList.js (1)

241-247: Consider using the localized default for Button Text fallback.

The fallback 'Listen Now' is a hardcoded English string. While the PHP block attribute provides a localized default, if buttonText is undefined in the editor, this hardcoded fallback will display.

♻️ Suggested improvement
 {isCards && <PanelRow>
 	<TextControl
 		label={__('Button Text', 'seriously-simple-podcasting')}
-		value={buttonText || 'Listen Now'}
+		value={buttonText || __('Listen Now', 'seriously-simple-podcasting')}
 		onChange={(buttonText) => setAttributes({buttonText})}
 	/>
 </PanelRow>}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/EditPodcastList.js` around lines 241 - 247, The TextControl
fallback uses a hardcoded English string ('Listen Now'); change it to use the
localized default instead: read the localized default provided by the block
attributes (or use the i18n __() call) and use that as the fallback for value in
the TextControl inside the isCards conditional — update the TextControl usage
that references buttonText and setAttributes({buttonText}) so it uses something
like (buttonText || localizedDefaultButtonText) or (buttonText || __('Listen
Now', 'seriously-simple-podcasting')) to ensure the fallback is localized.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/scss/podcast-list.scss`:
- Around line 43-55: The active pagination styles (.current and
a.page-numbers:hover) hardcode white text which breaks contrast for light
user-controlled active backgrounds; change the color declarations to use a new
CSS variable (e.g. --ssp-episode-list-pagination-active-foreground) with a safe
fallback (currently `#fff`) and apply it in both .current and a.page-numbers:hover
so text color is configurable; update the stylesheet references to use
var(--ssp-episode-list-pagination-active-foreground, `#fff`) and ensure the new
variable is exposed/wired in the template/editor configuration.
- Around line 242-287: Replace deprecated grid-gap with the modern gap property
in the SCSS selectors where it's used: change grid-gap to gap in .castos-player
.player__main, .castos-player .play-progress, and .castos-player .playback
.playback__controls; then rebuild the compiled stylesheet
(assets/css/blocks/podcast-list.css) so the updated gap rules take effect.

In `@templates/blocks/podcast-list.php`:
- Around line 94-125: The full-card overlay anchor (ssp-episode-card-link,
controlled by $is_card_clickable) is blocking interactive descendants like the
player ($player, $is_player_below) and links in the excerpt
(get_the_excerpt())—either stop rendering the overlay when interactive content
is present (e.g. if $player is truthy or excerpt contains anchors) or ensure
those descendants are placed in a positioned container with higher stacking
context (give the player/excerpt wrapper a position and higher z-index than
ssp-episode-card-link); update the conditional around the overlay or wrap the
player/excerpt output (in the ssp-episode-card-body block) so they sit above the
overlay.
- Around line 39-41: The branch that appends the modifier class
'ssp-podcast-list--col-2' currently uses the condition "$columns_per_row >= 2"
which incorrectly marks 3- and 4-column layouts as two-column; change the
condition in templates/blocks/podcast-list.php so that $wrapper_class only gets
'ssp-podcast-list--col-2' when $columns_per_row == 2 (i.e., exactly two
columns), leaving other column counts to keep their correct classes.
- Around line 33-36: The current logic makes cards "title-click" mode remove the
Listen button but the only anchor is rendered inside if ( $show_title ), so when
$show_title is false the card has no navigation target; update the conditional
setup after computing $is_title_link to detect when $is_title_link && !
$show_title and in that case fallback to a real card-level link (e.g., force
$is_card_clickable = true or set $show_listen_btn = true) so the card still has
a navigation target; ensure the rendering code that expects an anchor (the block
guarded by if ( $show_title )) is adjusted or an alternative anchor is emitted
when $is_card_clickable is true.

---

Nitpick comments:
In `@src/components/EditPodcastList.js`:
- Around line 241-247: The TextControl fallback uses a hardcoded English string
('Listen Now'); change it to use the localized default instead: read the
localized default provided by the block attributes (or use the i18n __() call)
and use that as the fallback for value in the TextControl inside the isCards
conditional — update the TextControl usage that references buttonText and
setAttributes({buttonText}) so it uses something like (buttonText ||
localizedDefaultButtonText) or (buttonText || __('Listen Now',
'seriously-simple-podcasting')) to ensure the fallback is localized.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 686aa21b-359a-4796-93e8-bf4bac09449e

📥 Commits

Reviewing files that changed from the base of the PR and between 20c358d and 7c52ea6.

📒 Files selected for processing (14)
  • assets/css/block-editor-styles.css
  • assets/css/blocks/podcast-list.css
  • php/classes/handlers/class-archive-page-handler.php
  • php/classes/handlers/class-settings-handler.php
  • php/classes/integrations/blocks/class-podcast-list-block.php
  • php/classes/presenters/class-episode-list-presenter.php
  • php/classes/shortcodes/class-episode-list.php
  • src/components/EditPodcastList.js
  • src/index.js
  • src/scss/podcast-list.scss
  • templates/blocks/podcast-list.php
  • tests/WPUnit/EpisodeListShortcodeTest.php
  • tests/WPUnit/PodcastListBlockTest.php
  • tests/WPUnit/SettingsHandlerTest.php

Comment thread src/scss/podcast-list.scss
Comment thread src/scss/podcast-list.scss
Comment thread templates/blocks/podcast-list.php Outdated
Comment thread templates/blocks/podcast-list.php
Comment thread templates/blocks/podcast-list.php
@zahardev
Copy link
Copy Markdown
Collaborator Author

zahardev commented Apr 1, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 1, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
templates/blocks/podcast-list.php (1)

39-41: ⚠️ Potential issue | 🟠 Major

Only add ssp-podcast-list--col-2 for exactly two columns.

This template is shared with the shortcode path, and tests/WPUnit/EpisodeListShortcodeTest.php Line 169 still treats columns="3" as valid input. In layout="cards", >= 2 will tag that render as --col-2 and enable the two-column compact-player overrides from src/scss/podcast-list.scss Lines 241-300.

Suggested fix
-	if ( $columns_per_row >= 2 ) {
+	if ( 2 === (int) $columns_per_row ) {
		$wrapper_class .= ' ssp-podcast-list--col-2';
	}
Based on learnings: `src/components/EditPodcastList.js` caps the block editor control at 2 columns, but that safeguard does not apply to shortcode input.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/blocks/podcast-list.php` around lines 39 - 41, The template
currently adds the CSS class 'ssp-podcast-list--col-2' whenever $columns_per_row
>= 2, which wrongly applies two-column styles for >2 columns (affecting
shortcode usage); update the conditional around $wrapper_class so it only
appends 'ssp-podcast-list--col-2' when $columns_per_row === 2 (check the
$columns_per_row variable in the podcast-list template and change the >= 2 check
to a strict equality), leaving all other logic intact so three+ columns do not
get the two-column compact-player overrides.
🧹 Nitpick comments (1)
templates/blocks/podcast-list.php (1)

131-132: Let the CTA label own its arrow.

$button_text is already the customizable/translatable label, but appending here forces the glyph onto every custom string and makes RTL/localized output harder to control. Put the arrow in the default translated label or render it in CSS instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@templates/blocks/podcast-list.php` around lines 131 - 132, The template
currently appends a hardcoded arrow to the CTA by echoing $button_text followed
by “→”; remove the glyph from the template so the label alone is output (i.e.,
change the echo to only render esc_html( $button_text ) in the
.ssp-listen-now-button-content span), then put the arrow into the default
translated label where appropriate or add it via CSS (for example using
.ssp-listen-now-button-content::after) so RTL/localized control remains with the
translation/CSS rather than the template.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/scss/podcast-list.scss`:
- Around line 1-8: The committed SCSS now defines instance-scoped variables on
.ssp-podcast-list (e.g., --ssp-episode-list-title-size,
--ssp-episode-list-article-margin-bottom, --ssp-episode-list-gap,
--ssp-episode-list-cols), but the built asset
assets/css/blocks/podcast-list.min.css still contains the old :root
--ssp-podcast-list-* variables; rebuild the block CSS bundle (run the project's
CSS build task) so the compiled podcast-list.min.css reflects the new
.ssp-podcast-list variable declarations and then commit the regenerated asset.

---

Duplicate comments:
In `@templates/blocks/podcast-list.php`:
- Around line 39-41: The template currently adds the CSS class
'ssp-podcast-list--col-2' whenever $columns_per_row >= 2, which wrongly applies
two-column styles for >2 columns (affecting shortcode usage); update the
conditional around $wrapper_class so it only appends 'ssp-podcast-list--col-2'
when $columns_per_row === 2 (check the $columns_per_row variable in the
podcast-list template and change the >= 2 check to a strict equality), leaving
all other logic intact so three+ columns do not get the two-column
compact-player overrides.

---

Nitpick comments:
In `@templates/blocks/podcast-list.php`:
- Around line 131-132: The template currently appends a hardcoded arrow to the
CTA by echoing $button_text followed by “→”; remove the glyph from the template
so the label alone is output (i.e., change the echo to only render esc_html(
$button_text ) in the .ssp-listen-now-button-content span), then put the arrow
into the default translated label where appropriate or add it via CSS (for
example using .ssp-listen-now-button-content::after) so RTL/localized control
remains with the translation/CSS rather than the template.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f5f586f0-0cc8-4bc1-856d-6409bbf82a51

📥 Commits

Reviewing files that changed from the base of the PR and between 7c52ea6 and a609198.

📒 Files selected for processing (7)
  • .github/workflows/run_tests.yml
  • seriously-simple-podcasting.php
  • src/scss/podcast-list.scss
  • templates/blocks/podcast-list.php
  • tests/WPUnit/ArchivePageTest.php
  • tests/WPUnit/EpisodeListShortcodeTest.php
  • tests/WPUnit/FeedControllerTest.php
✅ Files skipped from review due to trivial changes (2)
  • .github/workflows/run_tests.yml
  • seriously-simple-podcasting.php

Comment thread src/scss/podcast-list.scss
@zahardev zahardev merged commit 558a9d7 into develop Apr 1, 2026
2 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant