diff --git a/CHANGELOG.md b/CHANGELOG.md
index cb73233..cbb6dca 100644
--- a/CHANGELOG.md
+++ b/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
diff --git a/CLAUDE.md b/CLAUDE.md
index c89640a..52f42c6 100644
--- a/CLAUDE.md
+++ b/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
diff --git a/README.md b/README.md
index bcd31d4..ca5a7f8 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/composer.json b/composer.json
index a1833ad..86f2584 100644
--- a/composer.json
+++ b/composer.json
@@ -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",
diff --git a/composer.lock b/composer.lock
index 4a9f004..2dda9b8 100644
--- a/composer.lock
+++ b/composer.lock
@@ -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": [
diff --git a/includes/Frontend/template-wrapper.php b/includes/Frontend/template-wrapper.php
index 9bd04ee..2b01e8c 100644
--- a/includes/Frontend/template-wrapper.php
+++ b/includes/Frontend/template-wrapper.php
@@ -1,6 +1,6 @@
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 array $context Template context variables.
+ * @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 '';
}
- // Prevent infinite recursion in Twig rendering.
+ // Prevent infinite recursion in rendering.
if ( self::$render_depth >= self::MAX_RENDER_DEPTH ) {
return '';
}
@@ -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.
*
diff --git a/templates/archive/album.php b/templates/archive/album.php
new file mode 100644
index 0000000..52b5dbd
--- /dev/null
+++ b/templates/archive/album.php
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ render_partial( 'partials/card-album', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/archive/album.twig b/templates/archive/album.twig
deleted file mode 100644
index 4d75f41..0000000
--- a/templates/archive/album.twig
+++ /dev/null
@@ -1,27 +0,0 @@
-{# Album archive template #}
-
-
-
- {% if posts is not empty %}
-
- {% for post in posts %}
- {% include 'partials/card-album.twig' with { post: post } %}
- {% endfor %}
-
-
- {% if pagination %}
-
- {% endif %}
- {% else %}
-
-
{{ __('No albums found.', 'wp-fedistream') }}
-
- {% endif %}
-
diff --git a/templates/archive/artist.php b/templates/archive/artist.php
new file mode 100644
index 0000000..467acfc
--- /dev/null
+++ b/templates/archive/artist.php
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ render_partial( 'partials/card-artist', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/archive/artist.twig b/templates/archive/artist.twig
deleted file mode 100644
index 4a77c38..0000000
--- a/templates/archive/artist.twig
+++ /dev/null
@@ -1,27 +0,0 @@
-{# Artist archive template #}
-
-
-
- {% if posts is not empty %}
-
- {% for post in posts %}
- {% include 'partials/card-artist.twig' with { post: post } %}
- {% endfor %}
-
-
- {% if pagination %}
-
- {% endif %}
- {% else %}
-
-
{{ __('No artists found.', 'wp-fedistream') }}
-
- {% endif %}
-
diff --git a/templates/archive/playlist.php b/templates/archive/playlist.php
new file mode 100644
index 0000000..7147122
--- /dev/null
+++ b/templates/archive/playlist.php
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ render_partial( 'partials/card-playlist', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/archive/playlist.twig b/templates/archive/playlist.twig
deleted file mode 100644
index 19ab615..0000000
--- a/templates/archive/playlist.twig
+++ /dev/null
@@ -1,27 +0,0 @@
-{# Playlist archive template #}
-
-
-
- {% if posts is not empty %}
-
- {% for post in posts %}
- {% include 'partials/card-playlist.twig' with { post: post } %}
- {% endfor %}
-
-
- {% if pagination %}
-
- {% endif %}
- {% else %}
-
-
{{ __('No playlists found.', 'wp-fedistream') }}
-
- {% endif %}
-
diff --git a/templates/archive/taxonomy.php b/templates/archive/taxonomy.php
new file mode 100644
index 0000000..37d03ba
--- /dev/null
+++ b/templates/archive/taxonomy.php
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+ 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;
+ }
+ ?>
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/archive/taxonomy.twig b/templates/archive/taxonomy.twig
deleted file mode 100644
index f92d2b0..0000000
--- a/templates/archive/taxonomy.twig
+++ /dev/null
@@ -1,37 +0,0 @@
-{# Taxonomy archive template (Genre, Mood) #}
-
-
-
- {% if posts is not empty %}
-
- {% 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 %}
-
-
- {% if pagination %}
-
- {% endif %}
- {% else %}
-
-
{{ __('No content found in this category.', 'wp-fedistream') }}
-
- {% endif %}
-
diff --git a/templates/archive/track.php b/templates/archive/track.php
new file mode 100644
index 0000000..10d2897
--- /dev/null
+++ b/templates/archive/track.php
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+ render_partial( 'partials/card-track', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/archive/track.twig b/templates/archive/track.twig
deleted file mode 100644
index f849fb3..0000000
--- a/templates/archive/track.twig
+++ /dev/null
@@ -1,27 +0,0 @@
-{# Track archive template #}
-
-
-
- {% if posts is not empty %}
-
- {% for post in posts %}
- {% include 'partials/card-track.twig' with { post: post } %}
- {% endfor %}
-
-
- {% if pagination %}
-
- {% endif %}
- {% else %}
-
-
{{ __('No tracks found.', 'wp-fedistream') }}
-
- {% endif %}
-
diff --git a/templates/partials/card-album.php b/templates/partials/card-album.php
new file mode 100644
index 0000000..66861b0
--- /dev/null
+++ b/templates/partials/card-album.php
@@ -0,0 +1,50 @@
+
+
+
+
+
+
![<?php echo esc_attr( $post['title'] ?? '' ); ?>](<?php echo esc_url( $post['thumbnail'] ); ?>)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 ) : ?>
+
+
+
+
+
+
+
diff --git a/templates/partials/card-album.twig b/templates/partials/card-album.twig
deleted file mode 100644
index 1db37b4..0000000
--- a/templates/partials/card-album.twig
+++ /dev/null
@@ -1,31 +0,0 @@
-{# Album card partial #}
-
-
-
- {% if post.thumbnail %}
-

- {% else %}
-
- {% endif %}
-
-
-
{{ post.title }}
- {% if post.artist_name %}
-
{{ post.artist_name }}
- {% endif %}
-
- {{ post.album_type_label }}
- {% if post.release_year %}
- {{ post.release_year }}
- {% endif %}
-
- {% if post.total_tracks > 0 %}
-
- {{ post.total_tracks }} {{ post.total_tracks == 1 ? 'track' : 'tracks' }}
-
- {% endif %}
-
-
-
diff --git a/templates/partials/card-artist.php b/templates/partials/card-artist.php
new file mode 100644
index 0000000..81973ed
--- /dev/null
+++ b/templates/partials/card-artist.php
@@ -0,0 +1,47 @@
+
+
+
+
+
+
![<?php echo esc_attr( $post['title'] ?? '' ); ?>](<?php echo esc_url( $post['thumbnail'] ); ?>)
+
+
+
+
+
+
+
+
+
+
+
+
+ 0 ) : ?>
+
+
+
+
+
+
+
diff --git a/templates/partials/card-artist.twig b/templates/partials/card-artist.twig
deleted file mode 100644
index 06282fc..0000000
--- a/templates/partials/card-artist.twig
+++ /dev/null
@@ -1,28 +0,0 @@
-{# Artist card partial #}
-
-
-
- {% if post.thumbnail %}
-

- {% else %}
-
- {% endif %}
-
-
-
{{ post.title }}
-
- {{ post.artist_type_label }}
- {% if post.location %}
- {{ post.location }}
- {% endif %}
-
- {% if post.album_count is defined and post.album_count > 0 %}
-
- {{ post.album_count }} {{ post.album_count == 1 ? 'album' : 'albums' }}
-
- {% endif %}
-
-
-
diff --git a/templates/partials/card-playlist.php b/templates/partials/card-playlist.php
new file mode 100644
index 0000000..e10d402
--- /dev/null
+++ b/templates/partials/card-playlist.php
@@ -0,0 +1,54 @@
+
+
+
+
+
+
![<?php echo esc_attr( $post['title'] ?? '' ); ?>](<?php echo esc_url( $post['thumbnail'] ); ?>)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/partials/card-playlist.twig b/templates/partials/card-playlist.twig
deleted file mode 100644
index 5303252..0000000
--- a/templates/partials/card-playlist.twig
+++ /dev/null
@@ -1,29 +0,0 @@
-{# Playlist card partial #}
-
-
-
- {% if post.thumbnail %}
-

- {% else %}
-
- {% endif %}
- {% if post.visibility == 'private' %}
-
-
-
- {% endif %}
-
-
-
{{ post.title }}
-
{{ post.author }}
-
- {{ post.track_count }} {{ post.track_count == 1 ? 'track' : 'tracks' }}
- {% if post.duration_formatted %}
- {{ post.duration_formatted }}
- {% endif %}
-
-
-
-
diff --git a/templates/partials/card-track.php b/templates/partials/card-track.php
new file mode 100644
index 0000000..afe5c90
--- /dev/null
+++ b/templates/partials/card-track.php
@@ -0,0 +1,56 @@
+
+
+
+
+
+
![<?php echo esc_attr( $post['title'] ?? '' ); ?>](<?php echo esc_url( $post['thumbnail'] ); ?>)
+
+
![<?php echo esc_attr( $post['title'] ?? '' ); ?>](<?php echo esc_url( $post['album_artwork'] ); ?>)
+
+
+
+
+
E
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/partials/card-track.twig b/templates/partials/card-track.twig
deleted file mode 100644
index 8f72457..0000000
--- a/templates/partials/card-track.twig
+++ /dev/null
@@ -1,37 +0,0 @@
-{# Track card partial #}
-
-
-
- {% if post.thumbnail %}
-

- {% elseif post.album_artwork %}
-

- {% else %}
-
- {% endif %}
- {% if post.explicit %}
-
E
- {% endif %}
-
-
-
{{ post.title }}
- {% if post.artists %}
-
- {% for artist in post.artists %}
- {{ artist.name }}{% if not loop.last %}, {% endif %}
- {% endfor %}
-
- {% endif %}
-
- {% if post.album_title %}
- {{ post.album_title }}
- {% endif %}
- {% if post.duration_formatted %}
- {{ post.duration_formatted }}
- {% endif %}
-
-
-
-
diff --git a/templates/shortcodes/album.php b/templates/shortcodes/album.php
new file mode 100644
index 0000000..28f9585
--- /dev/null
+++ b/templates/shortcodes/album.php
@@ -0,0 +1,89 @@
+
+
diff --git a/templates/shortcodes/album.twig b/templates/shortcodes/album.twig
deleted file mode 100644
index 2467660..0000000
--- a/templates/shortcodes/album.twig
+++ /dev/null
@@ -1,64 +0,0 @@
-{# Album shortcode template #}
-
-
-
-
- {% if show_tracks and post.tracks is not empty %}
-
-
- {% for track in post.tracks %}
-
-
{{ track.track_number|default(loop.index) }}
-
- {% if track.duration_formatted %}
-
{{ track.duration_formatted }}
- {% endif %}
-
-
- {% endfor %}
-
-
- {% endif %}
-
-
diff --git a/templates/shortcodes/artist.php b/templates/shortcodes/artist.php
new file mode 100644
index 0000000..dd6a4ed
--- /dev/null
+++ b/templates/shortcodes/artist.php
@@ -0,0 +1,84 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ render_partial( 'partials/card-album', array( 'post' => $album ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/shortcodes/artist.twig b/templates/shortcodes/artist.twig
deleted file mode 100644
index 31c4305..0000000
--- a/templates/shortcodes/artist.twig
+++ /dev/null
@@ -1,65 +0,0 @@
-{# Artist shortcode template #}
-
-
-
-
- {% if layout == 'full' and post.content %}
-
- {{ post.content|raw }}
-
- {% endif %}
-
- {% if show_albums and post.albums is not empty %}
-
-
{{ __('Albums', 'wp-fedistream') }}
-
- {% for album in post.albums|slice(0, 4) %}
- {% include 'partials/card-album.twig' with { post: album } %}
- {% endfor %}
-
-
- {% endif %}
-
- {% if show_tracks and post.tracks is not empty %}
-
-
{{ __('Popular Tracks', 'wp-fedistream') }}
-
- {% for track in post.tracks|slice(0, 5) %}
-
-
{{ loop.index }}
-
- {% if track.duration_formatted %}
-
{{ track.duration_formatted }}
- {% endif %}
-
- {% endfor %}
-
-
- {% endif %}
-
-
diff --git a/templates/shortcodes/artists-grid.php b/templates/shortcodes/artists-grid.php
new file mode 100644
index 0000000..d9d3db8
--- /dev/null
+++ b/templates/shortcodes/artists-grid.php
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+ render_partial( 'partials/card-artist', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
+
+
+
+
+
+
diff --git a/templates/shortcodes/artists-grid.twig b/templates/shortcodes/artists-grid.twig
deleted file mode 100644
index b8abf11..0000000
--- a/templates/shortcodes/artists-grid.twig
+++ /dev/null
@@ -1,18 +0,0 @@
-{# Artists grid shortcode template #}
-
- {% if title %}
-
{{ title }}
- {% endif %}
-
- {% if posts is not empty %}
-
- {% for post in posts %}
- {% include 'partials/card-artist.twig' with { post: post } %}
- {% endfor %}
-
- {% else %}
-
-
{{ __('No artists found.', 'wp-fedistream') }}
-
- {% endif %}
-
diff --git a/templates/shortcodes/player.php b/templates/shortcodes/player.php
new file mode 100644
index 0000000..b3285ae
--- /dev/null
+++ b/templates/shortcodes/player.php
@@ -0,0 +1,127 @@
+ 1;
+?>
+
+
+
+
+
+
![<?php echo esc_attr( $first_track['title'] ?? '' ); ?>](<?php echo esc_url( $first_track['thumbnail'] ); ?>)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
$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 ) ) ); ?>'>
+
+ $track ) : ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/shortcodes/player.twig b/templates/shortcodes/player.twig
deleted file mode 100644
index 6f1cad4..0000000
--- a/templates/shortcodes/player.twig
+++ /dev/null
@@ -1,108 +0,0 @@
-{# Audio player shortcode template #}
-
diff --git a/templates/shortcodes/playlist.php b/templates/shortcodes/playlist.php
new file mode 100644
index 0000000..64a5977
--- /dev/null
+++ b/templates/shortcodes/playlist.php
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+ $track ) : ?>
+
+
+
+
; ?>)
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/shortcodes/playlist.twig b/templates/shortcodes/playlist.twig
deleted file mode 100644
index 9fe5241..0000000
--- a/templates/shortcodes/playlist.twig
+++ /dev/null
@@ -1,71 +0,0 @@
-{# Playlist shortcode template #}
-
-
-
-
- {% if show_tracks and post.tracks is not empty %}
-
-
- {% for track in post.tracks %}
-
-
{{ loop.index }}
- {% if track.thumbnail %}
-

- {% endif %}
-
- {% if track.duration_formatted %}
-
{{ track.duration_formatted }}
- {% endif %}
-
-
- {% endfor %}
-
-
- {% endif %}
-
-
diff --git a/templates/shortcodes/releases-grid.php b/templates/shortcodes/releases-grid.php
new file mode 100644
index 0000000..d827563
--- /dev/null
+++ b/templates/shortcodes/releases-grid.php
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+ render_partial( 'partials/card-album', array( 'post' => $post ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
+
+
+
+
+
+
diff --git a/templates/shortcodes/releases-grid.twig b/templates/shortcodes/releases-grid.twig
deleted file mode 100644
index 3accf3d..0000000
--- a/templates/shortcodes/releases-grid.twig
+++ /dev/null
@@ -1,18 +0,0 @@
-{# Latest releases grid shortcode template #}
-
- {% if title %}
-
{{ title }}
- {% endif %}
-
- {% if posts is not empty %}
-
- {% for post in posts %}
- {% include 'partials/card-album.twig' with { post: post } %}
- {% endfor %}
-
- {% else %}
-
-
{{ __('No releases found.', 'wp-fedistream') }}
-
- {% endif %}
-
diff --git a/templates/shortcodes/track.php b/templates/shortcodes/track.php
new file mode 100644
index 0000000..6cb61ae
--- /dev/null
+++ b/templates/shortcodes/track.php
@@ -0,0 +1,97 @@
+
+
diff --git a/templates/shortcodes/track.twig b/templates/shortcodes/track.twig
deleted file mode 100644
index e04cd90..0000000
--- a/templates/shortcodes/track.twig
+++ /dev/null
@@ -1,64 +0,0 @@
-{# Track shortcode template #}
-
-
-
-
- {% if show_player and post.audio_url %}
-
-
-
-
-
{{ post.duration_formatted|default('0:00') }}
-
-
- {% endif %}
-
-
diff --git a/templates/shortcodes/tracks-list.php b/templates/shortcodes/tracks-list.php
new file mode 100644
index 0000000..1675088
--- /dev/null
+++ b/templates/shortcodes/tracks-list.php
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+
+ $post ) : ?>
+
+
+
+
; ?>)
+
+
+
+
+
+
+
+ %s',
+ esc_url( $artist['url'] ?? '#' ),
+ esc_html( $artist['name'] ?? '' )
+ );
+ }
+ echo implode( ', ', $artist_links ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/shortcodes/tracks-list.twig b/templates/shortcodes/tracks-list.twig
deleted file mode 100644
index 659da4e..0000000
--- a/templates/shortcodes/tracks-list.twig
+++ /dev/null
@@ -1,48 +0,0 @@
-{# Popular tracks list shortcode template #}
-
- {% if title %}
-
{{ title }}
- {% endif %}
-
- {% if posts is not empty %}
-
- {% for post in posts %}
-
-
{{ loop.index }}
- {% if post.thumbnail %}
-

- {% else %}
-
- {% endif %}
-
-
{{ post.title }}
-
- {% if post.artists is iterable %}
- {% for artist in post.artists %}
- {{ artist.name }}{% if not loop.last %}, {% endif %}
- {% endfor %}
- {% else %}
- {{ post.artist }}
- {% endif %}
-
-
- {% if post.play_count %}
-
{{ post.play_count|number_format }}
- {% endif %}
- {% if post.duration_formatted %}
-
{{ post.duration_formatted }}
- {% endif %}
-
-
- {% endfor %}
-
- {% else %}
-
-
{{ __('No tracks found.', 'wp-fedistream') }}
-
- {% endif %}
-
diff --git a/templates/single/album.php b/templates/single/album.php
new file mode 100644
index 0000000..e75d25b
--- /dev/null
+++ b/templates/single/album.php
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+ $track ) : ?>
+
+
+
+
+
E
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/single/album.twig b/templates/single/album.twig
deleted file mode 100644
index 85007d6..0000000
--- a/templates/single/album.twig
+++ /dev/null
@@ -1,105 +0,0 @@
-{# Single album template #}
-
-
-
- {% if post.tracks is not empty %}
-
-
- {% for track in post.tracks %}
-
-
{{ track.track_number|default(loop.index) }}
-
-
{{ track.title }}
- {% if track.featured_artists %}
-
{{ __('feat.', 'wp-fedistream') }} {{ track.featured_artists }}
- {% endif %}
-
- {% if track.explicit %}
-
E
- {% endif %}
- {% if track.duration_formatted %}
-
{{ track.duration_formatted }}
- {% endif %}
-
-
- {% endfor %}
-
-
- {% endif %}
-
- {% if post.content %}
-
- {{ __('About This Album', 'wp-fedistream') }}
-
- {{ post.content|raw }}
-
-
- {% endif %}
-
- {% if post.credits %}
-
- {{ __('Credits', 'wp-fedistream') }}
-
- {{ post.credits|raw }}
-
-
- {% endif %}
-
- {% if post.license %}
-
- {% endif %}
-
diff --git a/templates/single/artist.php b/templates/single/artist.php
new file mode 100644
index 0000000..907a5c3
--- /dev/null
+++ b/templates/single/artist.php
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ render_partial( 'partials/card-album', array( 'post' => $album ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
+
+
+
+
+
+
+
+
+
+ $track ) : ?>
+
+
+
+
; ?>)
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/single/artist.twig b/templates/single/artist.twig
deleted file mode 100644
index e958c0f..0000000
--- a/templates/single/artist.twig
+++ /dev/null
@@ -1,88 +0,0 @@
-{# Single artist template #}
-
-
-
- {% if post.content %}
-
- {{ __('About', 'wp-fedistream') }}
-
- {{ post.content|raw }}
-
-
- {% endif %}
-
- {% if post.social_links is not empty %}
-
- {{ __('Connect', 'wp-fedistream') }}
-
-
- {% endif %}
-
- {% if post.albums is not empty %}
-
- {{ __('Discography', 'wp-fedistream') }}
-
- {% for album in post.albums %}
- {% include 'partials/card-album.twig' with { post: album } %}
- {% endfor %}
-
-
- {% endif %}
-
- {% if post.tracks is not empty %}
-
- {{ __('Popular Tracks', 'wp-fedistream') }}
-
- {% for track in post.tracks %}
-
-
{{ loop.index }}
- {% if track.thumbnail %}
-

- {% endif %}
-
- {% if track.duration_formatted %}
-
{{ track.duration_formatted }}
- {% endif %}
-
-
- {% endfor %}
-
-
- {% endif %}
-
diff --git a/templates/single/playlist.php b/templates/single/playlist.php
new file mode 100644
index 0000000..3b60e4a
--- /dev/null
+++ b/templates/single/playlist.php
@@ -0,0 +1,136 @@
+
+
+
+
+
+
+
+
+
+
+
+ $track ) : ?>
+
+
+
+
; ?>)
+
+
+
+
+
+ %s',
+ esc_url( $artist['url'] ?? '#' ),
+ esc_html( $artist['name'] ?? '' )
+ );
+ }
+ echo implode( ', ', $artist_links ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
+ ?>
+
+
+
+
+
+
+
E
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/single/playlist.twig b/templates/single/playlist.twig
deleted file mode 100644
index 3ce4d6d..0000000
--- a/templates/single/playlist.twig
+++ /dev/null
@@ -1,107 +0,0 @@
-{# Single playlist template #}
-
-
-
- {% if post.content %}
-
-
- {{ post.content|raw }}
-
-
- {% endif %}
-
- {% if post.tracks is not empty %}
-
-
- {% for track in post.tracks %}
-
-
{{ loop.index }}
- {% if track.thumbnail %}
-

- {% endif %}
-
-
{{ track.title }}
-
- {% if track.artists is iterable %}
- {% for artist in track.artists %}
- {{ artist.name }}{% if not loop.last %}, {% endif %}
- {% endfor %}
- {% else %}
- {{ track.artist }}
- {% endif %}
-
-
- {% if track.explicit %}
-
E
- {% endif %}
- {% if track.duration_formatted %}
-
{{ track.duration_formatted }}
- {% endif %}
-
-
- {% endfor %}
-
-
- {% else %}
-
-
-
{{ __('This playlist is empty.', 'wp-fedistream') }}
-
-
- {% endif %}
-
diff --git a/templates/single/track.php b/templates/single/track.php
new file mode 100644
index 0000000..4f531f8
--- /dev/null
+++ b/templates/single/track.php
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/single/track.twig b/templates/single/track.twig
deleted file mode 100644
index 102fe32..0000000
--- a/templates/single/track.twig
+++ /dev/null
@@ -1,120 +0,0 @@
-{# Single track template #}
-
-
-
- {% if post.audio_url %}
-
-
-
-
-
0:00
-
-
{{ post.duration_formatted|default('0:00') }}
-
-
-
-
- {% endif %}
-
- {% if post.content %}
-
- {{ __('About This Track', 'wp-fedistream') }}
-
- {{ post.content|raw }}
-
-
- {% endif %}
-
- {% if post.lyrics %}
-
- {{ __('Lyrics', 'wp-fedistream') }}
-
- {{ post.lyrics|nl2br }}
-
-
- {% endif %}
-
- {% if post.credits %}
-
- {{ __('Credits', 'wp-fedistream') }}
-
- {{ post.credits|raw }}
-
-
- {% endif %}
-
- {% if post.license %}
-
- {% endif %}
-
diff --git a/templates/widgets/featured-artist.php b/templates/widgets/featured-artist.php
new file mode 100644
index 0000000..5fcae21
--- /dev/null
+++ b/templates/widgets/featured-artist.php
@@ -0,0 +1,70 @@
+
+
+
+
+
+
diff --git a/templates/widgets/featured-artist.twig b/templates/widgets/featured-artist.twig
deleted file mode 100644
index 1fc1fa7..0000000
--- a/templates/widgets/featured-artist.twig
+++ /dev/null
@@ -1,41 +0,0 @@
-{# Featured Artist Widget Template #}
-{% if post %}
-
-{% else %}
- {{ __('No artist selected.', 'wp-fedistream') }}
-{% endif %}
diff --git a/templates/widgets/now-playing.twig b/templates/widgets/now-playing.php
similarity index 74%
rename from templates/widgets/now-playing.twig
rename to templates/widgets/now-playing.php
index 473a60c..e6cdde1 100644
--- a/templates/widgets/now-playing.twig
+++ b/templates/widgets/now-playing.php
@@ -1,10 +1,25 @@
-{# Now Playing Widget Template #}
+
-
{{ __('Nothing playing', 'wp-fedistream') }}
+
- {% if show_player %}
+
@@ -36,6 +51,6 @@
0:00
- {% endif %}
+
diff --git a/templates/widgets/popular-tracks.php b/templates/widgets/popular-tracks.php
new file mode 100644
index 0000000..4ad2860
--- /dev/null
+++ b/templates/widgets/popular-tracks.php
@@ -0,0 +1,45 @@
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/widgets/popular-tracks.twig b/templates/widgets/popular-tracks.twig
deleted file mode 100644
index c4afdaa..0000000
--- a/templates/widgets/popular-tracks.twig
+++ /dev/null
@@ -1,32 +0,0 @@
-{# Popular Tracks Widget Template #}
-{% if posts is not empty %}
-
- {% for post in posts %}
- -
-
- {% if post.thumbnail %}
-
- {% else %}
-
-
-
- {% endif %}
-
- {{ post.title }}
- {% if post.artist %}
- {{ post.artist }}
- {% endif %}
-
- {% if post.play_count %}
- {{ post.play_count|number_format }}
- {% endif %}
-
-
-
- {% endfor %}
-
-{% else %}
- {{ __('No tracks yet.', 'wp-fedistream') }}
-{% endif %}
diff --git a/templates/widgets/recent-releases.php b/templates/widgets/recent-releases.php
new file mode 100644
index 0000000..8481525
--- /dev/null
+++ b/templates/widgets/recent-releases.php
@@ -0,0 +1,42 @@
+
+
+
+
+
+
diff --git a/templates/widgets/recent-releases.twig b/templates/widgets/recent-releases.twig
deleted file mode 100644
index 61c79f7..0000000
--- a/templates/widgets/recent-releases.twig
+++ /dev/null
@@ -1,29 +0,0 @@
-{# Recent Releases Widget Template #}
-{% if posts is not empty %}
-
-{% else %}
- {{ __('No releases yet.', 'wp-fedistream') }}
-{% endif %}
diff --git a/wp-fedistream.php b/wp-fedistream.php
index cc155e0..872522c 100644
--- a/wp-fedistream.php
+++ b/wp-fedistream.php
@@ -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.