You've already forked wp-fedistream
feat: Replace Twig with native PHP templates
All checks were successful
Create Release Package / build-release (push) Successful in 55s
All checks were successful
Create Release Package / build-release (push) Successful in 55s
- Remove twig/twig dependency from composer.json - Convert all 25 Twig templates to native PHP templates - New render() method in Plugin.php using PHP include with output buffering - New render_partial() helper method for including partials - Templates support theme overrides via fedistream/ directory - Reduced plugin size by eliminating Twig and its dependencies Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
24
CHANGELOG.md
24
CHANGELOG.md
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.6.0] - 2026-02-02
|
||||
|
||||
### Changed
|
||||
|
||||
- **Replaced Twig with native PHP templates** - Major refactoring to remove external dependency
|
||||
- Removed `twig/twig` from composer.json dependencies
|
||||
- All 25 Twig templates converted to native PHP templates
|
||||
- New `render()` method in Plugin.php uses PHP include with output buffering
|
||||
- New `render_partial()` helper method for including partials from within templates
|
||||
- Templates support theme overrides via `fedistream/` directory in themes
|
||||
- Improved performance by eliminating Twig compilation overhead
|
||||
- Reduced plugin size by removing Twig and its dependencies (symfony/polyfill-ctype, symfony/polyfill-mbstring)
|
||||
|
||||
### Removed
|
||||
|
||||
- Twig template engine dependency
|
||||
- All `.twig` template files (replaced with `.php` equivalents)
|
||||
- Twig-related initialization code in Plugin.php
|
||||
|
||||
## [0.5.1] - 2026-02-02
|
||||
|
||||
### Added
|
||||
@@ -305,7 +324,10 @@ Initial release of WP FediStream - a WordPress plugin for streaming music over A
|
||||
|
||||
---
|
||||
|
||||
[Unreleased]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.4.9...HEAD
|
||||
[Unreleased]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.6.0...HEAD
|
||||
[0.6.0]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.5.1...v0.6.0
|
||||
[0.5.1]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.5.0...v0.5.1
|
||||
[0.5.0]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.4.9...v0.5.0
|
||||
[0.4.9]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.4.8...v0.4.9
|
||||
[0.4.8]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.4.7...v0.4.8
|
||||
[0.4.7]: https://src.bundespruefstelle.ch/magdev/wp-fedistream/compare/v0.4.6...v0.4.7
|
||||
|
||||
41
CLAUDE.md
41
CLAUDE.md
@@ -31,7 +31,7 @@ This project is proudly **"vibe-coded"** using Claude.AI - the entire codebase w
|
||||
- **Language:** PHP 8.3.x
|
||||
- **Framework:** Latest WordPress Plugin API
|
||||
- **E-commerce (optional):** WooCommerce 10.0+
|
||||
- **Template Engine:** Twig 3.0 (via Composer)
|
||||
- **Template Engine:** Native PHP templates (with theme override support)
|
||||
- **Communication Protocol:** ActivityPub
|
||||
- **Wordpress Base Theme** twentytwentyfive
|
||||
- **Frontend:** Vanilla JavaScript
|
||||
@@ -658,3 +658,42 @@ if (get_option('wp_fedistream_enable_prometheus', 0) && $this->is_prometheus_act
|
||||
- Metrics use simple COUNT queries for performance
|
||||
- ActivityPub followers limited to top 10 to avoid cardinality explosion
|
||||
- Default disabled (opt-in via Settings > Integrations)
|
||||
|
||||
### 2026-02-02 - Native PHP Templates v0.6.0
|
||||
|
||||
**Summary:** Removed Twig dependency and converted all templates to native PHP for improved performance and reduced dependencies.
|
||||
|
||||
**Changes:**
|
||||
|
||||
- Removed `twig/twig` from composer.json dependencies
|
||||
- Converted all 25 Twig templates to native PHP templates
|
||||
- Updated `Plugin.php` with new `render()` method using PHP include with output buffering
|
||||
- Added `render_partial()` helper method for including partials from within templates
|
||||
- Added `get_template_path()` method supporting theme overrides via `fedistream/` directory
|
||||
- Reduced plugin package size by removing Twig and its dependencies
|
||||
|
||||
**Files Modified:**
|
||||
|
||||
- `includes/Plugin.php` - Removed Twig initialization, new native PHP render methods
|
||||
- `includes/Frontend/template-wrapper.php` - Updated docblock
|
||||
- `composer.json` - Removed `twig/twig` dependency
|
||||
|
||||
**Templates Created (25 PHP files replacing Twig):**
|
||||
|
||||
- `templates/partials/` - card-artist.php, card-album.php, card-track.php, card-playlist.php
|
||||
- `templates/single/` - artist.php, album.php, track.php, playlist.php
|
||||
- `templates/archive/` - artist.php, album.php, track.php, playlist.php, taxonomy.php
|
||||
- `templates/shortcodes/` - artist.php, album.php, track.php, playlist.php, player.php, releases-grid.php, tracks-list.php, artists-grid.php
|
||||
- `templates/widgets/` - recent-releases.php, popular-tracks.php, featured-artist.php, now-playing.php
|
||||
|
||||
**Templates Deleted (25 Twig files):**
|
||||
|
||||
- All `.twig` files in templates directory
|
||||
|
||||
**Benefits:**
|
||||
|
||||
- No external template engine dependency
|
||||
- Improved performance (no Twig compilation)
|
||||
- Native WordPress template overriding support
|
||||
- Smaller plugin package size
|
||||
- Simpler debugging with standard PHP
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
Stream music over ActivityPub - Build your own music streaming platform for Musicians and Labels.
|
||||
|
||||
[](CHANGELOG.md)
|
||||
[](CHANGELOG.md)
|
||||
[](https://php.net)
|
||||
[](https://wordpress.org)
|
||||
[](https://www.gnu.org/licenses/gpl-2.0.html)
|
||||
@@ -146,7 +146,7 @@ wp-fedistream/
|
||||
│ ├── Plugin.php # Main plugin singleton
|
||||
│ └── Installer.php # Activation/deactivation
|
||||
├── languages/ # Translation files
|
||||
├── templates/ # Twig templates
|
||||
├── templates/ # PHP templates
|
||||
├── vendor/ # Composer dependencies
|
||||
├── CHANGELOG.md # Version history
|
||||
└── wp-fedistream.php # Plugin entry point
|
||||
|
||||
@@ -22,8 +22,7 @@
|
||||
],
|
||||
"require": {
|
||||
"php": ">=8.3",
|
||||
"magdev/wc-licensed-product-client": "^0.2",
|
||||
"twig/twig": "^3.0"
|
||||
"magdev/wc-licensed-product-client": "^0.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^10.0",
|
||||
|
||||
249
composer.lock
generated
249
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "0c8153ac31232ffe7f0af117cec865b4",
|
||||
"content-hash": "19d851431c9b602615e115746e3cbd9d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "magdev/wc-licensed-product-client",
|
||||
@@ -558,174 +558,6 @@
|
||||
],
|
||||
"time": "2025-04-29T11:18:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gert de Pagter",
|
||||
"email": "BackEndTea@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for ctype functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"ctype",
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.33.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493",
|
||||
"reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-iconv": "*",
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"provide": {
|
||||
"ext-mbstring": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Mbstring\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for the Mbstring extension",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"mbstring",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/nicolas-grekas",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-23T08:48:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php83",
|
||||
"version": "v1.33.0",
|
||||
@@ -892,85 +724,6 @@
|
||||
}
|
||||
],
|
||||
"time": "2025-07-15T11:30:57+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.23.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9",
|
||||
"reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1.0",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-ctype": "^1.8",
|
||||
"symfony/polyfill-mbstring": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"psr/container": "^1.0|^2.0",
|
||||
"symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/Resources/core.php",
|
||||
"src/Resources/debug.php",
|
||||
"src/Resources/escaper.php",
|
||||
"src/Resources/string_loader.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Twig\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Twig Team",
|
||||
"role": "Contributors"
|
||||
},
|
||||
{
|
||||
"name": "Armin Ronacher",
|
||||
"email": "armin.ronacher@active-4.com",
|
||||
"role": "Project Founder"
|
||||
}
|
||||
],
|
||||
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||
"homepage": "https://twig.symfony.com",
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.23.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2026-01-23T21:00:41+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/**
|
||||
* Template wrapper for FediStream Twig templates.
|
||||
* Template wrapper for FediStream PHP templates.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*/
|
||||
|
||||
@@ -24,7 +24,7 @@ use WP_FediStream\PostTypes\Track;
|
||||
use WP_FediStream\PostTypes\Playlist;
|
||||
use WP_FediStream\Taxonomies\Genre;
|
||||
use WP_FediStream\Taxonomies\Mood;
|
||||
use WP_FediStream\Taxonomies\License;
|
||||
use WP_FediStream\Taxonomies\License as LicenseTaxonomy;
|
||||
use WP_FediStream\User\Library as UserLibrary;
|
||||
use WP_FediStream\User\LibraryPage;
|
||||
use WP_FediStream\User\Notifications;
|
||||
@@ -50,21 +50,14 @@ final class Plugin {
|
||||
private static ?Plugin $instance = null;
|
||||
|
||||
/**
|
||||
* Twig environment instance.
|
||||
*
|
||||
* @var \Twig\Environment|null
|
||||
*/
|
||||
private ?\Twig\Environment $twig = null;
|
||||
|
||||
/**
|
||||
* Current Twig render depth to prevent infinite recursion.
|
||||
* Current render depth to prevent infinite recursion.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private static int $render_depth = 0;
|
||||
|
||||
/**
|
||||
* Maximum allowed Twig render depth.
|
||||
* Maximum allowed render depth.
|
||||
* Set to 2 to allow one level of nested includes but prevent deeper recursion.
|
||||
*
|
||||
* @var int
|
||||
@@ -109,7 +102,6 @@ final class Plugin {
|
||||
* Private constructor to enforce singleton pattern.
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->init_twig();
|
||||
$this->init_components();
|
||||
$this->init_hooks();
|
||||
$this->load_textdomain();
|
||||
@@ -132,32 +124,6 @@ final class Plugin {
|
||||
throw new \Exception( 'Cannot unserialize singleton' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Twig template engine.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function init_twig(): void {
|
||||
$loader = new \Twig\Loader\FilesystemLoader( WP_FEDISTREAM_PATH . 'templates' );
|
||||
|
||||
$this->twig = new \Twig\Environment(
|
||||
$loader,
|
||||
array(
|
||||
'cache' => WP_FEDISTREAM_PATH . 'cache/twig',
|
||||
'auto_reload' => WP_DEBUG,
|
||||
)
|
||||
);
|
||||
|
||||
// Add WordPress escaping functions.
|
||||
$this->twig->addFunction( new \Twig\TwigFunction( 'esc_html', 'esc_html' ) );
|
||||
$this->twig->addFunction( new \Twig\TwigFunction( 'esc_attr', 'esc_attr' ) );
|
||||
$this->twig->addFunction( new \Twig\TwigFunction( 'esc_url', 'esc_url' ) );
|
||||
$this->twig->addFunction( new \Twig\TwigFunction( 'esc_js', 'esc_js' ) );
|
||||
$this->twig->addFunction( new \Twig\TwigFunction( 'wp_nonce_field', 'wp_nonce_field', array( 'is_safe' => array( 'html' ) ) ) );
|
||||
$this->twig->addFunction( new \Twig\TwigFunction( '__', '__' ) );
|
||||
$this->twig->addFunction( new \Twig\TwigFunction( '_e', '_e' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize plugin components.
|
||||
*
|
||||
@@ -173,7 +139,7 @@ final class Plugin {
|
||||
// Initialize taxonomies.
|
||||
$this->taxonomies['genre'] = new Genre();
|
||||
$this->taxonomies['mood'] = new Mood();
|
||||
$this->taxonomies['license'] = new License();
|
||||
$this->taxonomies['license'] = new LicenseTaxonomy();
|
||||
|
||||
// Initialize admin components.
|
||||
if ( is_admin() ) {
|
||||
@@ -876,19 +842,30 @@ final class Plugin {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Twig environment.
|
||||
* Get the path to a template file.
|
||||
*
|
||||
* @return \Twig\Environment
|
||||
* Checks theme for override first, then falls back to plugin template.
|
||||
*
|
||||
* @param string $template Template name (without extension).
|
||||
* @return string Full path to template file.
|
||||
*/
|
||||
public function get_twig(): \Twig\Environment {
|
||||
return $this->twig;
|
||||
public function get_template_path( string $template ): string {
|
||||
// Check theme for override.
|
||||
$theme_template = locate_template( "fedistream/{$template}.php" );
|
||||
if ( $theme_template ) {
|
||||
return $theme_template;
|
||||
}
|
||||
|
||||
// Use plugin template.
|
||||
return WP_FEDISTREAM_PATH . "templates/{$template}.php";
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a Twig template.
|
||||
* Render a PHP template.
|
||||
*
|
||||
* @param string $template Template name (without .twig extension).
|
||||
* @param string $template Template name (without extension).
|
||||
* @param array $context Template context variables.
|
||||
* @param bool $is_main_template Whether this is the main page template.
|
||||
* @return string Rendered template.
|
||||
*/
|
||||
public function render( string $template, array $context = array(), bool $is_main_template = false ): string {
|
||||
@@ -897,7 +874,7 @@ final class Plugin {
|
||||
return '<!-- FediStream: blocked during main template render -->';
|
||||
}
|
||||
|
||||
// Prevent infinite recursion in Twig rendering.
|
||||
// Prevent infinite recursion in rendering.
|
||||
if ( self::$render_depth >= self::MAX_RENDER_DEPTH ) {
|
||||
return '<!-- FediStream: render depth exceeded -->';
|
||||
}
|
||||
@@ -911,7 +888,24 @@ final class Plugin {
|
||||
++self::$render_depth;
|
||||
|
||||
try {
|
||||
$result = $this->twig->render( $template . '.twig', $context );
|
||||
$template_path = $this->get_template_path( $template );
|
||||
|
||||
if ( ! file_exists( $template_path ) ) {
|
||||
throw new \Exception( "Template not found: {$template}" );
|
||||
}
|
||||
|
||||
// Extract context variables for use in template.
|
||||
// phpcs:ignore WordPress.PHP.DontExtract.extract_extract
|
||||
extract( $context, EXTR_SKIP );
|
||||
|
||||
// Start output buffering.
|
||||
ob_start();
|
||||
|
||||
// Include the template.
|
||||
include $template_path;
|
||||
|
||||
// Get the rendered content.
|
||||
$result = ob_get_clean();
|
||||
} finally {
|
||||
--self::$render_depth;
|
||||
if ( $is_main_template ) {
|
||||
@@ -922,6 +916,17 @@ final class Plugin {
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a partial template (helper for use within templates).
|
||||
*
|
||||
* @param string $partial Partial template name (without extension).
|
||||
* @param array $context Template context variables.
|
||||
* @return string Rendered partial.
|
||||
*/
|
||||
public function render_partial( string $partial, array $context = array() ): string {
|
||||
return $this->render( $partial, $context, false );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a post type instance.
|
||||
*
|
||||
|
||||
49
templates/archive/album.php
Normal file
49
templates/archive/album.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Album archive template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $posts Array of album data.
|
||||
* @var string $archive_title Archive title.
|
||||
* @var string $archive_description Archive description.
|
||||
* @var array $pagination Pagination data.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = \WP_FediStream\Plugin::get_instance();
|
||||
?>
|
||||
<div class="fedistream-archive fedistream-archive--albums">
|
||||
<header class="fedistream-archive__header">
|
||||
<h1 class="fedistream-archive__title"><?php esc_html_e( 'Albums', 'wp-fedistream' ); ?></h1>
|
||||
<?php if ( ! empty( $archive_description ) ) : ?>
|
||||
<div class="fedistream-archive__description"><?php echo wp_kses_post( $archive_description ); ?></div>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<?php if ( ! empty( $posts ) && is_array( $posts ) ) : ?>
|
||||
<div class="fedistream-grid fedistream-grid--albums">
|
||||
<?php foreach ( $posts as $post ) : ?>
|
||||
<?php echo $plugin->render_partial( 'partials/card-album', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( ! empty( $pagination['links'] ) ) : ?>
|
||||
<nav class="fedistream-pagination">
|
||||
<?php
|
||||
foreach ( $pagination['links'] as $link ) {
|
||||
echo $link; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<div class="fedistream-empty">
|
||||
<p><?php esc_html_e( 'No albums found.', 'wp-fedistream' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,27 +0,0 @@
|
||||
{# Album archive template #}
|
||||
<div class="fedistream-archive fedistream-archive--albums">
|
||||
<header class="fedistream-archive__header">
|
||||
<h1 class="fedistream-archive__title">{{ __('Albums', 'wp-fedistream') }}</h1>
|
||||
{% if archive_description %}
|
||||
<div class="fedistream-archive__description">{{ archive_description }}</div>
|
||||
{% endif %}
|
||||
</header>
|
||||
|
||||
{% if posts is not empty %}
|
||||
<div class="fedistream-grid fedistream-grid--albums">
|
||||
{% for post in posts %}
|
||||
{% include 'partials/card-album.twig' with { post: post } %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if pagination %}
|
||||
<nav class="fedistream-pagination">
|
||||
{{ pagination|raw }}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="fedistream-empty">
|
||||
<p>{{ __('No albums found.', 'wp-fedistream') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
49
templates/archive/artist.php
Normal file
49
templates/archive/artist.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Artist archive template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $posts Array of artist data.
|
||||
* @var string $archive_title Archive title.
|
||||
* @var string $archive_description Archive description.
|
||||
* @var array $pagination Pagination data.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = \WP_FediStream\Plugin::get_instance();
|
||||
?>
|
||||
<div class="fedistream-archive fedistream-archive--artists">
|
||||
<header class="fedistream-archive__header">
|
||||
<h1 class="fedistream-archive__title"><?php esc_html_e( 'Artists', 'wp-fedistream' ); ?></h1>
|
||||
<?php if ( ! empty( $archive_description ) ) : ?>
|
||||
<div class="fedistream-archive__description"><?php echo wp_kses_post( $archive_description ); ?></div>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<?php if ( ! empty( $posts ) && is_array( $posts ) ) : ?>
|
||||
<div class="fedistream-grid fedistream-grid--artists">
|
||||
<?php foreach ( $posts as $post ) : ?>
|
||||
<?php echo $plugin->render_partial( 'partials/card-artist', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( ! empty( $pagination['links'] ) ) : ?>
|
||||
<nav class="fedistream-pagination">
|
||||
<?php
|
||||
foreach ( $pagination['links'] as $link ) {
|
||||
echo $link; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<div class="fedistream-empty">
|
||||
<p><?php esc_html_e( 'No artists found.', 'wp-fedistream' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,27 +0,0 @@
|
||||
{# Artist archive template #}
|
||||
<div class="fedistream-archive fedistream-archive--artists">
|
||||
<header class="fedistream-archive__header">
|
||||
<h1 class="fedistream-archive__title">{{ __('Artists', 'wp-fedistream') }}</h1>
|
||||
{% if archive_description %}
|
||||
<div class="fedistream-archive__description">{{ archive_description }}</div>
|
||||
{% endif %}
|
||||
</header>
|
||||
|
||||
{% if posts is not empty %}
|
||||
<div class="fedistream-grid fedistream-grid--artists">
|
||||
{% for post in posts %}
|
||||
{% include 'partials/card-artist.twig' with { post: post } %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if pagination %}
|
||||
<nav class="fedistream-pagination">
|
||||
{{ pagination|raw }}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="fedistream-empty">
|
||||
<p>{{ __('No artists found.', 'wp-fedistream') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
49
templates/archive/playlist.php
Normal file
49
templates/archive/playlist.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Playlist archive template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $posts Array of playlist data.
|
||||
* @var string $archive_title Archive title.
|
||||
* @var string $archive_description Archive description.
|
||||
* @var array $pagination Pagination data.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = \WP_FediStream\Plugin::get_instance();
|
||||
?>
|
||||
<div class="fedistream-archive fedistream-archive--playlists">
|
||||
<header class="fedistream-archive__header">
|
||||
<h1 class="fedistream-archive__title"><?php esc_html_e( 'Playlists', 'wp-fedistream' ); ?></h1>
|
||||
<?php if ( ! empty( $archive_description ) ) : ?>
|
||||
<div class="fedistream-archive__description"><?php echo wp_kses_post( $archive_description ); ?></div>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<?php if ( ! empty( $posts ) && is_array( $posts ) ) : ?>
|
||||
<div class="fedistream-grid fedistream-grid--playlists">
|
||||
<?php foreach ( $posts as $post ) : ?>
|
||||
<?php echo $plugin->render_partial( 'partials/card-playlist', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( ! empty( $pagination['links'] ) ) : ?>
|
||||
<nav class="fedistream-pagination">
|
||||
<?php
|
||||
foreach ( $pagination['links'] as $link ) {
|
||||
echo $link; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<div class="fedistream-empty">
|
||||
<p><?php esc_html_e( 'No playlists found.', 'wp-fedistream' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,27 +0,0 @@
|
||||
{# Playlist archive template #}
|
||||
<div class="fedistream-archive fedistream-archive--playlists">
|
||||
<header class="fedistream-archive__header">
|
||||
<h1 class="fedistream-archive__title">{{ __('Playlists', 'wp-fedistream') }}</h1>
|
||||
{% if archive_description %}
|
||||
<div class="fedistream-archive__description">{{ archive_description }}</div>
|
||||
{% endif %}
|
||||
</header>
|
||||
|
||||
{% if posts is not empty %}
|
||||
<div class="fedistream-grid fedistream-grid--playlists">
|
||||
{% for post in posts %}
|
||||
{% include 'partials/card-playlist.twig' with { post: post } %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if pagination %}
|
||||
<nav class="fedistream-pagination">
|
||||
{{ pagination|raw }}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="fedistream-empty">
|
||||
<p>{{ __('No playlists found.', 'wp-fedistream') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
72
templates/archive/taxonomy.php
Normal file
72
templates/archive/taxonomy.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Taxonomy archive template (Genre, Mood).
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $posts Array of post data.
|
||||
* @var string $archive_title Archive title.
|
||||
* @var string $archive_description Archive description.
|
||||
* @var string $taxonomy_name Taxonomy name (Genre, Mood).
|
||||
* @var object $term Current term object.
|
||||
* @var array $pagination Pagination data.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = \WP_FediStream\Plugin::get_instance();
|
||||
?>
|
||||
<div class="fedistream-archive fedistream-archive--taxonomy">
|
||||
<header class="fedistream-archive__header">
|
||||
<h1 class="fedistream-archive__title">
|
||||
<?php if ( ! empty( $taxonomy_name ) ) : ?>
|
||||
<?php echo esc_html( $taxonomy_name ); ?>:
|
||||
<?php endif; ?>
|
||||
<?php echo esc_html( $archive_title ?? '' ); ?>
|
||||
</h1>
|
||||
<?php if ( ! empty( $archive_description ) ) : ?>
|
||||
<div class="fedistream-archive__description"><?php echo wp_kses_post( $archive_description ); ?></div>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<?php if ( ! empty( $posts ) && is_array( $posts ) ) : ?>
|
||||
<div class="fedistream-grid fedistream-grid--mixed">
|
||||
<?php foreach ( $posts as $post ) : ?>
|
||||
<?php
|
||||
$post_type = $post['post_type'] ?? '';
|
||||
switch ( $post_type ) {
|
||||
case 'fedistream_artist':
|
||||
echo $plugin->render_partial( 'partials/card-artist', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
break;
|
||||
case 'fedistream_album':
|
||||
echo $plugin->render_partial( 'partials/card-album', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
break;
|
||||
case 'fedistream_track':
|
||||
echo $plugin->render_partial( 'partials/card-track', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
break;
|
||||
case 'fedistream_playlist':
|
||||
echo $plugin->render_partial( 'partials/card-playlist', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
break;
|
||||
}
|
||||
?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( ! empty( $pagination['links'] ) ) : ?>
|
||||
<nav class="fedistream-pagination">
|
||||
<?php
|
||||
foreach ( $pagination['links'] as $link ) {
|
||||
echo $link; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<div class="fedistream-empty">
|
||||
<p><?php esc_html_e( 'No content found in this category.', 'wp-fedistream' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,37 +0,0 @@
|
||||
{# Taxonomy archive template (Genre, Mood) #}
|
||||
<div class="fedistream-archive fedistream-archive--taxonomy">
|
||||
<header class="fedistream-archive__header">
|
||||
<h1 class="fedistream-archive__title">
|
||||
{% if taxonomy_name %}{{ taxonomy_name }}: {% endif %}{{ term.name }}
|
||||
</h1>
|
||||
{% if term.description %}
|
||||
<div class="fedistream-archive__description">{{ term.description }}</div>
|
||||
{% endif %}
|
||||
</header>
|
||||
|
||||
{% if posts is not empty %}
|
||||
<div class="fedistream-grid fedistream-grid--mixed">
|
||||
{% for post in posts %}
|
||||
{% if post.post_type == 'fedistream_artist' %}
|
||||
{% include 'partials/card-artist.twig' with { post: post } %}
|
||||
{% elseif post.post_type == 'fedistream_album' %}
|
||||
{% include 'partials/card-album.twig' with { post: post } %}
|
||||
{% elseif post.post_type == 'fedistream_track' %}
|
||||
{% include 'partials/card-track.twig' with { post: post } %}
|
||||
{% elseif post.post_type == 'fedistream_playlist' %}
|
||||
{% include 'partials/card-playlist.twig' with { post: post } %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if pagination %}
|
||||
<nav class="fedistream-pagination">
|
||||
{{ pagination|raw }}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="fedistream-empty">
|
||||
<p>{{ __('No content found in this category.', 'wp-fedistream') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
49
templates/archive/track.php
Normal file
49
templates/archive/track.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
/**
|
||||
* Track archive template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $posts Array of track data.
|
||||
* @var string $archive_title Archive title.
|
||||
* @var string $archive_description Archive description.
|
||||
* @var array $pagination Pagination data.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = \WP_FediStream\Plugin::get_instance();
|
||||
?>
|
||||
<div class="fedistream-archive fedistream-archive--tracks">
|
||||
<header class="fedistream-archive__header">
|
||||
<h1 class="fedistream-archive__title"><?php esc_html_e( 'Tracks', 'wp-fedistream' ); ?></h1>
|
||||
<?php if ( ! empty( $archive_description ) ) : ?>
|
||||
<div class="fedistream-archive__description"><?php echo wp_kses_post( $archive_description ); ?></div>
|
||||
<?php endif; ?>
|
||||
</header>
|
||||
|
||||
<?php if ( ! empty( $posts ) && is_array( $posts ) ) : ?>
|
||||
<div class="fedistream-grid fedistream-grid--tracks">
|
||||
<?php foreach ( $posts as $post ) : ?>
|
||||
<?php echo $plugin->render_partial( 'partials/card-track', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
|
||||
<?php if ( ! empty( $pagination['links'] ) ) : ?>
|
||||
<nav class="fedistream-pagination">
|
||||
<?php
|
||||
foreach ( $pagination['links'] as $link ) {
|
||||
echo $link; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
}
|
||||
?>
|
||||
</nav>
|
||||
<?php endif; ?>
|
||||
<?php else : ?>
|
||||
<div class="fedistream-empty">
|
||||
<p><?php esc_html_e( 'No tracks found.', 'wp-fedistream' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,27 +0,0 @@
|
||||
{# Track archive template #}
|
||||
<div class="fedistream-archive fedistream-archive--tracks">
|
||||
<header class="fedistream-archive__header">
|
||||
<h1 class="fedistream-archive__title">{{ __('Tracks', 'wp-fedistream') }}</h1>
|
||||
{% if archive_description %}
|
||||
<div class="fedistream-archive__description">{{ archive_description }}</div>
|
||||
{% endif %}
|
||||
</header>
|
||||
|
||||
{% if posts is not empty %}
|
||||
<div class="fedistream-grid fedistream-grid--tracks">
|
||||
{% for post in posts %}
|
||||
{% include 'partials/card-track.twig' with { post: post } %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% if pagination %}
|
||||
<nav class="fedistream-pagination">
|
||||
{{ pagination|raw }}
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<div class="fedistream-empty">
|
||||
<p>{{ __('No tracks found.', 'wp-fedistream') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
50
templates/partials/card-album.php
Normal file
50
templates/partials/card-album.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Album card partial template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Album data array.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<article class="fedistream-card fedistream-card--album">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '' ); ?>" class="fedistream-card__link">
|
||||
<div class="fedistream-card__image fedistream-card__image--square">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" loading="lazy">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-card__placeholder fedistream-card__placeholder--album">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-card__content">
|
||||
<h3 class="fedistream-card__title"><?php echo esc_html( $post['title'] ?? '' ); ?></h3>
|
||||
<?php if ( ! empty( $post['artist_name'] ) ) : ?>
|
||||
<p class="fedistream-card__artist"><?php echo esc_html( $post['artist_name'] ); ?></p>
|
||||
<?php endif; ?>
|
||||
<p class="fedistream-card__meta">
|
||||
<span class="fedistream-card__type"><?php echo esc_html( $post['album_type_label'] ?? '' ); ?></span>
|
||||
<?php if ( ! empty( $post['release_year'] ) ) : ?>
|
||||
<span class="fedistream-card__year"><?php echo esc_html( $post['release_year'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<?php if ( ! empty( $post['total_tracks'] ) && $post['total_tracks'] > 0 ) : ?>
|
||||
<p class="fedistream-card__stats">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of tracks */
|
||||
esc_html( _n( '%d track', '%d tracks', $post['total_tracks'], 'wp-fedistream' ) ),
|
||||
(int) $post['total_tracks']
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
@@ -1,31 +0,0 @@
|
||||
{# Album card partial #}
|
||||
<article class="fedistream-card fedistream-card--album">
|
||||
<a href="{{ post.permalink }}" class="fedistream-card__link">
|
||||
<div class="fedistream-card__image fedistream-card__image--square">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" loading="lazy">
|
||||
{% else %}
|
||||
<div class="fedistream-card__placeholder fedistream-card__placeholder--album">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-card__content">
|
||||
<h3 class="fedistream-card__title">{{ post.title }}</h3>
|
||||
{% if post.artist_name %}
|
||||
<p class="fedistream-card__artist">{{ post.artist_name }}</p>
|
||||
{% endif %}
|
||||
<p class="fedistream-card__meta">
|
||||
<span class="fedistream-card__type">{{ post.album_type_label }}</span>
|
||||
{% if post.release_year %}
|
||||
<span class="fedistream-card__year">{{ post.release_year }}</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% if post.total_tracks > 0 %}
|
||||
<p class="fedistream-card__stats">
|
||||
{{ post.total_tracks }} {{ post.total_tracks == 1 ? 'track' : 'tracks' }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
47
templates/partials/card-artist.php
Normal file
47
templates/partials/card-artist.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Artist card partial template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Artist data array.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<article class="fedistream-card fedistream-card--artist">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '' ); ?>" class="fedistream-card__link">
|
||||
<div class="fedistream-card__image">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" loading="lazy">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-card__placeholder fedistream-card__placeholder--artist">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-card__content">
|
||||
<h3 class="fedistream-card__title"><?php echo esc_html( $post['title'] ?? '' ); ?></h3>
|
||||
<p class="fedistream-card__meta">
|
||||
<span class="fedistream-card__type"><?php echo esc_html( $post['artist_type_label'] ?? '' ); ?></span>
|
||||
<?php if ( ! empty( $post['location'] ) ) : ?>
|
||||
<span class="fedistream-card__location"><?php echo esc_html( $post['location'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
<?php if ( isset( $post['album_count'] ) && $post['album_count'] > 0 ) : ?>
|
||||
<p class="fedistream-card__stats">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of albums */
|
||||
esc_html( _n( '%d album', '%d albums', $post['album_count'], 'wp-fedistream' ) ),
|
||||
(int) $post['album_count']
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
@@ -1,28 +0,0 @@
|
||||
{# Artist card partial #}
|
||||
<article class="fedistream-card fedistream-card--artist">
|
||||
<a href="{{ post.permalink }}" class="fedistream-card__link">
|
||||
<div class="fedistream-card__image">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" loading="lazy">
|
||||
{% else %}
|
||||
<div class="fedistream-card__placeholder fedistream-card__placeholder--artist">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-card__content">
|
||||
<h3 class="fedistream-card__title">{{ post.title }}</h3>
|
||||
<p class="fedistream-card__meta">
|
||||
<span class="fedistream-card__type">{{ post.artist_type_label }}</span>
|
||||
{% if post.location %}
|
||||
<span class="fedistream-card__location">{{ post.location }}</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
{% if post.album_count is defined and post.album_count > 0 %}
|
||||
<p class="fedistream-card__stats">
|
||||
{{ post.album_count }} {{ post.album_count == 1 ? 'album' : 'albums' }}
|
||||
</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
54
templates/partials/card-playlist.php
Normal file
54
templates/partials/card-playlist.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Playlist card partial template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Playlist data array.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<article class="fedistream-card fedistream-card--playlist">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '' ); ?>" class="fedistream-card__link">
|
||||
<div class="fedistream-card__image fedistream-card__image--square">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" loading="lazy">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-card__placeholder fedistream-card__placeholder--playlist">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( isset( $post['visibility'] ) && 'private' === $post['visibility'] ) : ?>
|
||||
<span class="fedistream-card__badge fedistream-card__badge--private">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" width="12" height="12"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6z"/></svg>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-card__content">
|
||||
<h3 class="fedistream-card__title"><?php echo esc_html( $post['title'] ?? '' ); ?></h3>
|
||||
<?php if ( ! empty( $post['author'] ) ) : ?>
|
||||
<p class="fedistream-card__author"><?php echo esc_html( $post['author'] ); ?></p>
|
||||
<?php endif; ?>
|
||||
<p class="fedistream-card__meta">
|
||||
<?php if ( ! empty( $post['track_count'] ) ) : ?>
|
||||
<span class="fedistream-card__tracks">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of tracks */
|
||||
esc_html( _n( '%d track', '%d tracks', $post['track_count'], 'wp-fedistream' ) ),
|
||||
(int) $post['track_count']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-card__duration"><?php echo esc_html( $post['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
@@ -1,29 +0,0 @@
|
||||
{# Playlist card partial #}
|
||||
<article class="fedistream-card fedistream-card--playlist">
|
||||
<a href="{{ post.permalink }}" class="fedistream-card__link">
|
||||
<div class="fedistream-card__image fedistream-card__image--square">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" loading="lazy">
|
||||
{% else %}
|
||||
<div class="fedistream-card__placeholder fedistream-card__placeholder--playlist">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if post.visibility == 'private' %}
|
||||
<span class="fedistream-card__badge fedistream-card__badge--private">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" width="12" height="12"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6zm9 14H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"/></svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-card__content">
|
||||
<h3 class="fedistream-card__title">{{ post.title }}</h3>
|
||||
<p class="fedistream-card__author">{{ post.author }}</p>
|
||||
<p class="fedistream-card__meta">
|
||||
<span class="fedistream-card__count">{{ post.track_count }} {{ post.track_count == 1 ? 'track' : 'tracks' }}</span>
|
||||
{% if post.duration_formatted %}
|
||||
<span class="fedistream-card__duration">{{ post.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
56
templates/partials/card-track.php
Normal file
56
templates/partials/card-track.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
/**
|
||||
* Track card partial template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Track data array.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<article class="fedistream-card fedistream-card--track">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '' ); ?>" class="fedistream-card__link">
|
||||
<div class="fedistream-card__image fedistream-card__image--square">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" loading="lazy">
|
||||
<?php elseif ( ! empty( $post['album_artwork'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['album_artwork'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" loading="lazy">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-card__placeholder fedistream-card__placeholder--track">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['explicit'] ) ) : ?>
|
||||
<span class="fedistream-card__badge fedistream-card__badge--explicit">E</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-card__content">
|
||||
<h3 class="fedistream-card__title"><?php echo esc_html( $post['title'] ?? '' ); ?></h3>
|
||||
<?php if ( ! empty( $post['artists'] ) && is_array( $post['artists'] ) ) : ?>
|
||||
<p class="fedistream-card__artist">
|
||||
<?php
|
||||
$artist_names = array_map(
|
||||
function ( $artist ) {
|
||||
return esc_html( $artist['name'] ?? '' );
|
||||
},
|
||||
$post['artists']
|
||||
);
|
||||
echo implode( ', ', $artist_names ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<p class="fedistream-card__meta">
|
||||
<?php if ( ! empty( $post['album_title'] ) ) : ?>
|
||||
<span class="fedistream-card__album"><?php echo esc_html( $post['album_title'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-card__duration"><?php echo esc_html( $post['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
@@ -1,37 +0,0 @@
|
||||
{# Track card partial #}
|
||||
<article class="fedistream-card fedistream-card--track">
|
||||
<a href="{{ post.permalink }}" class="fedistream-card__link">
|
||||
<div class="fedistream-card__image fedistream-card__image--square">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" loading="lazy">
|
||||
{% elseif post.album_artwork %}
|
||||
<img src="{{ post.album_artwork }}" alt="{{ post.title|e('html_attr') }}" loading="lazy">
|
||||
{% else %}
|
||||
<div class="fedistream-card__placeholder fedistream-card__placeholder--track">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if post.explicit %}
|
||||
<span class="fedistream-card__badge fedistream-card__badge--explicit">E</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-card__content">
|
||||
<h3 class="fedistream-card__title">{{ post.title }}</h3>
|
||||
{% if post.artists %}
|
||||
<p class="fedistream-card__artist">
|
||||
{% for artist in post.artists %}
|
||||
{{ artist.name }}{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
<p class="fedistream-card__meta">
|
||||
{% if post.album_title %}
|
||||
<span class="fedistream-card__album">{{ post.album_title }}</span>
|
||||
{% endif %}
|
||||
{% if post.duration_formatted %}
|
||||
<span class="fedistream-card__duration">{{ post.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
</a>
|
||||
</article>
|
||||
89
templates/shortcodes/album.php
Normal file
89
templates/shortcodes/album.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* Album shortcode template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Album data array.
|
||||
* @var string $layout Layout style (full, card, compact).
|
||||
* @var bool $show_tracks Whether to show tracks.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$layout = $layout ?? 'full';
|
||||
?>
|
||||
<div class="fedistream-shortcode fedistream-shortcode--album fedistream-shortcode--<?php echo esc_attr( $layout ); ?>">
|
||||
<div class="fedistream-album">
|
||||
<div class="fedistream-album__header">
|
||||
<div class="fedistream-album__artwork">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-album__image">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-album__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-album__info">
|
||||
<?php if ( ! empty( $post['album_type_label'] ) ) : ?>
|
||||
<span class="fedistream-album__type-badge"><?php echo esc_html( $post['album_type_label'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<h3 class="fedistream-album__title">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '#' ); ?>"><?php echo esc_html( $post['title'] ?? '' ); ?></a>
|
||||
</h3>
|
||||
<?php if ( ! empty( $post['artist_name'] ) ) : ?>
|
||||
<p class="fedistream-album__artist">
|
||||
<a href="<?php echo esc_url( $post['artist_url'] ?? '#' ); ?>"><?php echo esc_html( $post['artist_name'] ); ?></a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-album__meta">
|
||||
<?php if ( ! empty( $post['release_date'] ) ) : ?>
|
||||
<span class="fedistream-album__date"><?php echo esc_html( $post['release_date'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['total_tracks'] ) ) : ?>
|
||||
<span class="fedistream-album__tracks">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of tracks */
|
||||
esc_html( _n( '%d track', '%d tracks', $post['total_tracks'], 'wp-fedistream' ) ),
|
||||
(int) $post['total_tracks']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-album__actions">
|
||||
<button type="button" class="fedistream-btn fedistream-btn--primary fedistream-btn--play-all" data-album-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<?php esc_html_e( 'Play', 'wp-fedistream' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ( ! empty( $show_tracks ) && ! empty( $post['tracks'] ) && is_array( $post['tracks'] ) ) : ?>
|
||||
<div class="fedistream-album__tracklist">
|
||||
<div class="fedistream-tracklist">
|
||||
<?php foreach ( $post['tracks'] as $index => $track ) : ?>
|
||||
<div class="fedistream-tracklist__item" data-track-id="<?php echo esc_attr( $track['id'] ?? '' ); ?>">
|
||||
<span class="fedistream-tracklist__number"><?php echo esc_html( $track['track_number'] ?? ( $index + 1 ) ); ?></span>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="<?php echo esc_url( $track['permalink'] ?? '#' ); ?>" class="fedistream-tracklist__title"><?php echo esc_html( $track['title'] ?? '' ); ?></a>
|
||||
</div>
|
||||
<?php if ( ! empty( $track['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__duration"><?php echo esc_html( $track['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,64 +0,0 @@
|
||||
{# Album shortcode template #}
|
||||
<div class="fedistream-shortcode fedistream-shortcode--album fedistream-shortcode--{{ layout }}">
|
||||
<div class="fedistream-album">
|
||||
<div class="fedistream-album__header">
|
||||
<div class="fedistream-album__artwork">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-album__image">
|
||||
{% else %}
|
||||
<div class="fedistream-album__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-album__info">
|
||||
{% if post.album_type %}
|
||||
<span class="fedistream-album__type-badge">{{ post.album_type }}</span>
|
||||
{% endif %}
|
||||
<h3 class="fedistream-album__title">
|
||||
<a href="{{ post.permalink }}">{{ post.title }}</a>
|
||||
</h3>
|
||||
{% if post.artist %}
|
||||
<p class="fedistream-album__artist">
|
||||
<a href="{{ post.artist_link }}">{{ post.artist }}</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="fedistream-album__meta">
|
||||
{% if post.release_date %}
|
||||
<span class="fedistream-album__date">{{ post.release_date }}</span>
|
||||
{% endif %}
|
||||
{% if post.track_count %}
|
||||
<span class="fedistream-album__tracks">{{ post.track_count }} {{ post.track_count == 1 ? 'track' : 'tracks' }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-album__actions">
|
||||
<button type="button" class="fedistream-btn fedistream-btn--primary fedistream-btn--play-all" data-album-id="{{ post.id }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
{{ __('Play', 'wp-fedistream') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if show_tracks and post.tracks is not empty %}
|
||||
<div class="fedistream-album__tracklist">
|
||||
<div class="fedistream-tracklist">
|
||||
{% for track in post.tracks %}
|
||||
<div class="fedistream-tracklist__item" data-track-id="{{ track.id }}">
|
||||
<span class="fedistream-tracklist__number">{{ track.track_number|default(loop.index) }}</span>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="{{ track.permalink }}" class="fedistream-tracklist__title">{{ track.title }}</a>
|
||||
</div>
|
||||
{% if track.duration_formatted %}
|
||||
<span class="fedistream-tracklist__duration">{{ track.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
84
templates/shortcodes/artist.php
Normal file
84
templates/shortcodes/artist.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/**
|
||||
* Artist shortcode template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Artist data array.
|
||||
* @var string $layout Layout style (full, card, compact).
|
||||
* @var bool $show_albums Whether to show albums.
|
||||
* @var bool $show_tracks Whether to show tracks.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = \WP_FediStream\Plugin::get_instance();
|
||||
$layout = $layout ?? 'full';
|
||||
?>
|
||||
<div class="fedistream-shortcode fedistream-shortcode--artist fedistream-shortcode--<?php echo esc_attr( $layout ); ?>">
|
||||
<div class="fedistream-artist">
|
||||
<div class="fedistream-artist__header">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-artist__image">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-artist__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-artist__info">
|
||||
<h3 class="fedistream-artist__name">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '#' ); ?>"><?php echo esc_html( $post['title'] ?? '' ); ?></a>
|
||||
</h3>
|
||||
<?php if ( ! empty( $post['artist_type_label'] ) ) : ?>
|
||||
<span class="fedistream-artist__type"><?php echo esc_html( $post['artist_type_label'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['genres'] ) && is_array( $post['genres'] ) ) : ?>
|
||||
<div class="fedistream-artist__genres">
|
||||
<?php foreach ( $post['genres'] as $genre ) : ?>
|
||||
<a href="<?php echo esc_url( $genre['url'] ?? '#' ); ?>" class="fedistream-tag"><?php echo esc_html( $genre['name'] ?? '' ); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ( 'full' === $layout && ! empty( $post['content'] ) ) : ?>
|
||||
<div class="fedistream-artist__bio">
|
||||
<?php echo wp_kses_post( $post['content'] ); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $show_albums ) && ! empty( $post['albums'] ) && is_array( $post['albums'] ) ) : ?>
|
||||
<div class="fedistream-artist__albums">
|
||||
<h4 class="fedistream-section__title"><?php esc_html_e( 'Albums', 'wp-fedistream' ); ?></h4>
|
||||
<div class="fedistream-grid fedistream-grid--small">
|
||||
<?php foreach ( array_slice( $post['albums'], 0, 4 ) as $album ) : ?>
|
||||
<?php echo $plugin->render_partial( 'partials/card-album', array( 'post' => $album ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $show_tracks ) && ! empty( $post['tracks'] ) && is_array( $post['tracks'] ) ) : ?>
|
||||
<div class="fedistream-artist__tracks">
|
||||
<h4 class="fedistream-section__title"><?php esc_html_e( 'Popular Tracks', 'wp-fedistream' ); ?></h4>
|
||||
<div class="fedistream-tracklist fedistream-tracklist--compact">
|
||||
<?php foreach ( array_slice( $post['tracks'], 0, 5 ) as $index => $track ) : ?>
|
||||
<div class="fedistream-tracklist__item" data-track-id="<?php echo esc_attr( $track['id'] ?? '' ); ?>">
|
||||
<span class="fedistream-tracklist__number"><?php echo esc_html( $index + 1 ); ?></span>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="<?php echo esc_url( $track['permalink'] ?? '#' ); ?>" class="fedistream-tracklist__title"><?php echo esc_html( $track['title'] ?? '' ); ?></a>
|
||||
</div>
|
||||
<?php if ( ! empty( $track['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__duration"><?php echo esc_html( $track['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,65 +0,0 @@
|
||||
{# Artist shortcode template #}
|
||||
<div class="fedistream-shortcode fedistream-shortcode--artist fedistream-shortcode--{{ layout }}">
|
||||
<div class="fedistream-artist">
|
||||
<div class="fedistream-artist__header">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-artist__image">
|
||||
{% else %}
|
||||
<div class="fedistream-artist__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="fedistream-artist__info">
|
||||
<h3 class="fedistream-artist__name">
|
||||
<a href="{{ post.permalink }}">{{ post.title }}</a>
|
||||
</h3>
|
||||
{% if post.artist_type %}
|
||||
<span class="fedistream-artist__type">{{ post.artist_type }}</span>
|
||||
{% endif %}
|
||||
{% if post.genres is not empty %}
|
||||
<div class="fedistream-artist__genres">
|
||||
{% for genre in post.genres %}
|
||||
<a href="{{ genre.link }}" class="fedistream-tag">{{ genre.name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if layout == 'full' and post.content %}
|
||||
<div class="fedistream-artist__bio">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_albums and post.albums is not empty %}
|
||||
<div class="fedistream-artist__albums">
|
||||
<h4 class="fedistream-section__title">{{ __('Albums', 'wp-fedistream') }}</h4>
|
||||
<div class="fedistream-grid fedistream-grid--small">
|
||||
{% for album in post.albums|slice(0, 4) %}
|
||||
{% include 'partials/card-album.twig' with { post: album } %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if show_tracks and post.tracks is not empty %}
|
||||
<div class="fedistream-artist__tracks">
|
||||
<h4 class="fedistream-section__title">{{ __('Popular Tracks', 'wp-fedistream') }}</h4>
|
||||
<div class="fedistream-tracklist fedistream-tracklist--compact">
|
||||
{% for track in post.tracks|slice(0, 5) %}
|
||||
<div class="fedistream-tracklist__item" data-track-id="{{ track.id }}">
|
||||
<span class="fedistream-tracklist__number">{{ loop.index }}</span>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="{{ track.permalink }}" class="fedistream-tracklist__title">{{ track.title }}</a>
|
||||
</div>
|
||||
{% if track.duration_formatted %}
|
||||
<span class="fedistream-tracklist__duration">{{ track.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
36
templates/shortcodes/artists-grid.php
Normal file
36
templates/shortcodes/artists-grid.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Artists grid shortcode template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $posts Array of artist data.
|
||||
* @var int $columns Number of columns.
|
||||
* @var string $title Section title.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = \WP_FediStream\Plugin::get_instance();
|
||||
$columns = $columns ?? 4;
|
||||
?>
|
||||
<div class="fedistream-shortcode fedistream-shortcode--artists">
|
||||
<?php if ( ! empty( $title ) ) : ?>
|
||||
<h3 class="fedistream-shortcode__title"><?php echo esc_html( $title ); ?></h3>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $posts ) && is_array( $posts ) ) : ?>
|
||||
<div class="fedistream-grid fedistream-grid--artists fedistream-grid--cols-<?php echo esc_attr( $columns ); ?>">
|
||||
<?php foreach ( $posts as $post ) : ?>
|
||||
<?php echo $plugin->render_partial( 'partials/card-artist', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="fedistream-empty">
|
||||
<p><?php esc_html_e( 'No artists found.', 'wp-fedistream' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,18 +0,0 @@
|
||||
{# Artists grid shortcode template #}
|
||||
<div class="fedistream-shortcode fedistream-shortcode--artists">
|
||||
{% if title %}
|
||||
<h3 class="fedistream-shortcode__title">{{ title }}</h3>
|
||||
{% endif %}
|
||||
|
||||
{% if posts is not empty %}
|
||||
<div class="fedistream-grid fedistream-grid--artists fedistream-grid--cols-{{ columns }}">
|
||||
{% for post in posts %}
|
||||
{% include 'partials/card-artist.twig' with { post: post } %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="fedistream-empty">
|
||||
<p>{{ __('No artists found.', 'wp-fedistream') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
127
templates/shortcodes/player.php
Normal file
127
templates/shortcodes/player.php
Normal file
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* Player shortcode template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $tracks Array of track data.
|
||||
* @var bool $autoplay Whether to autoplay.
|
||||
* @var string $style Player style (default, compact, mini).
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$style = $style ?? 'default';
|
||||
$autoplay = $autoplay ?? false;
|
||||
|
||||
if ( empty( $tracks ) || ! is_array( $tracks ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$first_track = $tracks[0];
|
||||
$is_playlist = count( $tracks ) > 1;
|
||||
?>
|
||||
<div class="fedistream-shortcode fedistream-shortcode--player fedistream-player-shortcode fedistream-player-shortcode--<?php echo esc_attr( $style ); ?>" data-autoplay="<?php echo esc_attr( $autoplay ? 'true' : 'false' ); ?>">
|
||||
<div class="fedistream-player-shortcode__container">
|
||||
<?php if ( 'mini' !== $style ) : ?>
|
||||
<div class="fedistream-player-shortcode__artwork">
|
||||
<?php if ( ! empty( $first_track['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $first_track['thumbnail'] ); ?>" alt="<?php echo esc_attr( $first_track['title'] ?? '' ); ?>" class="fedistream-player-shortcode__image">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-player-shortcode__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="fedistream-player-shortcode__info">
|
||||
<h4 class="fedistream-player-shortcode__title"><?php echo esc_html( $first_track['title'] ?? '' ); ?></h4>
|
||||
<?php if ( ! empty( $first_track['artists'] ) && is_array( $first_track['artists'] ) ) : ?>
|
||||
<p class="fedistream-player-shortcode__artist">
|
||||
<?php
|
||||
$artist_names = array_map(
|
||||
function ( $artist ) {
|
||||
return esc_html( $artist['name'] ?? '' );
|
||||
},
|
||||
$first_track['artists']
|
||||
);
|
||||
echo implode( ', ', $artist_names ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="fedistream-player" data-track-id="<?php echo esc_attr( $first_track['id'] ?? '' ); ?>" data-audio-url="<?php echo esc_url( $first_track['audio_url'] ?? '' ); ?>">
|
||||
<div class="fedistream-player__controls">
|
||||
<?php if ( $is_playlist ) : ?>
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--prev" aria-label="<?php esc_attr_e( 'Previous', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></svg>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--play" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--play" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--pause" viewBox="0 0 24 24" fill="currentColor"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
|
||||
</button>
|
||||
|
||||
<?php if ( $is_playlist ) : ?>
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--next" aria-label="<?php esc_attr_e( 'Next', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></svg>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="fedistream-player__progress">
|
||||
<span class="fedistream-player__time fedistream-player__time--current">0:00</span>
|
||||
<div class="fedistream-player__bar">
|
||||
<div class="fedistream-player__bar-progress"></div>
|
||||
<input type="range" class="fedistream-player__seek" min="0" max="100" value="0" aria-label="<?php esc_attr_e( 'Seek', 'wp-fedistream' ); ?>">
|
||||
</div>
|
||||
<span class="fedistream-player__time fedistream-player__time--total"><?php echo esc_html( $first_track['duration_formatted'] ?? '0:00' ); ?></span>
|
||||
</div>
|
||||
|
||||
<div class="fedistream-player__volume">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--volume" aria-label="<?php esc_attr_e( 'Volume', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>
|
||||
</button>
|
||||
<input type="range" class="fedistream-player__volume-slider" min="0" max="100" value="80" aria-label="<?php esc_attr_e( 'Volume', 'wp-fedistream' ); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ( $is_playlist ) : ?>
|
||||
<div class="fedistream-player-shortcode__playlist" data-tracks='<?php echo esc_attr( wp_json_encode( array_map( function ( $track ) {
|
||||
return array(
|
||||
'id' => $track['id'] ?? 0,
|
||||
'title' => $track['title'] ?? '',
|
||||
'artist' => ! empty( $track['artists'] ) ? implode( ', ', array_column( $track['artists'], 'name' ) ) : '',
|
||||
'audio' => $track['audio_url'] ?? '',
|
||||
'duration' => $track['duration_formatted'] ?? '0:00',
|
||||
'artwork' => $track['thumbnail'] ?? '',
|
||||
);
|
||||
}, $tracks ) ) ); ?>'>
|
||||
<div class="fedistream-tracklist fedistream-tracklist--player">
|
||||
<?php foreach ( $tracks as $index => $track ) : ?>
|
||||
<div class="fedistream-tracklist__item<?php echo 0 === $index ? ' fedistream-tracklist__item--active' : ''; ?>" data-track-id="<?php echo esc_attr( $track['id'] ?? '' ); ?>" data-index="<?php echo esc_attr( $index ); ?>">
|
||||
<span class="fedistream-tracklist__number"><?php echo esc_html( $index + 1 ); ?></span>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<span class="fedistream-tracklist__title"><?php echo esc_html( $track['title'] ?? '' ); ?></span>
|
||||
<?php if ( ! empty( $track['artists'] ) && is_array( $track['artists'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__artist">
|
||||
<?php echo esc_html( implode( ', ', array_column( $track['artists'], 'name' ) ) ); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( ! empty( $track['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__duration"><?php echo esc_html( $track['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,108 +0,0 @@
|
||||
{# Audio player shortcode template #}
|
||||
<div class="fedistream-shortcode fedistream-shortcode--player fedistream-player-widget fedistream-player-widget--{{ style }}" data-autoplay="{{ autoplay ? 'true' : 'false' }}">
|
||||
{% if tracks|length == 1 %}
|
||||
{# Single track player #}
|
||||
{% set track = tracks[0] %}
|
||||
<div class="fedistream-player fedistream-player--single" data-track-id="{{ track.id }}" data-audio-url="{{ track.audio_url }}">
|
||||
<div class="fedistream-player__track-info">
|
||||
{% if track.thumbnail %}
|
||||
<img src="{{ track.thumbnail }}" alt="{{ track.title|e('html_attr') }}" class="fedistream-player__artwork">
|
||||
{% endif %}
|
||||
<div class="fedistream-player__details">
|
||||
<span class="fedistream-player__title">{{ track.title }}</span>
|
||||
{% if track.artist %}
|
||||
<span class="fedistream-player__artist">{{ track.artist }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="fedistream-player__controls">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--play" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--play" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--pause" viewBox="0 0 24 24" fill="currentColor"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="fedistream-player__progress">
|
||||
<span class="fedistream-player__time fedistream-player__time--current">0:00</span>
|
||||
<div class="fedistream-player__bar">
|
||||
<div class="fedistream-player__bar-progress"></div>
|
||||
<input type="range" class="fedistream-player__seek" min="0" max="100" value="0" aria-label="{{ __('Seek', 'wp-fedistream') }}">
|
||||
</div>
|
||||
<span class="fedistream-player__time fedistream-player__time--total">{{ track.duration_formatted|default('0:00') }}</span>
|
||||
</div>
|
||||
<div class="fedistream-player__volume">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--volume" aria-label="{{ __('Volume', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>
|
||||
</button>
|
||||
<input type="range" class="fedistream-player__volume-slider" min="0" max="100" value="80" aria-label="{{ __('Volume', 'wp-fedistream') }}">
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{# Multi-track player (playlist/album) #}
|
||||
<div class="fedistream-player fedistream-player--multi" data-tracks="{{ tracks|json_encode|e('html_attr') }}">
|
||||
<div class="fedistream-player__now-playing">
|
||||
<div class="fedistream-player__artwork-wrapper">
|
||||
<img src="" alt="" class="fedistream-player__artwork fedistream-player__artwork--current">
|
||||
</div>
|
||||
<div class="fedistream-player__details">
|
||||
<span class="fedistream-player__title fedistream-player__title--current"></span>
|
||||
<span class="fedistream-player__artist fedistream-player__artist--current"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fedistream-player__main-controls">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--prev" aria-label="{{ __('Previous', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></svg>
|
||||
</button>
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--play fedistream-player__btn--play-main" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--play" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--pause" viewBox="0 0 24 24" fill="currentColor"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
|
||||
</button>
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--next" aria-label="{{ __('Next', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="fedistream-player__progress">
|
||||
<span class="fedistream-player__time fedistream-player__time--current">0:00</span>
|
||||
<div class="fedistream-player__bar">
|
||||
<div class="fedistream-player__bar-progress"></div>
|
||||
<input type="range" class="fedistream-player__seek" min="0" max="100" value="0" aria-label="{{ __('Seek', 'wp-fedistream') }}">
|
||||
</div>
|
||||
<span class="fedistream-player__time fedistream-player__time--total">0:00</span>
|
||||
</div>
|
||||
<div class="fedistream-player__secondary-controls">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--shuffle" aria-label="{{ __('Shuffle', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></svg>
|
||||
</button>
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--repeat" aria-label="{{ __('Repeat', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z"/></svg>
|
||||
</button>
|
||||
<div class="fedistream-player__volume">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--volume" aria-label="{{ __('Volume', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>
|
||||
</button>
|
||||
<input type="range" class="fedistream-player__volume-slider" min="0" max="100" value="80" aria-label="{{ __('Volume', 'wp-fedistream') }}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Track list #}
|
||||
<div class="fedistream-player__queue">
|
||||
<div class="fedistream-tracklist fedistream-tracklist--queue">
|
||||
{% for track in tracks %}
|
||||
<div class="fedistream-tracklist__item" data-track-index="{{ loop.index0 }}" data-track-id="{{ track.id }}">
|
||||
<span class="fedistream-tracklist__number">{{ loop.index }}</span>
|
||||
{% if track.thumbnail %}
|
||||
<img src="{{ track.thumbnail }}" alt="" class="fedistream-tracklist__artwork">
|
||||
{% endif %}
|
||||
<div class="fedistream-tracklist__info">
|
||||
<span class="fedistream-tracklist__title">{{ track.title }}</span>
|
||||
<span class="fedistream-tracklist__artist">{{ track.artist }}</span>
|
||||
</div>
|
||||
{% if track.duration_formatted %}
|
||||
<span class="fedistream-tracklist__duration">{{ track.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
96
templates/shortcodes/playlist.php
Normal file
96
templates/shortcodes/playlist.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Playlist shortcode template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Playlist data array.
|
||||
* @var string $layout Layout style (full, card, compact).
|
||||
* @var bool $show_tracks Whether to show tracks.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$layout = $layout ?? 'full';
|
||||
?>
|
||||
<div class="fedistream-shortcode fedistream-shortcode--playlist fedistream-shortcode--<?php echo esc_attr( $layout ); ?>">
|
||||
<div class="fedistream-playlist">
|
||||
<div class="fedistream-playlist__header">
|
||||
<div class="fedistream-playlist__artwork">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-playlist__image">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-playlist__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( isset( $post['visibility'] ) && 'private' === $post['visibility'] ) : ?>
|
||||
<span class="fedistream-playlist__badge fedistream-playlist__badge--private">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" width="12" height="12"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6zm9 14H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"/></svg>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-playlist__info">
|
||||
<span class="fedistream-playlist__type-badge"><?php esc_html_e( 'Playlist', 'wp-fedistream' ); ?></span>
|
||||
<h3 class="fedistream-playlist__title">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '#' ); ?>"><?php echo esc_html( $post['title'] ?? '' ); ?></a>
|
||||
</h3>
|
||||
<?php if ( ! empty( $post['author'] ) ) : ?>
|
||||
<p class="fedistream-playlist__author">
|
||||
<?php esc_html_e( 'by', 'wp-fedistream' ); ?> <?php echo esc_html( $post['author'] ); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-playlist__meta">
|
||||
<?php if ( ! empty( $post['track_count'] ) ) : ?>
|
||||
<span class="fedistream-playlist__count">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of tracks */
|
||||
esc_html( _n( '%d track', '%d tracks', $post['track_count'], 'wp-fedistream' ) ),
|
||||
(int) $post['track_count']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-playlist__duration"><?php echo esc_html( $post['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-playlist__actions">
|
||||
<button type="button" class="fedistream-btn fedistream-btn--primary fedistream-btn--play-all" data-playlist-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<?php esc_html_e( 'Play', 'wp-fedistream' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ( ! empty( $show_tracks ) && ! empty( $post['tracks'] ) && is_array( $post['tracks'] ) ) : ?>
|
||||
<div class="fedistream-playlist__tracklist">
|
||||
<div class="fedistream-tracklist">
|
||||
<?php foreach ( $post['tracks'] as $index => $track ) : ?>
|
||||
<div class="fedistream-tracklist__item" data-track-id="<?php echo esc_attr( $track['id'] ?? '' ); ?>">
|
||||
<span class="fedistream-tracklist__number"><?php echo esc_html( $index + 1 ); ?></span>
|
||||
<?php if ( ! empty( $track['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $track['thumbnail'] ); ?>" alt="" class="fedistream-tracklist__artwork">
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="<?php echo esc_url( $track['permalink'] ?? '#' ); ?>" class="fedistream-tracklist__title"><?php echo esc_html( $track['title'] ?? '' ); ?></a>
|
||||
<span class="fedistream-tracklist__artist"><?php echo esc_html( $track['artist'] ?? '' ); ?></span>
|
||||
</div>
|
||||
<?php if ( ! empty( $track['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__duration"><?php echo esc_html( $track['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,71 +0,0 @@
|
||||
{# Playlist shortcode template #}
|
||||
<div class="fedistream-shortcode fedistream-shortcode--playlist fedistream-shortcode--{{ layout }}">
|
||||
<div class="fedistream-playlist">
|
||||
<div class="fedistream-playlist__header">
|
||||
<div class="fedistream-playlist__artwork">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-playlist__image">
|
||||
{% else %}
|
||||
<div class="fedistream-playlist__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if post.visibility == 'private' %}
|
||||
<span class="fedistream-playlist__badge fedistream-playlist__badge--private">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" width="12" height="12"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6zm9 14H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"/></svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-playlist__info">
|
||||
<span class="fedistream-playlist__type-badge">{{ __('Playlist', 'wp-fedistream') }}</span>
|
||||
<h3 class="fedistream-playlist__title">
|
||||
<a href="{{ post.permalink }}">{{ post.title }}</a>
|
||||
</h3>
|
||||
{% if post.author %}
|
||||
<p class="fedistream-playlist__author">
|
||||
{{ __('by', 'wp-fedistream') }} {{ post.author }}
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="fedistream-playlist__meta">
|
||||
{% if post.track_count %}
|
||||
<span class="fedistream-playlist__count">{{ post.track_count }} {{ post.track_count == 1 ? 'track' : 'tracks' }}</span>
|
||||
{% endif %}
|
||||
{% if post.duration_formatted %}
|
||||
<span class="fedistream-playlist__duration">{{ post.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-playlist__actions">
|
||||
<button type="button" class="fedistream-btn fedistream-btn--primary fedistream-btn--play-all" data-playlist-id="{{ post.id }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
{{ __('Play', 'wp-fedistream') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if show_tracks and post.tracks is not empty %}
|
||||
<div class="fedistream-playlist__tracklist">
|
||||
<div class="fedistream-tracklist">
|
||||
{% for track in post.tracks %}
|
||||
<div class="fedistream-tracklist__item" data-track-id="{{ track.id }}">
|
||||
<span class="fedistream-tracklist__number">{{ loop.index }}</span>
|
||||
{% if track.thumbnail %}
|
||||
<img src="{{ track.thumbnail }}" alt="" class="fedistream-tracklist__artwork">
|
||||
{% endif %}
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="{{ track.permalink }}" class="fedistream-tracklist__title">{{ track.title }}</a>
|
||||
<span class="fedistream-tracklist__artist">{{ track.artist }}</span>
|
||||
</div>
|
||||
{% if track.duration_formatted %}
|
||||
<span class="fedistream-tracklist__duration">{{ track.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
36
templates/shortcodes/releases-grid.php
Normal file
36
templates/shortcodes/releases-grid.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Releases grid shortcode template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $posts Array of album data.
|
||||
* @var int $columns Number of columns.
|
||||
* @var string $title Section title.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = \WP_FediStream\Plugin::get_instance();
|
||||
$columns = $columns ?? 3;
|
||||
?>
|
||||
<div class="fedistream-shortcode fedistream-shortcode--releases">
|
||||
<?php if ( ! empty( $title ) ) : ?>
|
||||
<h3 class="fedistream-shortcode__title"><?php echo esc_html( $title ); ?></h3>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $posts ) && is_array( $posts ) ) : ?>
|
||||
<div class="fedistream-grid fedistream-grid--albums fedistream-grid--cols-<?php echo esc_attr( $columns ); ?>">
|
||||
<?php foreach ( $posts as $post ) : ?>
|
||||
<?php echo $plugin->render_partial( 'partials/card-album', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="fedistream-empty">
|
||||
<p><?php esc_html_e( 'No releases found.', 'wp-fedistream' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,18 +0,0 @@
|
||||
{# Latest releases grid shortcode template #}
|
||||
<div class="fedistream-shortcode fedistream-shortcode--releases">
|
||||
{% if title %}
|
||||
<h3 class="fedistream-shortcode__title">{{ title }}</h3>
|
||||
{% endif %}
|
||||
|
||||
{% if posts is not empty %}
|
||||
<div class="fedistream-grid fedistream-grid--albums fedistream-grid--cols-{{ columns }}">
|
||||
{% for post in posts %}
|
||||
{% include 'partials/card-album.twig' with { post: post } %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="fedistream-empty">
|
||||
<p>{{ __('No releases found.', 'wp-fedistream') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
97
templates/shortcodes/track.php
Normal file
97
templates/shortcodes/track.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* Track shortcode template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Track data array.
|
||||
* @var string $layout Layout style (full, card, compact).
|
||||
* @var bool $show_player Whether to show the player.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$layout = $layout ?? 'full';
|
||||
?>
|
||||
<div class="fedistream-shortcode fedistream-shortcode--track fedistream-shortcode--<?php echo esc_attr( $layout ); ?>">
|
||||
<div class="fedistream-track">
|
||||
<div class="fedistream-track__header">
|
||||
<div class="fedistream-track__artwork">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-track__image">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-track__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $show_player ) ) : ?>
|
||||
<button type="button" class="fedistream-track__play-overlay" data-track-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-track__info">
|
||||
<h3 class="fedistream-track__title">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '#' ); ?>"><?php echo esc_html( $post['title'] ?? '' ); ?></a>
|
||||
</h3>
|
||||
<?php if ( ! empty( $post['artists'] ) && is_array( $post['artists'] ) ) : ?>
|
||||
<p class="fedistream-track__artists">
|
||||
<?php
|
||||
$artist_links = array();
|
||||
foreach ( $post['artists'] as $artist ) {
|
||||
$artist_links[] = sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
esc_url( $artist['url'] ?? '#' ),
|
||||
esc_html( $artist['name'] ?? '' )
|
||||
);
|
||||
}
|
||||
echo implode( ', ', $artist_links ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['album_title'] ) ) : ?>
|
||||
<p class="fedistream-track__album">
|
||||
<?php esc_html_e( 'From', 'wp-fedistream' ); ?> <a href="<?php echo esc_url( $post['album_url'] ?? '#' ); ?>"><?php echo esc_html( $post['album_title'] ); ?></a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-track__meta">
|
||||
<?php if ( ! empty( $post['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-track__duration"><?php echo esc_html( $post['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['play_count'] ) ) : ?>
|
||||
<span class="fedistream-track__plays">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of plays */
|
||||
esc_html( _n( '%d play', '%d plays', $post['play_count'], 'wp-fedistream' ) ),
|
||||
(int) $post['play_count']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ( ! empty( $show_player ) && ! empty( $post['audio_url'] ) ) : ?>
|
||||
<div class="fedistream-track__player">
|
||||
<div class="fedistream-player fedistream-player--inline" data-track-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>" data-audio-url="<?php echo esc_url( $post['audio_url'] ); ?>">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--play" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--play" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--pause" viewBox="0 0 24 24" fill="currentColor"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
|
||||
</button>
|
||||
<div class="fedistream-player__progress">
|
||||
<div class="fedistream-player__bar">
|
||||
<div class="fedistream-player__bar-progress"></div>
|
||||
<input type="range" class="fedistream-player__seek" min="0" max="100" value="0" aria-label="<?php esc_attr_e( 'Seek', 'wp-fedistream' ); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<span class="fedistream-player__time"><?php echo esc_html( $post['duration_formatted'] ?? '0:00' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,64 +0,0 @@
|
||||
{# Track shortcode template #}
|
||||
<div class="fedistream-shortcode fedistream-shortcode--track fedistream-shortcode--{{ layout }}">
|
||||
<div class="fedistream-track">
|
||||
<div class="fedistream-track__header">
|
||||
<div class="fedistream-track__artwork">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-track__image">
|
||||
{% else %}
|
||||
<div class="fedistream-track__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if show_player %}
|
||||
<button type="button" class="fedistream-track__play-overlay" data-track-id="{{ post.id }}" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-track__info">
|
||||
<h3 class="fedistream-track__title">
|
||||
<a href="{{ post.permalink }}">{{ post.title }}</a>
|
||||
</h3>
|
||||
{% if post.artists is not empty %}
|
||||
<p class="fedistream-track__artists">
|
||||
{% for artist in post.artists %}
|
||||
<a href="{{ artist.link }}">{{ artist.name }}</a>{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if post.album %}
|
||||
<p class="fedistream-track__album">
|
||||
{{ __('From', 'wp-fedistream') }} <a href="{{ post.album_link }}">{{ post.album }}</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="fedistream-track__meta">
|
||||
{% if post.duration_formatted %}
|
||||
<span class="fedistream-track__duration">{{ post.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
{% if post.play_count %}
|
||||
<span class="fedistream-track__plays">{{ post.play_count }} {{ post.play_count == 1 ? 'play' : 'plays' }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if show_player and post.audio_url %}
|
||||
<div class="fedistream-track__player">
|
||||
<div class="fedistream-player fedistream-player--inline" data-track-id="{{ post.id }}" data-audio-url="{{ post.audio_url }}">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--play" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--play" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--pause" viewBox="0 0 24 24" fill="currentColor"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
|
||||
</button>
|
||||
<div class="fedistream-player__progress">
|
||||
<div class="fedistream-player__bar">
|
||||
<div class="fedistream-player__bar-progress"></div>
|
||||
<input type="range" class="fedistream-player__seek" min="0" max="100" value="0" aria-label="{{ __('Seek', 'wp-fedistream') }}">
|
||||
</div>
|
||||
</div>
|
||||
<span class="fedistream-player__time">{{ post.duration_formatted|default('0:00') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
73
templates/shortcodes/tracks-list.php
Normal file
73
templates/shortcodes/tracks-list.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
/**
|
||||
* Tracks list shortcode template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $posts Array of track data.
|
||||
* @var int $columns Number of columns.
|
||||
* @var string $title Section title.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$columns = $columns ?? 1;
|
||||
?>
|
||||
<div class="fedistream-shortcode fedistream-shortcode--tracks">
|
||||
<?php if ( ! empty( $title ) ) : ?>
|
||||
<h3 class="fedistream-shortcode__title"><?php echo esc_html( $title ); ?></h3>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $posts ) && is_array( $posts ) ) : ?>
|
||||
<div class="fedistream-tracklist fedistream-tracklist--numbered">
|
||||
<?php foreach ( $posts as $index => $post ) : ?>
|
||||
<div class="fedistream-tracklist__item" data-track-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>">
|
||||
<span class="fedistream-tracklist__rank"><?php echo esc_html( $index + 1 ); ?></span>
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="" class="fedistream-tracklist__artwork">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-tracklist__artwork fedistream-tracklist__artwork--placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '#' ); ?>" class="fedistream-tracklist__title"><?php echo esc_html( $post['title'] ?? '' ); ?></a>
|
||||
<span class="fedistream-tracklist__artist">
|
||||
<?php if ( ! empty( $post['artists'] ) && is_array( $post['artists'] ) ) : ?>
|
||||
<?php
|
||||
$artist_links = array();
|
||||
foreach ( $post['artists'] as $artist ) {
|
||||
$artist_links[] = sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
esc_url( $artist['url'] ?? '#' ),
|
||||
esc_html( $artist['name'] ?? '' )
|
||||
);
|
||||
}
|
||||
echo implode( ', ', $artist_links ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
<?php elseif ( ! empty( $post['artist'] ) ) : ?>
|
||||
<?php echo esc_html( $post['artist'] ); ?>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php if ( ! empty( $post['play_count'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__plays"><?php echo esc_html( number_format( $post['play_count'] ) ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__duration"><?php echo esc_html( $post['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="fedistream-empty">
|
||||
<p><?php esc_html_e( 'No tracks found.', 'wp-fedistream' ); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -1,48 +0,0 @@
|
||||
{# Popular tracks list shortcode template #}
|
||||
<div class="fedistream-shortcode fedistream-shortcode--tracks">
|
||||
{% if title %}
|
||||
<h3 class="fedistream-shortcode__title">{{ title }}</h3>
|
||||
{% endif %}
|
||||
|
||||
{% if posts is not empty %}
|
||||
<div class="fedistream-tracklist fedistream-tracklist--numbered">
|
||||
{% for post in posts %}
|
||||
<div class="fedistream-tracklist__item" data-track-id="{{ post.id }}">
|
||||
<span class="fedistream-tracklist__rank">{{ loop.index }}</span>
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="" class="fedistream-tracklist__artwork">
|
||||
{% else %}
|
||||
<div class="fedistream-tracklist__artwork fedistream-tracklist__artwork--placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="{{ post.permalink }}" class="fedistream-tracklist__title">{{ post.title }}</a>
|
||||
<span class="fedistream-tracklist__artist">
|
||||
{% if post.artists is iterable %}
|
||||
{% for artist in post.artists %}
|
||||
<a href="{{ artist.link }}">{{ artist.name }}</a>{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{ post.artist }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% if post.play_count %}
|
||||
<span class="fedistream-tracklist__plays">{{ post.play_count|number_format }}</span>
|
||||
{% endif %}
|
||||
{% if post.duration_formatted %}
|
||||
<span class="fedistream-tracklist__duration">{{ post.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="fedistream-empty">
|
||||
<p>{{ __('No tracks found.', 'wp-fedistream') }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
126
templates/single/album.php
Normal file
126
templates/single/album.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
/**
|
||||
* Single album template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Album data array.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<article class="fedistream-single fedistream-single--album">
|
||||
<header class="fedistream-single__header fedistream-single__header--album">
|
||||
<div class="fedistream-single__artwork">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-single__image fedistream-single__image--album">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-single__placeholder fedistream-single__placeholder--album">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-single__info">
|
||||
<span class="fedistream-single__type-badge"><?php echo esc_html( $post['album_type_label'] ?? __( 'Album', 'wp-fedistream' ) ); ?></span>
|
||||
<h1 class="fedistream-single__title"><?php echo esc_html( $post['title'] ?? '' ); ?></h1>
|
||||
<?php if ( ! empty( $post['artist_name'] ) ) : ?>
|
||||
<p class="fedistream-single__artist">
|
||||
<a href="<?php echo esc_url( $post['artist_url'] ?? '#' ); ?>"><?php echo esc_html( $post['artist_name'] ); ?></a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-single__meta">
|
||||
<?php if ( ! empty( $post['release_date'] ) ) : ?>
|
||||
<span class="fedistream-single__date"><?php echo esc_html( $post['release_date'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['total_tracks'] ) ) : ?>
|
||||
<span class="fedistream-single__tracks">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of tracks */
|
||||
esc_html( _n( '%d track', '%d tracks', $post['total_tracks'], 'wp-fedistream' ) ),
|
||||
(int) $post['total_tracks']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-single__duration"><?php echo esc_html( $post['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( ! empty( $post['genres'] ) && is_array( $post['genres'] ) ) : ?>
|
||||
<div class="fedistream-single__genres">
|
||||
<?php foreach ( $post['genres'] as $genre ) : ?>
|
||||
<a href="<?php echo esc_url( $genre['url'] ?? '#' ); ?>" class="fedistream-tag"><?php echo esc_html( $genre['name'] ?? '' ); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-single__actions">
|
||||
<button type="button" class="fedistream-btn fedistream-btn--primary fedistream-btn--play-all" data-album-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<?php esc_html_e( 'Play All', 'wp-fedistream' ); ?>
|
||||
</button>
|
||||
<button type="button" class="fedistream-btn fedistream-btn--secondary fedistream-btn--shuffle" data-album-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></svg>
|
||||
<?php esc_html_e( 'Shuffle', 'wp-fedistream' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<?php if ( ! empty( $post['tracks'] ) && is_array( $post['tracks'] ) ) : ?>
|
||||
<section class="fedistream-single__tracklist">
|
||||
<div class="fedistream-tracklist fedistream-tracklist--album">
|
||||
<?php foreach ( $post['tracks'] as $index => $track ) : ?>
|
||||
<div class="fedistream-tracklist__item" data-track-id="<?php echo esc_attr( $track['id'] ?? '' ); ?>">
|
||||
<span class="fedistream-tracklist__number"><?php echo esc_html( $track['track_number'] ?? ( $index + 1 ) ); ?></span>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="<?php echo esc_url( $track['permalink'] ?? '#' ); ?>" class="fedistream-tracklist__title"><?php echo esc_html( $track['title'] ?? '' ); ?></a>
|
||||
<?php if ( ! empty( $track['featured_artists'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__featuring"><?php esc_html_e( 'feat.', 'wp-fedistream' ); ?> <?php echo esc_html( $track['featured_artists'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( ! empty( $track['explicit'] ) ) : ?>
|
||||
<span class="fedistream-badge fedistream-badge--explicit">E</span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $track['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__duration"><?php echo esc_html( $track['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['content'] ) ) : ?>
|
||||
<section class="fedistream-single__content">
|
||||
<h2 class="fedistream-section__title"><?php esc_html_e( 'About This Album', 'wp-fedistream' ); ?></h2>
|
||||
<div class="fedistream-single__description">
|
||||
<?php echo wp_kses_post( $post['content'] ); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['credits'] ) ) : ?>
|
||||
<section class="fedistream-single__credits">
|
||||
<h2 class="fedistream-section__title"><?php esc_html_e( 'Credits', 'wp-fedistream' ); ?></h2>
|
||||
<div class="fedistream-credits">
|
||||
<?php echo wp_kses_post( $post['credits'] ); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['license'] ) ) : ?>
|
||||
<section class="fedistream-single__license">
|
||||
<p class="fedistream-license">
|
||||
<strong><?php esc_html_e( 'License:', 'wp-fedistream' ); ?></strong>
|
||||
<a href="<?php echo esc_url( $post['license']['link'] ?? '#' ); ?>"><?php echo esc_html( $post['license']['name'] ?? '' ); ?></a>
|
||||
</p>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
@@ -1,105 +0,0 @@
|
||||
{# Single album template #}
|
||||
<article class="fedistream-single fedistream-single--album">
|
||||
<header class="fedistream-single__header fedistream-single__header--album">
|
||||
<div class="fedistream-single__artwork">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-single__image fedistream-single__image--album">
|
||||
{% else %}
|
||||
<div class="fedistream-single__placeholder fedistream-single__placeholder--album">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-single__info">
|
||||
<span class="fedistream-single__type-badge">{{ post.album_type|default('Album') }}</span>
|
||||
<h1 class="fedistream-single__title">{{ post.title }}</h1>
|
||||
{% if post.artist %}
|
||||
<p class="fedistream-single__artist">
|
||||
<a href="{{ post.artist_link }}">{{ post.artist }}</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="fedistream-single__meta">
|
||||
{% if post.release_date %}
|
||||
<span class="fedistream-single__date">{{ post.release_date }}</span>
|
||||
{% endif %}
|
||||
{% if post.track_count %}
|
||||
<span class="fedistream-single__tracks">{{ post.track_count }} {{ post.track_count == 1 ? __('track', 'wp-fedistream') : __('tracks', 'wp-fedistream') }}</span>
|
||||
{% endif %}
|
||||
{% if post.duration_formatted %}
|
||||
<span class="fedistream-single__duration">{{ post.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if post.genres is not empty %}
|
||||
<div class="fedistream-single__genres">
|
||||
{% for genre in post.genres %}
|
||||
<a href="{{ genre.link }}" class="fedistream-tag">{{ genre.name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="fedistream-single__actions">
|
||||
<button type="button" class="fedistream-btn fedistream-btn--primary fedistream-btn--play-all" data-album-id="{{ post.id }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
{{ __('Play All', 'wp-fedistream') }}
|
||||
</button>
|
||||
<button type="button" class="fedistream-btn fedistream-btn--secondary fedistream-btn--shuffle" data-album-id="{{ post.id }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></svg>
|
||||
{{ __('Shuffle', 'wp-fedistream') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{% if post.tracks is not empty %}
|
||||
<section class="fedistream-single__tracklist">
|
||||
<div class="fedistream-tracklist fedistream-tracklist--album">
|
||||
{% for track in post.tracks %}
|
||||
<div class="fedistream-tracklist__item" data-track-id="{{ track.id }}">
|
||||
<span class="fedistream-tracklist__number">{{ track.track_number|default(loop.index) }}</span>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="{{ track.permalink }}" class="fedistream-tracklist__title">{{ track.title }}</a>
|
||||
{% if track.featured_artists %}
|
||||
<span class="fedistream-tracklist__featuring">{{ __('feat.', 'wp-fedistream') }} {{ track.featured_artists }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if track.explicit %}
|
||||
<span class="fedistream-badge fedistream-badge--explicit">E</span>
|
||||
{% endif %}
|
||||
{% if track.duration_formatted %}
|
||||
<span class="fedistream-tracklist__duration">{{ track.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.content %}
|
||||
<section class="fedistream-single__content">
|
||||
<h2 class="fedistream-section__title">{{ __('About This Album', 'wp-fedistream') }}</h2>
|
||||
<div class="fedistream-single__description">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.credits %}
|
||||
<section class="fedistream-single__credits">
|
||||
<h2 class="fedistream-section__title">{{ __('Credits', 'wp-fedistream') }}</h2>
|
||||
<div class="fedistream-credits">
|
||||
{{ post.credits|raw }}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.license %}
|
||||
<section class="fedistream-single__license">
|
||||
<p class="fedistream-license">
|
||||
<strong>{{ __('License:', 'wp-fedistream') }}</strong>
|
||||
<a href="{{ post.license.link }}">{{ post.license.name }}</a>
|
||||
</p>
|
||||
</section>
|
||||
{% endif %}
|
||||
</article>
|
||||
103
templates/single/artist.php
Normal file
103
templates/single/artist.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
/**
|
||||
* Single artist template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Artist data array.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$plugin = \WP_FediStream\Plugin::get_instance();
|
||||
?>
|
||||
<article class="fedistream-single fedistream-single--artist">
|
||||
<header class="fedistream-single__header">
|
||||
<div class="fedistream-single__hero">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-single__image fedistream-single__image--artist">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-single__placeholder fedistream-single__placeholder--artist">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-single__info">
|
||||
<h1 class="fedistream-single__title"><?php echo esc_html( $post['title'] ?? '' ); ?></h1>
|
||||
<?php if ( ! empty( $post['artist_type_label'] ) ) : ?>
|
||||
<p class="fedistream-single__type"><?php echo esc_html( $post['artist_type_label'] ); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['genres'] ) && is_array( $post['genres'] ) ) : ?>
|
||||
<div class="fedistream-single__genres">
|
||||
<?php foreach ( $post['genres'] as $genre ) : ?>
|
||||
<a href="<?php echo esc_url( $genre['url'] ?? '#' ); ?>" class="fedistream-tag"><?php echo esc_html( $genre['name'] ?? '' ); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<?php if ( ! empty( $post['content'] ) ) : ?>
|
||||
<section class="fedistream-single__content">
|
||||
<h2 class="fedistream-section__title"><?php esc_html_e( 'About', 'wp-fedistream' ); ?></h2>
|
||||
<div class="fedistream-single__description">
|
||||
<?php echo wp_kses_post( $post['content'] ); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['social_links'] ) && is_array( $post['social_links'] ) ) : ?>
|
||||
<section class="fedistream-single__social">
|
||||
<h2 class="fedistream-section__title"><?php esc_html_e( 'Connect', 'wp-fedistream' ); ?></h2>
|
||||
<div class="fedistream-social-links">
|
||||
<?php foreach ( $post['social_links'] as $platform => $url ) : ?>
|
||||
<a href="<?php echo esc_url( $url ); ?>" class="fedistream-social-link fedistream-social-link--<?php echo esc_attr( $platform ); ?>" target="_blank" rel="noopener noreferrer">
|
||||
<?php echo esc_html( $platform ); ?>
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['albums'] ) && is_array( $post['albums'] ) ) : ?>
|
||||
<section class="fedistream-single__albums">
|
||||
<h2 class="fedistream-section__title"><?php esc_html_e( 'Discography', 'wp-fedistream' ); ?></h2>
|
||||
<div class="fedistream-grid fedistream-grid--albums">
|
||||
<?php foreach ( $post['albums'] as $album ) : ?>
|
||||
<?php echo $plugin->render_partial( 'partials/card-album', array( 'post' => $album ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['tracks'] ) && is_array( $post['tracks'] ) ) : ?>
|
||||
<section class="fedistream-single__tracks">
|
||||
<h2 class="fedistream-section__title"><?php esc_html_e( 'Popular Tracks', 'wp-fedistream' ); ?></h2>
|
||||
<div class="fedistream-tracklist">
|
||||
<?php foreach ( $post['tracks'] as $index => $track ) : ?>
|
||||
<div class="fedistream-tracklist__item" data-track-id="<?php echo esc_attr( $track['id'] ?? '' ); ?>">
|
||||
<span class="fedistream-tracklist__number"><?php echo esc_html( $index + 1 ); ?></span>
|
||||
<?php if ( ! empty( $track['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $track['thumbnail'] ); ?>" alt="" class="fedistream-tracklist__artwork">
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="<?php echo esc_url( $track['permalink'] ?? '#' ); ?>" class="fedistream-tracklist__title"><?php echo esc_html( $track['title'] ?? '' ); ?></a>
|
||||
<?php if ( ! empty( $track['album_title'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__album"><?php echo esc_html( $track['album_title'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( ! empty( $track['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__duration"><?php echo esc_html( $track['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
@@ -1,88 +0,0 @@
|
||||
{# Single artist template #}
|
||||
<article class="fedistream-single fedistream-single--artist">
|
||||
<header class="fedistream-single__header">
|
||||
<div class="fedistream-single__hero">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-single__image fedistream-single__image--artist">
|
||||
{% else %}
|
||||
<div class="fedistream-single__placeholder fedistream-single__placeholder--artist">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-single__info">
|
||||
<h1 class="fedistream-single__title">{{ post.title }}</h1>
|
||||
{% if post.artist_type %}
|
||||
<p class="fedistream-single__type">{{ post.artist_type }}</p>
|
||||
{% endif %}
|
||||
{% if post.genres is not empty %}
|
||||
<div class="fedistream-single__genres">
|
||||
{% for genre in post.genres %}
|
||||
<a href="{{ genre.link }}" class="fedistream-tag">{{ genre.name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{% if post.content %}
|
||||
<section class="fedistream-single__content">
|
||||
<h2 class="fedistream-section__title">{{ __('About', 'wp-fedistream') }}</h2>
|
||||
<div class="fedistream-single__description">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.social_links is not empty %}
|
||||
<section class="fedistream-single__social">
|
||||
<h2 class="fedistream-section__title">{{ __('Connect', 'wp-fedistream') }}</h2>
|
||||
<div class="fedistream-social-links">
|
||||
{% for platform, url in post.social_links %}
|
||||
<a href="{{ url }}" class="fedistream-social-link fedistream-social-link--{{ platform }}" target="_blank" rel="noopener noreferrer">
|
||||
{{ platform }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.albums is not empty %}
|
||||
<section class="fedistream-single__albums">
|
||||
<h2 class="fedistream-section__title">{{ __('Discography', 'wp-fedistream') }}</h2>
|
||||
<div class="fedistream-grid fedistream-grid--albums">
|
||||
{% for album in post.albums %}
|
||||
{% include 'partials/card-album.twig' with { post: album } %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.tracks is not empty %}
|
||||
<section class="fedistream-single__tracks">
|
||||
<h2 class="fedistream-section__title">{{ __('Popular Tracks', 'wp-fedistream') }}</h2>
|
||||
<div class="fedistream-tracklist">
|
||||
{% for track in post.tracks %}
|
||||
<div class="fedistream-tracklist__item" data-track-id="{{ track.id }}">
|
||||
<span class="fedistream-tracklist__number">{{ loop.index }}</span>
|
||||
{% if track.thumbnail %}
|
||||
<img src="{{ track.thumbnail }}" alt="" class="fedistream-tracklist__artwork">
|
||||
{% endif %}
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="{{ track.permalink }}" class="fedistream-tracklist__title">{{ track.title }}</a>
|
||||
{% if track.album %}
|
||||
<span class="fedistream-tracklist__album">{{ track.album }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if track.duration_formatted %}
|
||||
<span class="fedistream-tracklist__duration">{{ track.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
</article>
|
||||
136
templates/single/playlist.php
Normal file
136
templates/single/playlist.php
Normal file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
/**
|
||||
* Single playlist template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Playlist data array.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<article class="fedistream-single fedistream-single--playlist">
|
||||
<header class="fedistream-single__header fedistream-single__header--playlist">
|
||||
<div class="fedistream-single__artwork">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-single__image fedistream-single__image--playlist">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-single__placeholder fedistream-single__placeholder--playlist">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( isset( $post['visibility'] ) && 'private' === $post['visibility'] ) : ?>
|
||||
<span class="fedistream-single__badge fedistream-single__badge--private">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6zm9 14H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"/></svg>
|
||||
<?php esc_html_e( 'Private', 'wp-fedistream' ); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="fedistream-single__info">
|
||||
<span class="fedistream-single__type-badge"><?php esc_html_e( 'Playlist', 'wp-fedistream' ); ?></span>
|
||||
<h1 class="fedistream-single__title"><?php echo esc_html( $post['title'] ?? '' ); ?></h1>
|
||||
<?php if ( ! empty( $post['author'] ) ) : ?>
|
||||
<p class="fedistream-single__author">
|
||||
<?php esc_html_e( 'Created by', 'wp-fedistream' ); ?> <a href="<?php echo esc_url( $post['author_link'] ?? '#' ); ?>"><?php echo esc_html( $post['author'] ); ?></a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-single__meta">
|
||||
<?php if ( ! empty( $post['track_count'] ) ) : ?>
|
||||
<span class="fedistream-single__tracks">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of tracks */
|
||||
esc_html( _n( '%d track', '%d tracks', $post['track_count'], 'wp-fedistream' ) ),
|
||||
(int) $post['track_count']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-single__duration"><?php echo esc_html( $post['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['updated_date'] ) ) : ?>
|
||||
<span class="fedistream-single__updated"><?php esc_html_e( 'Updated', 'wp-fedistream' ); ?> <?php echo esc_html( $post['updated_date'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( ! empty( $post['moods'] ) && is_array( $post['moods'] ) ) : ?>
|
||||
<div class="fedistream-single__moods">
|
||||
<?php foreach ( $post['moods'] as $mood ) : ?>
|
||||
<a href="<?php echo esc_url( $mood['url'] ?? '#' ); ?>" class="fedistream-tag fedistream-tag--mood"><?php echo esc_html( $mood['name'] ?? '' ); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-single__actions">
|
||||
<button type="button" class="fedistream-btn fedistream-btn--primary fedistream-btn--play-all" data-playlist-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<?php esc_html_e( 'Play All', 'wp-fedistream' ); ?>
|
||||
</button>
|
||||
<button type="button" class="fedistream-btn fedistream-btn--secondary fedistream-btn--shuffle" data-playlist-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></svg>
|
||||
<?php esc_html_e( 'Shuffle', 'wp-fedistream' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<?php if ( ! empty( $post['content'] ) ) : ?>
|
||||
<section class="fedistream-single__content">
|
||||
<div class="fedistream-single__description">
|
||||
<?php echo wp_kses_post( $post['content'] ); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['tracks'] ) && is_array( $post['tracks'] ) ) : ?>
|
||||
<section class="fedistream-single__tracklist">
|
||||
<div class="fedistream-tracklist fedistream-tracklist--playlist">
|
||||
<?php foreach ( $post['tracks'] as $index => $track ) : ?>
|
||||
<div class="fedistream-tracklist__item" data-track-id="<?php echo esc_attr( $track['id'] ?? '' ); ?>">
|
||||
<span class="fedistream-tracklist__number"><?php echo esc_html( $index + 1 ); ?></span>
|
||||
<?php if ( ! empty( $track['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $track['thumbnail'] ); ?>" alt="" class="fedistream-tracklist__artwork">
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="<?php echo esc_url( $track['permalink'] ?? '#' ); ?>" class="fedistream-tracklist__title"><?php echo esc_html( $track['title'] ?? '' ); ?></a>
|
||||
<span class="fedistream-tracklist__artist">
|
||||
<?php if ( ! empty( $track['artists'] ) && is_array( $track['artists'] ) ) : ?>
|
||||
<?php
|
||||
$artist_links = array();
|
||||
foreach ( $track['artists'] as $artist ) {
|
||||
$artist_links[] = sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
esc_url( $artist['url'] ?? '#' ),
|
||||
esc_html( $artist['name'] ?? '' )
|
||||
);
|
||||
}
|
||||
echo implode( ', ', $artist_links ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
<?php elseif ( ! empty( $track['artist'] ) ) : ?>
|
||||
<?php echo esc_html( $track['artist'] ); ?>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php if ( ! empty( $track['explicit'] ) ) : ?>
|
||||
<span class="fedistream-badge fedistream-badge--explicit">E</span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $track['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-tracklist__duration"><?php echo esc_html( $track['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php else : ?>
|
||||
<section class="fedistream-single__empty">
|
||||
<div class="fedistream-empty">
|
||||
<p><?php esc_html_e( 'This playlist is empty.', 'wp-fedistream' ); ?></p>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
@@ -1,107 +0,0 @@
|
||||
{# Single playlist template #}
|
||||
<article class="fedistream-single fedistream-single--playlist">
|
||||
<header class="fedistream-single__header fedistream-single__header--playlist">
|
||||
<div class="fedistream-single__artwork">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-single__image fedistream-single__image--playlist">
|
||||
{% else %}
|
||||
<div class="fedistream-single__placeholder fedistream-single__placeholder--playlist">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M15 6H3v2h12V6zm0 4H3v2h12v-2zM3 16h8v-2H3v2zM17 6v8.18c-.31-.11-.65-.18-1-.18-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3V8h3V6h-5z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if post.visibility == 'private' %}
|
||||
<span class="fedistream-single__badge fedistream-single__badge--private">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6zm9 14H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"/></svg>
|
||||
{{ __('Private', 'wp-fedistream') }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="fedistream-single__info">
|
||||
<span class="fedistream-single__type-badge">{{ __('Playlist', 'wp-fedistream') }}</span>
|
||||
<h1 class="fedistream-single__title">{{ post.title }}</h1>
|
||||
{% if post.author %}
|
||||
<p class="fedistream-single__author">
|
||||
{{ __('Created by', 'wp-fedistream') }} <a href="{{ post.author_link }}">{{ post.author }}</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="fedistream-single__meta">
|
||||
{% if post.track_count %}
|
||||
<span class="fedistream-single__tracks">{{ post.track_count }} {{ post.track_count == 1 ? __('track', 'wp-fedistream') : __('tracks', 'wp-fedistream') }}</span>
|
||||
{% endif %}
|
||||
{% if post.duration_formatted %}
|
||||
<span class="fedistream-single__duration">{{ post.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
{% if post.updated_date %}
|
||||
<span class="fedistream-single__updated">{{ __('Updated', 'wp-fedistream') }} {{ post.updated_date }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if post.moods is not empty %}
|
||||
<div class="fedistream-single__moods">
|
||||
{% for mood in post.moods %}
|
||||
<a href="{{ mood.link }}" class="fedistream-tag fedistream-tag--mood">{{ mood.name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="fedistream-single__actions">
|
||||
<button type="button" class="fedistream-btn fedistream-btn--primary fedistream-btn--play-all" data-playlist-id="{{ post.id }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
{{ __('Play All', 'wp-fedistream') }}
|
||||
</button>
|
||||
<button type="button" class="fedistream-btn fedistream-btn--secondary fedistream-btn--shuffle" data-playlist-id="{{ post.id }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></svg>
|
||||
{{ __('Shuffle', 'wp-fedistream') }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{% if post.content %}
|
||||
<section class="fedistream-single__content">
|
||||
<div class="fedistream-single__description">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.tracks is not empty %}
|
||||
<section class="fedistream-single__tracklist">
|
||||
<div class="fedistream-tracklist fedistream-tracklist--playlist">
|
||||
{% for track in post.tracks %}
|
||||
<div class="fedistream-tracklist__item" data-track-id="{{ track.id }}">
|
||||
<span class="fedistream-tracklist__number">{{ loop.index }}</span>
|
||||
{% if track.thumbnail %}
|
||||
<img src="{{ track.thumbnail }}" alt="" class="fedistream-tracklist__artwork">
|
||||
{% endif %}
|
||||
<div class="fedistream-tracklist__info">
|
||||
<a href="{{ track.permalink }}" class="fedistream-tracklist__title">{{ track.title }}</a>
|
||||
<span class="fedistream-tracklist__artist">
|
||||
{% if track.artists is iterable %}
|
||||
{% for artist in track.artists %}
|
||||
<a href="{{ artist.link }}">{{ artist.name }}</a>{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{ track.artist }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% if track.explicit %}
|
||||
<span class="fedistream-badge fedistream-badge--explicit">E</span>
|
||||
{% endif %}
|
||||
{% if track.duration_formatted %}
|
||||
<span class="fedistream-tracklist__duration">{{ track.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
<button type="button" class="fedistream-tracklist__play" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% else %}
|
||||
<section class="fedistream-single__empty">
|
||||
<div class="fedistream-empty">
|
||||
<p>{{ __('This playlist is empty.', 'wp-fedistream') }}</p>
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
</article>
|
||||
149
templates/single/track.php
Normal file
149
templates/single/track.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
/**
|
||||
* Single track template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Track data array.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<article class="fedistream-single fedistream-single--track">
|
||||
<header class="fedistream-single__header fedistream-single__header--track">
|
||||
<div class="fedistream-single__artwork">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-single__image fedistream-single__image--track">
|
||||
<?php else : ?>
|
||||
<div class="fedistream-single__placeholder fedistream-single__placeholder--track">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="fedistream-single__play-overlay" data-track-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="fedistream-single__info">
|
||||
<h1 class="fedistream-single__title"><?php echo esc_html( $post['title'] ?? '' ); ?></h1>
|
||||
<?php if ( ! empty( $post['artists'] ) && is_array( $post['artists'] ) ) : ?>
|
||||
<p class="fedistream-single__artists">
|
||||
<?php
|
||||
$artist_links = array();
|
||||
foreach ( $post['artists'] as $artist ) {
|
||||
$artist_links[] = sprintf(
|
||||
'<a href="%s">%s</a>',
|
||||
esc_url( $artist['url'] ?? '#' ),
|
||||
esc_html( $artist['name'] ?? '' )
|
||||
);
|
||||
}
|
||||
echo implode( ', ', $artist_links ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['album_title'] ) ) : ?>
|
||||
<p class="fedistream-single__album">
|
||||
<?php esc_html_e( 'From', 'wp-fedistream' ); ?> <a href="<?php echo esc_url( $post['album_url'] ?? '#' ); ?>"><?php echo esc_html( $post['album_title'] ); ?></a>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<div class="fedistream-single__meta">
|
||||
<?php if ( ! empty( $post['duration_formatted'] ) ) : ?>
|
||||
<span class="fedistream-single__duration"><?php echo esc_html( $post['duration_formatted'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['play_count'] ) ) : ?>
|
||||
<span class="fedistream-single__plays">
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of plays */
|
||||
esc_html( _n( '%d play', '%d plays', $post['play_count'], 'wp-fedistream' ) ),
|
||||
(int) $post['play_count']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['explicit'] ) ) : ?>
|
||||
<span class="fedistream-badge fedistream-badge--explicit"><?php esc_html_e( 'Explicit', 'wp-fedistream' ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if ( ! empty( $post['genres'] ) && is_array( $post['genres'] ) ) : ?>
|
||||
<div class="fedistream-single__genres">
|
||||
<?php foreach ( $post['genres'] as $genre ) : ?>
|
||||
<a href="<?php echo esc_url( $genre['url'] ?? '#' ); ?>" class="fedistream-tag"><?php echo esc_html( $genre['name'] ?? '' ); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['moods'] ) && is_array( $post['moods'] ) ) : ?>
|
||||
<div class="fedistream-single__moods">
|
||||
<?php foreach ( $post['moods'] as $mood ) : ?>
|
||||
<a href="<?php echo esc_url( $mood['url'] ?? '#' ); ?>" class="fedistream-tag fedistream-tag--mood"><?php echo esc_html( $mood['name'] ?? '' ); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<?php if ( ! empty( $post['audio_url'] ) ) : ?>
|
||||
<section class="fedistream-single__player">
|
||||
<div class="fedistream-player" data-track-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>" data-audio-url="<?php echo esc_url( $post['audio_url'] ); ?>">
|
||||
<div class="fedistream-player__controls">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--play" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--play" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--pause" viewBox="0 0 24 24" fill="currentColor"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="fedistream-player__progress">
|
||||
<span class="fedistream-player__time fedistream-player__time--current">0:00</span>
|
||||
<div class="fedistream-player__bar">
|
||||
<div class="fedistream-player__bar-progress"></div>
|
||||
<input type="range" class="fedistream-player__seek" min="0" max="100" value="0" aria-label="<?php esc_attr_e( 'Seek', 'wp-fedistream' ); ?>">
|
||||
</div>
|
||||
<span class="fedistream-player__time fedistream-player__time--total"><?php echo esc_html( $post['duration_formatted'] ?? '0:00' ); ?></span>
|
||||
</div>
|
||||
<div class="fedistream-player__volume">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--volume" aria-label="<?php esc_attr_e( 'Volume', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>
|
||||
</button>
|
||||
<input type="range" class="fedistream-player__volume-slider" min="0" max="100" value="80" aria-label="<?php esc_attr_e( 'Volume', 'wp-fedistream' ); ?>">
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['content'] ) ) : ?>
|
||||
<section class="fedistream-single__content">
|
||||
<h2 class="fedistream-section__title"><?php esc_html_e( 'About This Track', 'wp-fedistream' ); ?></h2>
|
||||
<div class="fedistream-single__description">
|
||||
<?php echo wp_kses_post( $post['content'] ); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['lyrics'] ) ) : ?>
|
||||
<section class="fedistream-single__lyrics">
|
||||
<h2 class="fedistream-section__title"><?php esc_html_e( 'Lyrics', 'wp-fedistream' ); ?></h2>
|
||||
<div class="fedistream-lyrics">
|
||||
<?php echo nl2br( esc_html( $post['lyrics'] ) ); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['credits'] ) ) : ?>
|
||||
<section class="fedistream-single__credits">
|
||||
<h2 class="fedistream-section__title"><?php esc_html_e( 'Credits', 'wp-fedistream' ); ?></h2>
|
||||
<div class="fedistream-credits">
|
||||
<?php echo wp_kses_post( $post['credits'] ); ?>
|
||||
</div>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( ! empty( $post['license'] ) ) : ?>
|
||||
<section class="fedistream-single__license">
|
||||
<p class="fedistream-license">
|
||||
<strong><?php esc_html_e( 'License:', 'wp-fedistream' ); ?></strong>
|
||||
<a href="<?php echo esc_url( $post['license']['link'] ?? '#' ); ?>"><?php echo esc_html( $post['license']['name'] ?? '' ); ?></a>
|
||||
</p>
|
||||
</section>
|
||||
<?php endif; ?>
|
||||
</article>
|
||||
@@ -1,120 +0,0 @@
|
||||
{# Single track template #}
|
||||
<article class="fedistream-single fedistream-single--track">
|
||||
<header class="fedistream-single__header fedistream-single__header--track">
|
||||
<div class="fedistream-single__artwork">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-single__image fedistream-single__image--track">
|
||||
{% else %}
|
||||
<div class="fedistream-single__placeholder fedistream-single__placeholder--track">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</div>
|
||||
{% endif %}
|
||||
<button type="button" class="fedistream-single__play-overlay" data-track-id="{{ post.id }}" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="fedistream-single__info">
|
||||
<h1 class="fedistream-single__title">{{ post.title }}</h1>
|
||||
{% if post.artists is not empty %}
|
||||
<p class="fedistream-single__artists">
|
||||
{% for artist in post.artists %}
|
||||
<a href="{{ artist.link }}">{{ artist.name }}</a>{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if post.album %}
|
||||
<p class="fedistream-single__album">
|
||||
{{ __('From', 'wp-fedistream') }} <a href="{{ post.album_link }}">{{ post.album }}</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
<div class="fedistream-single__meta">
|
||||
{% if post.duration_formatted %}
|
||||
<span class="fedistream-single__duration">{{ post.duration_formatted }}</span>
|
||||
{% endif %}
|
||||
{% if post.play_count %}
|
||||
<span class="fedistream-single__plays">{{ post.play_count }} {{ post.play_count == 1 ? __('play', 'wp-fedistream') : __('plays', 'wp-fedistream') }}</span>
|
||||
{% endif %}
|
||||
{% if post.explicit %}
|
||||
<span class="fedistream-badge fedistream-badge--explicit">{{ __('Explicit', 'wp-fedistream') }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if post.genres is not empty %}
|
||||
<div class="fedistream-single__genres">
|
||||
{% for genre in post.genres %}
|
||||
<a href="{{ genre.link }}" class="fedistream-tag">{{ genre.name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if post.moods is not empty %}
|
||||
<div class="fedistream-single__moods">
|
||||
{% for mood in post.moods %}
|
||||
<a href="{{ mood.link }}" class="fedistream-tag fedistream-tag--mood">{{ mood.name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{% if post.audio_url %}
|
||||
<section class="fedistream-single__player">
|
||||
<div class="fedistream-player" data-track-id="{{ post.id }}" data-audio-url="{{ post.audio_url }}">
|
||||
<div class="fedistream-player__controls">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--play" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--play" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<svg class="fedistream-player__icon fedistream-player__icon--pause" viewBox="0 0 24 24" fill="currentColor"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="fedistream-player__progress">
|
||||
<span class="fedistream-player__time fedistream-player__time--current">0:00</span>
|
||||
<div class="fedistream-player__bar">
|
||||
<div class="fedistream-player__bar-progress"></div>
|
||||
<input type="range" class="fedistream-player__seek" min="0" max="100" value="0" aria-label="{{ __('Seek', 'wp-fedistream') }}">
|
||||
</div>
|
||||
<span class="fedistream-player__time fedistream-player__time--total">{{ post.duration_formatted|default('0:00') }}</span>
|
||||
</div>
|
||||
<div class="fedistream-player__volume">
|
||||
<button type="button" class="fedistream-player__btn fedistream-player__btn--volume" aria-label="{{ __('Volume', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>
|
||||
</button>
|
||||
<input type="range" class="fedistream-player__volume-slider" min="0" max="100" value="80" aria-label="{{ __('Volume', 'wp-fedistream') }}">
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.content %}
|
||||
<section class="fedistream-single__content">
|
||||
<h2 class="fedistream-section__title">{{ __('About This Track', 'wp-fedistream') }}</h2>
|
||||
<div class="fedistream-single__description">
|
||||
{{ post.content|raw }}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.lyrics %}
|
||||
<section class="fedistream-single__lyrics">
|
||||
<h2 class="fedistream-section__title">{{ __('Lyrics', 'wp-fedistream') }}</h2>
|
||||
<div class="fedistream-lyrics">
|
||||
{{ post.lyrics|nl2br }}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.credits %}
|
||||
<section class="fedistream-single__credits">
|
||||
<h2 class="fedistream-section__title">{{ __('Credits', 'wp-fedistream') }}</h2>
|
||||
<div class="fedistream-credits">
|
||||
{{ post.credits|raw }}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if post.license %}
|
||||
<section class="fedistream-single__license">
|
||||
<p class="fedistream-license">
|
||||
<strong>{{ __('License:', 'wp-fedistream') }}</strong>
|
||||
<a href="{{ post.license.link }}">{{ post.license.name }}</a>
|
||||
</p>
|
||||
</section>
|
||||
{% endif %}
|
||||
</article>
|
||||
70
templates/widgets/featured-artist.php
Normal file
70
templates/widgets/featured-artist.php
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* Featured Artist Widget Template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $post Artist data array.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<?php if ( ! empty( $post ) ) : ?>
|
||||
<div class="fedistream-widget__featured">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '#' ); ?>" class="fedistream-widget__featured-link">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-widget__featured-image">
|
||||
<?php else : ?>
|
||||
<span class="fedistream-widget__placeholder fedistream-widget__placeholder--large">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<div class="fedistream-widget__featured-info">
|
||||
<h4 class="fedistream-widget__featured-name">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '#' ); ?>"><?php echo esc_html( $post['title'] ?? '' ); ?></a>
|
||||
</h4>
|
||||
<?php if ( ! empty( $post['artist_type_label'] ) ) : ?>
|
||||
<span class="fedistream-widget__featured-type"><?php echo esc_html( $post['artist_type_label'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['genres'] ) && is_array( $post['genres'] ) ) : ?>
|
||||
<div class="fedistream-widget__featured-genres">
|
||||
<?php foreach ( array_slice( $post['genres'], 0, 3 ) as $genre ) : ?>
|
||||
<a href="<?php echo esc_url( $genre['url'] ?? '#' ); ?>" class="fedistream-tag fedistream-tag--small"><?php echo esc_html( $genre['name'] ?? '' ); ?></a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['album_count'] ) || ! empty( $post['track_count'] ) ) : ?>
|
||||
<div class="fedistream-widget__featured-stats">
|
||||
<?php if ( ! empty( $post['album_count'] ) ) : ?>
|
||||
<span>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of albums */
|
||||
esc_html( _n( '%d album', '%d albums', $post['album_count'], 'wp-fedistream' ) ),
|
||||
(int) $post['album_count']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['track_count'] ) ) : ?>
|
||||
<span>
|
||||
<?php
|
||||
printf(
|
||||
/* translators: %d: number of tracks */
|
||||
esc_html( _n( '%d track', '%d tracks', $post['track_count'], 'wp-fedistream' ) ),
|
||||
(int) $post['track_count']
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<p class="fedistream-widget__empty"><?php esc_html_e( 'No artist selected.', 'wp-fedistream' ); ?></p>
|
||||
<?php endif; ?>
|
||||
@@ -1,41 +0,0 @@
|
||||
{# Featured Artist Widget Template #}
|
||||
{% if post %}
|
||||
<div class="fedistream-widget__featured">
|
||||
<a href="{{ post.permalink }}" class="fedistream-widget__featured-link">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-widget__featured-image">
|
||||
{% else %}
|
||||
<span class="fedistream-widget__placeholder fedistream-widget__placeholder--large">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
<div class="fedistream-widget__featured-info">
|
||||
<h4 class="fedistream-widget__featured-name">
|
||||
<a href="{{ post.permalink }}">{{ post.title }}</a>
|
||||
</h4>
|
||||
{% if post.artist_type %}
|
||||
<span class="fedistream-widget__featured-type">{{ post.artist_type }}</span>
|
||||
{% endif %}
|
||||
{% if post.genres is not empty %}
|
||||
<div class="fedistream-widget__featured-genres">
|
||||
{% for genre in post.genres|slice(0, 3) %}
|
||||
<a href="{{ genre.link }}" class="fedistream-tag fedistream-tag--small">{{ genre.name }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if post.album_count or post.track_count %}
|
||||
<div class="fedistream-widget__featured-stats">
|
||||
{% if post.album_count %}
|
||||
<span>{{ post.album_count }} {{ post.album_count == 1 ? __('album', 'wp-fedistream') : __('albums', 'wp-fedistream') }}</span>
|
||||
{% endif %}
|
||||
{% if post.track_count %}
|
||||
<span>{{ post.track_count }} {{ post.track_count == 1 ? __('track', 'wp-fedistream') : __('tracks', 'wp-fedistream') }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="fedistream-widget__empty">{{ __('No artist selected.', 'wp-fedistream') }}</p>
|
||||
{% endif %}
|
||||
@@ -1,10 +1,25 @@
|
||||
{# Now Playing Widget Template #}
|
||||
<?php
|
||||
/**
|
||||
* Now Playing Widget Template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var bool $show_player Whether to show player controls.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
$show_player = $show_player ?? true;
|
||||
?>
|
||||
<div class="fedistream-now-playing" data-widget="now-playing">
|
||||
<div class="fedistream-now-playing__idle">
|
||||
<span class="fedistream-now-playing__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</span>
|
||||
<span class="fedistream-now-playing__message">{{ __('Nothing playing', 'wp-fedistream') }}</span>
|
||||
<span class="fedistream-now-playing__message"><?php esc_html_e( 'Nothing playing', 'wp-fedistream' ); ?></span>
|
||||
</div>
|
||||
<div class="fedistream-now-playing__active" style="display: none;">
|
||||
<div class="fedistream-now-playing__track">
|
||||
@@ -14,16 +29,16 @@
|
||||
<span class="fedistream-now-playing__artist"></span>
|
||||
</div>
|
||||
</div>
|
||||
{% if show_player %}
|
||||
<?php if ( $show_player ) : ?>
|
||||
<div class="fedistream-now-playing__controls">
|
||||
<button type="button" class="fedistream-now-playing__btn fedistream-now-playing__btn--prev" aria-label="{{ __('Previous', 'wp-fedistream') }}">
|
||||
<button type="button" class="fedistream-now-playing__btn fedistream-now-playing__btn--prev" aria-label="<?php esc_attr_e( 'Previous', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></svg>
|
||||
</button>
|
||||
<button type="button" class="fedistream-now-playing__btn fedistream-now-playing__btn--play" aria-label="{{ __('Play/Pause', 'wp-fedistream') }}">
|
||||
<button type="button" class="fedistream-now-playing__btn fedistream-now-playing__btn--play" aria-label="<?php esc_attr_e( 'Play/Pause', 'wp-fedistream' ); ?>">
|
||||
<svg class="fedistream-now-playing__icon fedistream-now-playing__icon--play" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
<svg class="fedistream-now-playing__icon fedistream-now-playing__icon--pause" viewBox="0 0 24 24" fill="currentColor"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
|
||||
</button>
|
||||
<button type="button" class="fedistream-now-playing__btn fedistream-now-playing__btn--next" aria-label="{{ __('Next', 'wp-fedistream') }}">
|
||||
<button type="button" class="fedistream-now-playing__btn fedistream-now-playing__btn--next" aria-label="<?php esc_attr_e( 'Next', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
@@ -36,6 +51,6 @@
|
||||
<span class="fedistream-now-playing__time fedistream-now-playing__time--total">0:00</span>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
45
templates/widgets/popular-tracks.php
Normal file
45
templates/widgets/popular-tracks.php
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
* Popular Tracks Widget Template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $posts Array of track data.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<?php if ( ! empty( $posts ) && is_array( $posts ) ) : ?>
|
||||
<ol class="fedistream-widget__list fedistream-widget__list--tracks">
|
||||
<?php foreach ( $posts as $post ) : ?>
|
||||
<li class="fedistream-widget__item" data-track-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '#' ); ?>" class="fedistream-widget__link">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-widget__image">
|
||||
<?php else : ?>
|
||||
<span class="fedistream-widget__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<span class="fedistream-widget__info">
|
||||
<span class="fedistream-widget__title"><?php echo esc_html( $post['title'] ?? '' ); ?></span>
|
||||
<?php if ( ! empty( $post['artist'] ) ) : ?>
|
||||
<span class="fedistream-widget__artist"><?php echo esc_html( $post['artist'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
<?php if ( ! empty( $post['play_count'] ) ) : ?>
|
||||
<span class="fedistream-widget__plays"><?php echo esc_html( number_format( $post['play_count'] ) ); ?></span>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<button type="button" class="fedistream-widget__play" data-track-id="<?php echo esc_attr( $post['id'] ?? '' ); ?>" aria-label="<?php esc_attr_e( 'Play', 'wp-fedistream' ); ?>">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ol>
|
||||
<?php else : ?>
|
||||
<p class="fedistream-widget__empty"><?php esc_html_e( 'No tracks yet.', 'wp-fedistream' ); ?></p>
|
||||
<?php endif; ?>
|
||||
@@ -1,32 +0,0 @@
|
||||
{# Popular Tracks Widget Template #}
|
||||
{% if posts is not empty %}
|
||||
<ol class="fedistream-widget__list fedistream-widget__list--tracks">
|
||||
{% for post in posts %}
|
||||
<li class="fedistream-widget__item" data-track-id="{{ post.id }}">
|
||||
<a href="{{ post.permalink }}" class="fedistream-widget__link">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-widget__image">
|
||||
{% else %}
|
||||
<span class="fedistream-widget__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
<span class="fedistream-widget__info">
|
||||
<span class="fedistream-widget__title">{{ post.title }}</span>
|
||||
{% if post.artist %}
|
||||
<span class="fedistream-widget__artist">{{ post.artist }}</span>
|
||||
{% endif %}
|
||||
</span>
|
||||
{% if post.play_count %}
|
||||
<span class="fedistream-widget__plays">{{ post.play_count|number_format }}</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
<button type="button" class="fedistream-widget__play" data-track-id="{{ post.id }}" aria-label="{{ __('Play', 'wp-fedistream') }}">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
{% else %}
|
||||
<p class="fedistream-widget__empty">{{ __('No tracks yet.', 'wp-fedistream') }}</p>
|
||||
{% endif %}
|
||||
42
templates/widgets/recent-releases.php
Normal file
42
templates/widgets/recent-releases.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* Recent Releases Widget Template.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*
|
||||
* @var array $posts Array of album data.
|
||||
*/
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
<?php if ( ! empty( $posts ) && is_array( $posts ) ) : ?>
|
||||
<ul class="fedistream-widget__list fedistream-widget__list--releases">
|
||||
<?php foreach ( $posts as $post ) : ?>
|
||||
<li class="fedistream-widget__item">
|
||||
<a href="<?php echo esc_url( $post['permalink'] ?? '#' ); ?>" class="fedistream-widget__link">
|
||||
<?php if ( ! empty( $post['thumbnail'] ) ) : ?>
|
||||
<img src="<?php echo esc_url( $post['thumbnail'] ); ?>" alt="<?php echo esc_attr( $post['title'] ?? '' ); ?>" class="fedistream-widget__image">
|
||||
<?php else : ?>
|
||||
<span class="fedistream-widget__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></svg>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
<span class="fedistream-widget__info">
|
||||
<span class="fedistream-widget__title"><?php echo esc_html( $post['title'] ?? '' ); ?></span>
|
||||
<?php if ( ! empty( $post['artist_name'] ) ) : ?>
|
||||
<span class="fedistream-widget__artist"><?php echo esc_html( $post['artist_name'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
<?php if ( ! empty( $post['release_date'] ) ) : ?>
|
||||
<span class="fedistream-widget__date"><?php echo esc_html( $post['release_date'] ); ?></span>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<?php else : ?>
|
||||
<p class="fedistream-widget__empty"><?php esc_html_e( 'No releases yet.', 'wp-fedistream' ); ?></p>
|
||||
<?php endif; ?>
|
||||
@@ -1,29 +0,0 @@
|
||||
{# Recent Releases Widget Template #}
|
||||
{% if posts is not empty %}
|
||||
<ul class="fedistream-widget__list fedistream-widget__list--releases">
|
||||
{% for post in posts %}
|
||||
<li class="fedistream-widget__item">
|
||||
<a href="{{ post.permalink }}" class="fedistream-widget__link">
|
||||
{% if post.thumbnail %}
|
||||
<img src="{{ post.thumbnail }}" alt="{{ post.title|e('html_attr') }}" class="fedistream-widget__image">
|
||||
{% else %}
|
||||
<span class="fedistream-widget__placeholder">
|
||||
<svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/></svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
<span class="fedistream-widget__info">
|
||||
<span class="fedistream-widget__title">{{ post.title }}</span>
|
||||
{% if post.artist %}
|
||||
<span class="fedistream-widget__artist">{{ post.artist }}</span>
|
||||
{% endif %}
|
||||
{% if post.release_date %}
|
||||
<span class="fedistream-widget__date">{{ post.release_date }}</span>
|
||||
{% endif %}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<p class="fedistream-widget__empty">{{ __('No releases yet.', 'wp-fedistream') }}</p>
|
||||
{% endif %}
|
||||
@@ -3,7 +3,7 @@
|
||||
* Plugin Name: WP FediStream
|
||||
* Plugin URI: https://src.bundespruefstelle.ch/magdev/wp-fedistream
|
||||
* Description: Stream music over ActivityPub - Build your own music streaming platform for Musicians and Labels.
|
||||
* Version: 0.5.1
|
||||
* Version: 0.6.0
|
||||
* Requires at least: 6.4
|
||||
* Requires PHP: 8.3
|
||||
* Author: Marco Graetsch
|
||||
@@ -26,7 +26,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
define( 'WP_FEDISTREAM_VERSION', '0.5.1' );
|
||||
define( 'WP_FEDISTREAM_VERSION', '0.6.0' );
|
||||
|
||||
/**
|
||||
* Plugin file path.
|
||||
|
||||
Reference in New Issue
Block a user