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
5 changes: 5 additions & 0 deletions .changeset/better-symbols-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"strapi-plugin-webtools": patch
---

fix: alias gets -0 suffix when updating non-i18n document
14 changes: 8 additions & 6 deletions packages/core/admin/containers/App/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Link,
} from 'react-router-dom';

import { useIntl } from 'react-intl';
import {
SubNav,
SubNavHeader,
Expand Down Expand Up @@ -34,6 +35,7 @@ const App = () => {
const {
allowedActions: { canList, canPatterns, canOverview },
} = useRBAC(pluginPermissions);
const { formatMessage } = useIntl();

const plugin = getPlugin(pluginId);

Expand All @@ -50,18 +52,18 @@ const App = () => {
<SubNavSections>
<SubNavSection label="Core">
{canOverview && (
<SubNavLink tag={Link} to="/plugins/webtools" key="test" className={currentPath === '/plugins/webtools' ? 'active' : ''}>
Overview
<SubNavLink tag={Link} to="/plugins/webtools" key="overview" className={currentPath === '/plugins/webtools' ? 'active' : ''}>
{formatMessage({ id: 'webtools.settings.page.overview.title', defaultMessage: 'Overview' })}
</SubNavLink>
)}
{canList && (
<SubNavLink tag={Link} to="/plugins/webtools/urls" key="test" className={currentPath.startsWith('/plugins/webtools/urls') ? 'active' : ''}>
All URLs
<SubNavLink tag={Link} to="/plugins/webtools/urls" key="list" className={currentPath.startsWith('/plugins/webtools/urls') ? 'active' : ''}>
{formatMessage({ id: 'webtools.settings.page.list.title', defaultMessage: 'All URLs' })}
</SubNavLink>
)}
{canPatterns && (
<SubNavLink tag={Link} to="/plugins/webtools/patterns" key="test" className={currentPath.startsWith('/plugins/webtools/patterns') ? 'active' : ''}>
Url Patterns
<SubNavLink tag={Link} to="/plugins/webtools/patterns" key="patterns" className={currentPath.startsWith('/plugins/webtools/patterns') ? 'active' : ''}>
{formatMessage({ id: 'webtools.settings.page.patterns.title', defaultMessage: 'URL patterns' })}
</SubNavLink>
)}
</SubNavSection>
Expand Down
2 changes: 1 addition & 1 deletion packages/core/admin/screens/List/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ const List = () => {
return (
<Page.Protect permissions={pluginPermissions['settings.list']}>
<Layouts.Header
title={formatMessage({ id: 'webtools.settings.page.list.title', defaultMessage: 'URLs' })}
title={formatMessage({ id: 'webtools.settings.page.list.title', defaultMessage: 'All URLs' })}
subtitle={formatMessage({ id: 'webtools.settings.page.list.description', defaultMessage: 'A list of all the known URL aliases.' })}
primaryAction={(
<GeneratePathsModal
Expand Down
2 changes: 1 addition & 1 deletion packages/core/admin/screens/Patterns/ListPage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ const ListPatternPage = () => {
<Page.Protect permissions={pluginPermissions['settings.patterns']}>
<Box>
<Layouts.Header
title={formatMessage({ id: 'webtools.settings.page.patterns.title', defaultMessage: 'Patterns' })}
title={formatMessage({ id: 'webtools.settings.page.patterns.title', defaultMessage: 'URL patterns' })}
subtitle={formatMessage({ id: 'webtools.settings.page.patterns.description', defaultMessage: 'A list of all the known URL alias patterns.' })}
primaryAction={(
<Button onClick={() => navigate(`/plugins/${pluginId}/patterns/new`)} startIcon={<Plus />}>
Expand Down
5 changes: 4 additions & 1 deletion packages/core/admin/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
"settings.form.pattern.description_3": "or",
"settings.form.contenttype.label": "Content type",

"settings.page.overview.title": "Overview",
"settings.page.overview.description": "Webtools global information",

"settings.page.list.title": "All URLs",
"settings.page.list.description": "A list of all the known URL aliases.",
"settings.page.list.body": "List all URL aliases",
Expand Down Expand Up @@ -65,5 +68,5 @@
"settings.page.patterns.create.subtitle": "Pattern details",
"settings.page.patterns.create.description": "Add a pattern for automatic URL alias generation.",

"notification.success.permalink_copied": "Permalinkk copied to the clipboard"
"notification.success.permalink_copied": "Permalink copied to the clipboard"
}
3 changes: 3 additions & 0 deletions packages/core/admin/translations/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
"settings.form.pattern.description_3": "of",
"settings.form.contenttype.label": "Inhoudstype",

"settings.page.overview.title": "Overzicht",
"settings.page.overview.description": "Algemene Webtools informatie",

"settings.page.list.title": "Alle URL's",
"settings.page.list.description": "Een lijst met alle bekende URL-aliassen.",
"settings.page.list.body": "Laat alle URL-aliassen zien",
Expand Down
22 changes: 22 additions & 0 deletions packages/core/server/middlewares/__tests__/middlewares.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,28 @@ describe('Query layer decorator', () => {
expect(updatedPage).toHaveProperty('url_alias[0].url_path', url);
});

it('Update - Should not duplicate check the same entry when updated - no i18n', async () => {
const category = await strapi.documents('api::category.category').create({
data: {
title: 'A category',
},
populate: ['url_alias'],
});

console.log(category);
expect(category).toHaveProperty('url_alias[0].url_path', '/category/a-category');

const updatedCategory = await strapi.documents('api::category.category').update({
documentId: category.documentId,
data: {
published_at: new Date(),
},
populate: ['url_alias'],
});

expect(updatedCategory).toHaveProperty('url_alias[0].url_path', '/category/a-category');
});

it('Delete - Should delete the corresponding URL alias as well', async () => {
const page = await strapi.documents('api::test.test').create({
data: {
Expand Down
9 changes: 5 additions & 4 deletions packages/core/server/middlewares/generate-url-alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ const generateUrlAliasMiddleware: Modules.Documents.Middleware.Middleware = asyn

// Fetch the URL pattern for this content type.
let relations: string[] = [];
let languages: string[] = [undefined];
let urlAliasEntity: Data.ContentType<'plugin::webtools.url-alias'> | undefined;

languages = [];
const locales = await strapi.entityService.findMany('plugin::i18n.locale', {});
languages = locales.map((locale) => locale.code);
let languages: (string | undefined)[] = [undefined];
if (params.locale) {
const locales = await strapi.entityService.findMany('plugin::i18n.locale', {});
languages = locales.map((locale) => locale.code);
}

await Promise.all(languages.map(async (lang) => {
const urlPatterns = await getPluginService('url-pattern').findByUid(uid, lang);
Expand Down
22 changes: 9 additions & 13 deletions packages/core/server/services/bulk-generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,12 @@ const generateUrlAliases = async (params: GenerateParams): Promise<number> => {

let relations: string[] = [];

const locales = await strapi.documents('plugin::i18n.locale').findMany({});
const languages = locales.map((locale) => locale.code);

// Get all relations for the type
await Promise.all(languages.map(async (lang) => {
const urlPatterns = await getPluginService('url-pattern').findByUid(type, lang);
urlPatterns.forEach((urlPattern) => {
const languageRelations = getPluginService('url-pattern').getRelationsFromPattern(urlPattern);
relations = [...relations, ...languageRelations];
});
}));
// Get all relations for the type from all patterns for all languages.
const urlPatterns = await getPluginService('url-pattern').findByUid(type);
urlPatterns.forEach((urlPattern) => {
const languageRelations = getPluginService('url-pattern').getRelationsFromPattern(urlPattern);
relations = [...relations, ...languageRelations];
});

// Query all the entities of the type that do not have a corresponding URL alias.
const entities = await strapi.documents(type as 'api::test.test').findMany({
Expand All @@ -70,9 +65,10 @@ const generateUrlAliases = async (params: GenerateParams): Promise<number> => {
*/
// eslint-disable-next-line no-restricted-syntax
for (const entity of entities) {
// FIXME: just filter the `urlPatterns` we already have.
// eslint-disable-next-line no-await-in-loop
const urlPatterns = await getPluginService('url-pattern').findByUid(type, entity.locale);
const resolvedPath = getPluginService('url-pattern').resolvePattern(type, entity, urlPatterns[0]);
const entityUrlPatterns = await getPluginService('url-pattern').findByUid(type, entity.locale);
const resolvedPath = getPluginService('url-pattern').resolvePattern(type, entity, entityUrlPatterns[0]);

// eslint-disable-next-line no-await-in-loop
const newUrlAlias = await strapi.documents('plugin::webtools.url-alias').create({
Expand Down
21 changes: 12 additions & 9 deletions packages/core/server/services/url-alias.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const customServices = () => ({
*
* @param originalPath The path as generated from the pattern and document
* @param currentDocumentId If generating for an existing document, its document id
* @param currentLocale If generating for an existing document, its locale code
* @param currentLocale If generating for an existing i18n document, its locale code
*/
makeUniquePath: async (
originalPath: string,
Expand All @@ -98,16 +98,19 @@ const customServices = () => ({
};

if (currentDocumentId) {
const documentFilters: unknown[] = [{
documentId: { $eq: currentDocumentId },
}];

if (currentLocale) {
documentFilters.push({
locale: { $eq: currentLocale },
});
}

filters.$and.push({
$not: {
$and: [
{
documentId: { $eq: currentDocumentId },
},
{
locale: { $eq: currentLocale },
},
],
$and: documentFilters,
},
});
}
Expand Down
9 changes: 4 additions & 5 deletions packages/core/server/services/url-pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ const customServices = () => ({
/**
* Get all fields from a pattern.
*
* @param {string[]} patterns - The patterns to extract fields from.
* @param {string} pattern - The patterns to extract fields from.
* @returns {string[]} The extracted fields.
*/
getFieldsFromPattern: (pattern: string) => {
getFieldsFromPattern: (pattern: string): string[] => {
const fields = pattern.match(/[[\w\d.]+]/g); // Get all substrings between [] as array.

if (!fields) {
Expand All @@ -119,10 +119,10 @@ const customServices = () => ({
/**
* Get all relations from a pattern.
*
* @param {string[]} patterns - The patterns to extract relations from.
* @param {string} pattern - The patterns to extract relations from.
* @returns {string[]} The extracted relations.
*/
getRelationsFromPattern: (pattern: string) => {
getRelationsFromPattern: (pattern: string): string[] => {
// Get fields from the pattern (assuming they are inside square brackets)
let fields = getPluginService('url-pattern').getFieldsFromPattern(pattern);

Expand Down Expand Up @@ -152,7 +152,6 @@ const customServices = () => ({
const resolve = (pattern: string) => {
let resolvedPattern: string = pattern;

// Ensure pattern is an array before sending it to getFieldsFromPattern
const fields = getPluginService('url-pattern').getFieldsFromPattern(
pattern,
);
Expand Down
2 changes: 2 additions & 0 deletions turbo.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"globalEnv": ["LOCALAPPDATA"],
"tasks": {
"build": {
"cache": false,
"dependsOn": ["^build"]
},
"eslint": {
Expand Down