Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "werkstattl/openblogware",
"description": "OpenBlogware: A Blog Module for Shopware 6.",
"version": "5.0.2",
"version": "5.1.0",
"type": "shopware-platform-plugin",
"keywords": ["blog", "news"],
"license":"MIT",
Expand Down
2 changes: 1 addition & 1 deletion src/Content/Blog/BlogSeoUrlRoute.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class BlogSeoUrlRoute implements SeoUrlRouteInterface
{
public const ROUTE_NAME = 'werkl.frontend.blog.detail';
public const DEFAULT_TEMPLATE = 'blog/{{ entry.blogCategories.first.translated.name|lower }}/{{ entry.translated.title|lower }}';
public const DEFAULT_TEMPLATE = 'blog/{{ entry.blogCategories.first.translated.name|lower }}/{{ entry.translated.slug|lower }}';

public function __construct(private readonly BlogEntryDefinition $blogEntryDefinition)
{
Expand Down
47 changes: 47 additions & 0 deletions src/Migration/Migration1767122033UpdateSeoUrlTemplateToUseSlug.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php
declare(strict_types=1);

namespace Werkl\OpenBlogware\Migration;

use Doctrine\DBAL\Connection;
use Shopware\Core\Framework\Migration\MigrationStep;

class Migration1767122033UpdateSeoUrlTemplateToUseSlug extends MigrationStep
{
public function getCreationTimestamp(): int
{
return 1767122033;
}

public function update(Connection $connection): void
{
// Update the SEO URL template to use slug instead of title
// This handles both old and new template formats
// This will cause all blog entry SEO URLs to be regenerated

// Update the newer template format (with categories)
$connection->executeStatement(
<<<SQL
UPDATE `seo_url_template`
SET `template` = 'blog/{{ entry.blogCategories.first.translated.name|lower }}/{{ entry.translated.slug|lower }}'
WHERE `entity_name` = 'werkl_blog_entry'
AND `template` = 'blog/{{ entry.blogCategories.first.translated.name|lower }}/{{ entry.translated.title|lower }}'
SQL
);

// Update the original template format (without categories)
$connection->executeStatement(
<<<SQL
UPDATE `seo_url_template`
SET `template` = 'blog/{{ entry.translated.slug|lower }}'
WHERE `entity_name` = 'werkl_blog_entry'
AND `template` = 'blog/{{ entry.translated.title|lower }}'
SQL
);
}

public function updateDestructive(Connection $connection): void
{
// No destructive changes needed
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
<mt-text-field
v-model="blog.slug"
required
disabled
:label="$tc('werkl-blog.detail.slugLabel')"
:placeholder="$tc('werkl-blog.detail.slugPlaceholder')"
:error="blogSlugError"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ export default {
localeLanguage: null,
showSectionModal: false,
sectionDontRemind: false,
slugManuallyEdited: false,
autoGeneratedSlug: null,
isAutoGenerating: false,
};
},

Expand Down Expand Up @@ -89,6 +92,22 @@ export default {
'blog.title': function (blogTitle) {
this.onBlogTitleChanged(blogTitle);
},
'blog.slug': function (newSlug) {
// Only mark as manually edited if we're not currently auto-generating
// For new blogs (autoGeneratedSlug is null), any slug value means manual edit
// For existing blogs or after first auto-generation, check if different from auto-generated
if (!this.isAutoGenerating) {
if (this.autoGeneratedSlug === null || this.autoGeneratedSlug === undefined) {
// New blog: if user types a slug before auto-generation, mark as manual
if (newSlug) {
this.slugManuallyEdited = true;
}
} else if (newSlug !== this.autoGeneratedSlug) {
// Existing blog or after auto-generation: check if different
this.slugManuallyEdited = true;
}
}
},
},

methods: {
Expand Down Expand Up @@ -151,6 +170,11 @@ export default {
return this.blogRepository.get(blogId, Context.api, this.loadBlogCriteria).then((entity) => {
this.blog = entity;
this.originalSlug = entity.slug;
// For existing blogs, mark slug as manually edited to prevent auto-updates
// This ensures URL stability for published content
this.slugManuallyEdited = true;
// Initialize auto-generated slug with the current slug
this.autoGeneratedSlug = entity.slug;

if (this.blog.translated.mediaId) {
this.mediaRepository.get(this.blog.translated.mediaId).then((media) => {
Expand Down Expand Up @@ -389,7 +413,13 @@ export default {

this.page.name = blogTitle;
this.getLocaleLanguage();
this.generateSlug(blogTitle);

// Only auto-generate slug if:
// 1. The slug is empty (new blog entry)
// 2. OR the slug hasn't been manually edited (still matches auto-generated format)
if (!this.blog.slug || !this.slugManuallyEdited) {
this.generateSlug(blogTitle);
}
}, debounceTimeout),

addBlogError({
Expand Down Expand Up @@ -428,8 +458,13 @@ export default {
lower: true,
});

// Mark that we're auto-generating to avoid triggering manual edit detection
this.isAutoGenerating = true;

if (!this.localeLanguage) {
this.blog.slug = slug;
this.autoGeneratedSlug = slug;
this.isAutoGenerating = false;
return;
}

Expand All @@ -445,8 +480,14 @@ export default {
} else {
this.blog.slug = slug;
}

// After auto-generating, store this as the expected auto-generated slug
this.autoGeneratedSlug = this.blog.slug;
this.isAutoGenerating = false;
}).catch(() => {
this.blog.slug = slug;
this.autoGeneratedSlug = this.blog.slug;
this.isAutoGenerating = false;
});
},

Expand Down
8 changes: 4 additions & 4 deletions src/Resources/public/administration/.vite/entrypoints.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,19 @@
"/bundles/werklopenblogware/administration/assets/index-Nv1kM84q.js",
"/bundles/werklopenblogware/administration/assets/index-djFVmhQq.js",
"/bundles/werklopenblogware/administration/assets/index-CB3s9RZ7.js",
"/bundles/werklopenblogware/administration/assets/index-RInXDG-m.js",
"/bundles/werklopenblogware/administration/assets/index-DQF0lEx3.js",
"/bundles/werklopenblogware/administration/assets/index-B1VMVOxB.js",
"/bundles/werklopenblogware/administration/assets/index-CnzDf3uJ.js",
"/bundles/werklopenblogware/administration/assets/index-DiCmnIhU.js",
"/bundles/werklopenblogware/administration/assets/index-DLbe5nbw.js",
"/bundles/werklopenblogware/administration/assets/index-DE9rQuyz.js",
"/bundles/werklopenblogware/administration/assets/index-OQ9pEuOh.js",
"/bundles/werklopenblogware/administration/assets/index-Dck_g9tK.js",
"/bundles/werklopenblogware/administration/assets/index-C1ThOcnB.js",
"/bundles/werklopenblogware/administration/assets/index-CI7M06HE.js",
"/bundles/werklopenblogware/administration/assets/index-BmZACn-g.js",
"/bundles/werklopenblogware/administration/assets/index-C293HHHL.js"
],
"js": [
"/bundles/werklopenblogware/administration/assets/werkl-open-blogware-DEy1Vkif.js"
"/bundles/werklopenblogware/administration/assets/werkl-open-blogware-DwBt8tES.js"
],
"legacy": false,
"preload": []
Expand Down
8 changes: 4 additions & 4 deletions src/Resources/public/administration/.vite/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"main.js": {
"file": "assets/werkl-open-blogware-DEy1Vkif.js",
"file": "assets/werkl-open-blogware-DwBt8tES.js",
"name": "werkl-open-blogware",
"src": "main.js",
"isEntry": true,
Expand Down Expand Up @@ -279,7 +279,7 @@
]
},
"module/blog-module/extension/component/cms/werkl-cms-sidebar/index.js": {
"file": "assets/index-RInXDG-m.js",
"file": "assets/index-DQF0lEx3.js",
"name": "index",
"src": "module/blog-module/extension/component/cms/werkl-cms-sidebar/index.js",
"isDynamicEntry": true,
Expand All @@ -297,7 +297,7 @@
]
},
"module/blog-module/extension/sw-cms/component/sw-cms-sidebar/index.js": {
"file": "assets/index-CnzDf3uJ.js",
"file": "assets/index-DiCmnIhU.js",
"name": "index",
"src": "module/blog-module/extension/sw-cms/component/sw-cms-sidebar/index.js",
"isDynamicEntry": true,
Expand Down Expand Up @@ -342,7 +342,7 @@
"isDynamicEntry": true
},
"module/blog-module/page/werkl-blog-detail/index.js": {
"file": "assets/index-CI7M06HE.js",
"file": "assets/index-BmZACn-g.js",
"name": "index",
"src": "module/blog-module/page/werkl-blog-detail/index.js",
"isDynamicEntry": true,
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

This file was deleted.

2 changes: 2 additions & 0 deletions src/Resources/public/administration/assets/index-DQF0lEx3.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading