GithubHelp home page GithubHelp logo

wazum / sluggi Goto Github PK

View Code? Open in Web Editor NEW
38.0 5.0 22.0 1.84 MB

The TYPO3 CMS slug helper

License: GNU General Public License v3.0

PHP 70.32% JavaScript 2.37% TypeScript 27.22% CSS 0.09%
typo3 extension slug url

sluggi's Introduction

sluggi

Installation

Require the latest package with composer:

composer require wazum/sluggi

Available on TER and packagist.

2023 Update information

  • The extension version schema changed with the rewrite. It's now coupled to the TYPO3 CMS version. So sluggi 12.x is for TYPO3 CMS 12.x.
  • All the old versions/tags are still available.
  • The documentation is always for the latest version. It's possible that some features are not available in older versions.

Features

  • Normal users can only edit the part of the page slug they have permission to edit. This means that administrators can restrict editing the page slug on certain pages.
  • The extension updates slug segments when a page is moved or copied, including all child pages.
  • You can automatically synchronize the slug segment with configured fields (e.g. page title), so you never have to think about updating the URL slug segment manually when changing the page title or moving the page.
  • The extension calculates the page slug based on a fallback chain. If there is an alternative page title, it will be used. Otherwise, the page title will be used. You can change the fields used in the extension configuration as a JSON array string (for more see below).
  • Forward slashes in the page slug are replaced with hyphens for new pages by default, but existing pages are not affected unless you recalculate the slugs.
  • You can set a flag to allow editing only for the last part of the URL (the segment for the current page). This corresponds to the earlier "realurl" approach.
  • You can lock a slug from updates.
  • The user interface is more comfortable. E.g. the redirects info dialog can be hidden if needed and the slug field can be edited with a simple double click.

Let's take a more detailed look at some of the features now.

Slug synchronization with configured fields

If the setting is enabled (see below, default is yes), then the URL slug segment will automatically adjust when the value in any of the configured fields changes. This also works if you change the title e.g. directly via the page tree.

Slug synchronization

You can disable this globally or per individual page with the toggle below the URL segment. The URL segment is updated as soon as the input loses focus or you toggle the synchronization switch.

Slug editing on restricted pages

Normal users can edit only the part of the page slug for which they have editing permission. Let's assume there is a DB mount and no permission to edit the pages above it, then the result would look like this:

Restricted page slug editing

The user is not allowed to change anything on the "Praesent Elit" page above it in the page tree, so it's not possible to change the slug part for this page either.

Edit only the last URL slug segment part

You can enable that only the last part of the URL slug can be edited. This corresponds to the former "realurl" approach.

Last segment editing

Locking the URL slug segment

Administrators or users with appropriate rights to the lock field can lock editing of the URL slug segment of a page.

Slug locking

Locking and synchronizing are mutually exclusive.

Simple edit

You can now simply double-click on the slug field to edit it. The edit button is still available.

Simple edit

Disable the redirects info dialog

You can now simply hide the redirects info dialog with a setting (see below), which informs you after saving that all slugs of all subpages have been changed and which offers the possibility to undo actions. It basically offers little added value. Either you want to create redirects automatically for the installation or not (see below). The offered possibilities to undo the last action (or only parts of it) is not used in practice from my experience and complicates the work in the backend.

Redirects info dialog

Even if you do not deactivate the dialog, it will now close after a reasonable timeout. Previously, this dialog remained visible until eternity.

Extension settings

You can configure all options for the extension via Admin Tools > Settings > Extension Configuration

Extension settings

Clear the cache after changing settings!

Allow standard editors to edit only the last segment of the URL slug

synchronize

Default: 1 (enabled)

Allow standard editors to edit only the last segment of the URL slug

last_segment_only

Default: 0 (disabled)

Use the following page fields for slug generation (valid JSON array!)

pages_fields

Default: [["nav_title","title"]]

This has to be a valid JSON string!

Backend user group ID list with extra permissions

whitelist

Default: (empty)

Members of this group are treated like administrators as far as the URL slug segment is concerned.

Replace slash (/) in slug segment with hyphen (-)

slash_replacement

Default: 1 (enabled)

Exclude page types (Spacer, Recycler, Folder by default)

exclude_page_types

Default: 199,255,254

This setting is relevant if you want to use sluggi and masi together (see below).

All slug related fields are removed from the backend interface for these page types too.

Disable the slug update and redirect information dialog

disable_slug_update_information

Default: 0 (disabled)

Dependencies and automatic redirects

sluggi depends on the Core typo3/cms-redirects package, as only this extension allows recursive updating of page slugs when updating a parent page.

If you don't want automatic redirects created, you can easily disable them in your website configuration (config/sites/my-site/config.yaml). Set autoCreateRedirects to false.

settings:
   redirects:
     # Automatically update slugs of all sub pages
     # (default: true)
     autoUpdateSlugs: true
     # Automatically create redirects for pages with a new slug (works only in LIVE workspace)
     # (default: true)
     autoCreateRedirects: true
     # Time To Live in days for redirect records to be created - `0` disables TTL, no expiration
     # (default: 0)
     redirectTTL: 30
     # HTTP status code for the redirect, see
     # https://developer.mozilla.org/en-US/docs/Web/HTTP/Redirections#Temporary_redirections
     # (default: 307)
     httpStatusCode: 307

Source: https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/10.1/Feature-89115-Auto-createRedirectsOnSlugChanges.html

Compatibility with other extensions

If you want to set slugs for folders or want to exclude certain pages, you need masi. The code is compatible with masi (>= 2.0) and there's a configuration option to set the excluded page types:

# cat=basic; type=string; label=Exclude page types (Spacer, Recycler, Folder by default)
exclude_page_types=199,255,254

The default is the list the core uses. If you want to use masi, set the value to 255 (recycler) only.

When you change the "Exclude this page for slug generation of subpages" toggle, sluggi will regenerate the slug for all the subpages of the current page. If you want to preserve slugs for certain subpages you have to lock them before.

sluggi removes the configuration for ['behaviour']['allowLanguageSynchronization'] and sets 'l10n_mode' = 'exclude' for the exclude_slug_for_subpages field. Makes no sense in my eyes and I don't want to deal with the problems.

The field tx_sluggi_lock has been renamed to slug_locked in version 12, so both extensions can work together.

Use the provided upgrade wizard ("Migrate tx_sluggi_lock field") to transfer your existing settings to the new field. You can remove tx_sluggi_lock from the database table pages afterwards.

Support and feature requests

Use the issues tracker on GitHub for support questions and new feature requests or ideas concerning the extension.

Sponsors

Thanks to plan2net GmbH to let me work on the extension during working hours.

Special thanks to TU München and other German universities who sponsored my time at plan2net GmbH to work on general improvements, bugfixes, new features and the update for PHP 8 and TYPO3 CMS 12 (including backports of certain bugfixes in earlier versions).

Say thanks! and support me

You like this extension? Get something for me (surprise! surprise!) from my wishlist on Amazon or help me pay the next pizza or Pho soup (mjam). Thanks a lot!

sluggi's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

sluggi's Issues

Moving page results in unexpected url

Using TYPO3 10 V10.4.17

Settings:
basic.slash_replacement: true
basic.synchronize: false
basic.last_segment_only: true

Pages given:
host.de/demo/demo1/demo1a
host.de/demo/demo2/demo2a

Moving as regular user which can only edit last segment.

Moving page demo1a to demo2 results in
host.de/demo/demo2/demo-demo2-demo1a

Expected url:
host.de/demo/demo2/demo1a

Fix of DatamapHook.php works for me:

10a11
> use Wazum\Sluggi\Helper\PermissionHelper;
77c78,84
<             $newSlug = rtrim($parentSlug, '/') . $currentSlugSegment;
---
>           $newSlug = rtrim($parentSlug, '/') . $currentSlugSegment;
>
>           if (PermissionHelper::hasFullPermission()) {
>                 $newSlug = rtrim($parentSlug, '/') . $currentSlugSegment;
>             }else{
>                 $newSlug = $currentSlugSegment;
>             }

Redirects: missing option for Keep GET Parameters

Great module by the way. The only thing I am missing in the extension settings is an option for the redirects to keep the GET parameters. It is important to keep this information fro tracking purpose when redirecting a page.
Thank you for creating this module

Moving pages in workspace draft mode no more possible due to an exception error

It's no more possible to move pages in the page tree in workspace draft mode.

This is caused by an exception error:
Core: Exception handler (WEB): Uncaught TYPO3 Exception: Argument 1 passed to Wazum\Sluggi\Backend\Hook\DatamapHook::getLastSlugSegment() must be of the type string, null given, called in /xxx/public/typo3conf/ext/sluggi/Classes/Backend/Hook/DatamapHook.php on line 251 | TypeError thrown in file /xxx/public/typo3conf/ext/sluggi/Classes/Backend/Hook/DatamapHook.php in line 652.

How can this prevented?

Dependency to sysext redirects

Hi,
sluggi seems to depend on the system extension "redirects" to do it's job but this is not stated in the ext_emconf.php not even as "suggest".
On Installations without "redirects" activated (e.g. after an update from 8.7) the missing DB columns lead to errors like "missing table source_host in where clause"

Regards
Thomas Moll

composer.json: list dependency to typo3/cms-core under "require"

The dependency to the specific version of typo3/cms-core should be listed under the "require" section in composer.json.

Practical implication: It makes sure composer always suggests the correct version to update to. Also, in a project we use 9.5.24 and use https://gitlab.com/dependabot-gitlab/dependabot to automatically create PRs for outdated packes. Because of the missing require-stement, it suggests to update sluggi to 2.0.2 which wouldn't work.

Update TER version to 2.0.3

Hi there and thanks for your awesome extension. Could you maybe update the TER version to 2.0.3? Thanks! :-)

Configuration Options missing when installed in Typo3 Version 9.5.8

Hi, when I install the extension with Typo3 Version 9.5.8 I only get the one configuration option. See screenshot. Renaming slug segements recursively is not working. Maybe because the config is not present? Or is there anything I'm missing? I dowloaded the latest version of your ext from TER.

2019-07-16 13_33_10-sluggi-config-options

Thanks for checking!

Redirect to self is created in multilanguage site

When you have a multilanguage site and edit a page in the default language, a redirect is created from the second language page to itself.

For example:

  • "page 1" exists in language 0 and 1 with slugs site.com/page and site.com/en/page
  • edit a property of the default page in the backend, e.g. the author.
  • when you save the page a redirect is created from site.com/en/page to site.com/en/page

I use TYPO3 10.4.12 and this problem is in the dev-master version of the exention and it's created with the fix for issue #40 because in version 2.0.0 the issue isn't there

URL with double slash

If there is, for some stupid reason, a slug on the start page e.g. /my-startpage all the subpage have this part in the slug field.

If the slug of the startpage is changed to (the correct) / the slug of the subpages start with //.

Deactivate updating slug of current page

It's not possible to deactivate updating slug of current page when moving or renaming.

  • it's possible to deactivate updating slug recursively when moving page. But it's not possible to deactivate udating slug of current page.
  • it's possible to deactivate updating slug recursively when renaming page. But if you rename pagetitle and set focus back to the title field it udates the slug of current page (via JavaScript).

Error if page has NULL slug

Hi,
if a page for some reason (external import) has a NULL slug, this error happens on saving the page:
Argument 2 passed to Wazum\Sluggi\Backend\Service\SlugService::rebuildSlugsForSlugChange() must be of the type string, null given, called in /typo3conf/ext/sluggi/Classes/Backend/Hook/DataHandlerSlugUpdateHook.php on line 148

TYPO3 10 LTS
sluggi 2.0.3

Wrong redirect generated for sites with URL prefix

I have tested this with TYPO3 9.5.14 and sluggi 1.9.1. It can be reproduced by adding a site configuration with a full URL prefix, e.g. /en/.

If you create a page named example and then rename it to example new, sluggi will create a regular redirect and a variant:

/en/example -> /en/example-new

/en/example/en -> /en/example-new

There are two problems to this, first /en/ gets recognised as variant, second the variant is always appended to the URL although it should be prepended in that case. I am not entirely sure what the best way would be to solve that issue..

The following screenshot shows the problem in the debugger:

image

Slug field is locked although switch says it isn't

There is still one minor issue:

Tested on Vivaldi, Chrome and Firefox (on Linux Mint) and with Version 1.8.3 from TER and 1.9.1 from git:
sluggi-lock

As you can see there is no edit button, although the lock is not engaged.
"Have you tried turning it on and off again?" unlocks the field successfully though.

you can sometimes see the edit button for a fraction of a second before it vanishes after loading the backend page.

Redirect has wrong language-suffix

TYPO3 10.4.28
sluggi: 2.1.3
When creating a new redirect in foreign languages it takes the suffix to the end.
F. e.: /en/global/welcome-center/preparing.html -> /en/global/welcome-center/preparing-new/en.html

Users are unable to edit page properties when sluggi is installed since TYPO3 9.5.14: Missing UID

Hi,

We are using

  • TYPO3 9.5.14 LTS
  • sluggi from TER (1.8.3) and sluggi from Github (1.9.0)
  • PHP 7.2.23 (cli) (built: Oct 17 2019 16:19:35) ( NTS )
  • Apache/2.4.25 (Debian) 2019-10-13T15:43:54

With both versions we get an error since we updated from TYPO3 9.5.13.
Whenever a non-admin user tries to edit the page properties of any page, they get:

Wed, 19 Feb 2020 11:40:30 +0100 [CRITICAL]
request="729a2287d0a71"
component="TYPO3.CMS.Core.Error.DebugExceptionHandler":
Core: Exception handler (WEB):
Uncaught TYPO3 Exception: #1578950324: The given page record is invalid. Missing uid. |
RuntimeException thrown in file /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php in line 397.
Requested URL: https://rrzk.uni-koeln.de/typo3/index.php?route=%2Frecord%2Fedit&token=--AnonymizedToken--&edit%5Bpages%5D%5B12735%5D=edit&returnUrl=%2Ftypo3%2Findex.php%3Froute%3D%252Fweb%252Flayout%252F%26token%3D482f7493fcc3d794a7e664ba5293c2421e032a94%26id%3D12735 -
{"TYPO3_MODE":"BE","exception":"RuntimeException: The given page record is invalid. Missing uid. in /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php:397
Stack trace:
#0 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php(632): 
TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication->isInWebMount(Array)
#1 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Authentication/BackendUserAuthentication.php(369): 
TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication->calcPerms(Array)
#2 /var/www/html/typo3conf/ext/sluggi/Classes/Helper/PermissionHelper.php(73): 
TYPO3\\CMS\\Core\\Authentication\\BackendUserAuthentication->doesUserHaveAccess(Array, 2)
#3 /var/www/html/typo3conf/ext/sluggi/Classes/Backend/Form/InputSlugElement.php(44): 
Wazum\\Sluggi\\Helper\\PermissionHelper::getTopmostAccessiblePage(12735)
#4 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Form/Container/SingleFieldContainer.php(180): 
Wazum\\Sluggi\\Backend\\Form\\InputSlugElement->render()
#5 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Form/Container/PaletteAndSingleContainer.php(223): 
TYPO3\\CMS\\Backend\\Form\\Container\\SingleFieldContainer->render()
#6 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Form/Container/PaletteAndSingleContainer.php(118): 
TYPO3\\CMS\\Backend\\Form\\Container\\PaletteAndSingleContainer->createPaletteContentArray('title')
#7 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Form/Container/TabsContainer.php(86): 
TYPO3\\CMS\\Backend\\Form\\Container\\PaletteAndSingleContainer->render()
#8 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Form/Container/FullRecordContainer.php(83): 
TYPO3\\CMS\\Backend\\Form\\Container\\TabsContainer->render()
#9 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Form/Container/OuterWrapContainer.php(55): 
TYPO3\\CMS\\Backend\\Form\\Container\\FullRecordContainer->render()
#10 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Controller/EditDocumentController.php(1369): 
TYPO3\\CMS\\Backend\\Form\\Container\\OuterWrapContainer->render()
#11 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Controller/EditDocumentController.php(1198): 
TYPO3\\CMS\\Backend\\Controller\\EditDocumentController->makeEditForm()
#12 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Controller/EditDocumentController.php(537): 
TYPO3\\CMS\\Backend\\Controller\\EditDocumentController->main(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#13 [internal function]: 
TYPO3\\CMS\\Backend\\Controller\\EditDocumentController->mainAction(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#14 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Http/RouteDispatcher.php(87): 
call_user_func_array(Array,
 Array)
#15 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Http/RequestHandler.php(73): 
TYPO3\\CMS\\Backend\\Http\\RouteDispatcher->dispatch(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest),
 Object(TYPO3\\CMS\\Core\\Http\\Response))
#16 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Middleware/SiteResolver.php(59): 
TYPO3\\CMS\\Backend\\Http\\RequestHandler->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#17 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php(138): 
TYPO3\\CMS\\Backend\\Middleware\\SiteResolver->process(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest),
 Object(TYPO3\\CMS\\Backend\\Http\\RequestHandler))
#18 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Middleware/AdditionalResponseHeaders.php(39): 
class@anonymous->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#19 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php(138): 
TYPO3\\CMS\\Backend\\Middleware\\AdditionalResponseHeaders->process(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest),
 Object(class@anonymous))
#20 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Middleware/OutputCompression.php(45): 
class@anonymous->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#21 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php(138): 
TYPO3\\CMS\\Backend\\Middleware\\OutputCompression->process(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest),
 Object(class@anonymous))
#22 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Middleware/LegacyBackendTemplateInitialization.php(42): 
class@anonymous->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#23 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php(138): 
TYPO3\\CMS\\Backend\\Middleware\\LegacyBackendTemplateInitialization->process(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest),
 Object(class@anonymous))
#24 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Middleware/BackendUserAuthenticator.php(70): 
class@anonymous->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#25 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php(138): 
TYPO3\\CMS\\Backend\\Middleware\\BackendUserAuthenticator->process(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest),
 Object(class@anonymous))
#26 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Middleware/BackendRouteInitialization.php(72): 
class@anonymous->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#27 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php(138): 
TYPO3\\CMS\\Backend\\Middleware\\BackendRouteInitialization->process(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest),
 Object(class@anonymous))
#28 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Middleware/ForcedHttpsBackendRedirector.php(53): 
class@anonymous->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#29 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php(138): 
TYPO3\\CMS\\Backend\\Middleware\\ForcedHttpsBackendRedirector->process(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest),
 Object(class@anonymous))
#30 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Middleware/LockedBackendGuard.php(71): class@anonymous->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#31 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php(138): 
TYPO3\\CMS\\Backend\\Middleware\\LockedBackendGuard->process(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest),
 Object(class@anonymous))
#32 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Middleware/NormalizedParamsAttribute.php(58): 
class@anonymous->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#33 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php(138): 
TYPO3\\CMS\\Core\\Middleware\
ormalizedParamsAttribute->process(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest),
 Object(class@anonymous))
#34 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php(67): 
class@anonymous->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#35 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/AbstractApplication.php(108): 
TYPO3\\CMS\\Core\\Http\\MiddlewareDispatcher->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#36 /var/www/html/typo3_src-9.5.14/typo3/sysext/backend/Classes/Http/Application.php(68): 
TYPO3\\CMS\\Core\\Http\\AbstractApplication->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#37 /var/www/html/typo3_src-9.5.14/typo3/sysext/core/Classes/Http/AbstractApplication.php(120): 
TYPO3\\CMS\\Backend\\Http\\Application->handle(Object(TYPO3\\CMS\\Core\\Http\\ServerRequest))
#38 /var/www/html/typo3_src-9.5.14/typo3/index.php(24): 
TYPO3\\CMS\\Core\\Http\\AbstractApplication->run()
#39 /var/www/html/typo3_src-9.5.14/typo3/index.php(25): 
{closure}()
#40 {main}"}

version 1.11.0 breaks sys_file_reference when copying pages in TYPO3 backend

Hello,
we have a TYPO3 Version 9.5.27 with following configuration:

  • TYPO3 9.5.27
  • sluggi version 1.11.0 from packagist
  • 11 Languages configured
  • use the pages->media field to add images for the pages

When copying pages with existing translations, it breaks with an error message and the default language has doubled sys_file_references in media field.
After removing sluggi the problem has gone.

I will provide a detailed description how to recover this behaviour in a fresh installation and provide a site package to test it.

Versions 2.1.2 and 2.1.3 are broken

I just updated EXT:sluggi from 2.1.1 to 2.1.3 and got an exception during TCA migration (e.g. when clearing caches or performing DB schema update):

[ UnexpectedValueException ]
Missing "type" in TCA of field "['pages']['[["nav_title"']['config']".

I have the following extension configuration:

'sluggi' => [
    'last_segment_only' => '0',
    'pages_fields' => '[["nav_title","title"]]',
    'slash_replacement' => '1',
    'synchronize' => '1',
    'whitelist' => '',
],

After a short research I was able to track it down to the following:

It seems like 02f363c is no longer available in versions 2.1.2 and 2.1.3, see for example https://github.com/wazum/sluggi/blob/2.1.2/ext_conf_template.txt#L6. Said commit was not merged back into the v2 compatibility branch typo3-10 which you likely used to create both versions.

This probably affects more changes that were introduced with 2.1.0 and 2.1.1 which might now be missing in the 2.1.2 and 2.1.3 versions, but haven't checked on this further.

Error "Too few arguments to function Wazum\Sluggi\Backend\Hook\DataHandlerSlugUpdateHook"

Hi folks,

I'm using TYPO3 9 LTS and the latest 2.0.2 version of sluggi. When I open the backend and try to edit a backend user record, the following error occurs when saving the updated record: "Too few arguments to function Wazum\Sluggi\Backend\Hook\DataHandlerSlugUpdateHook"

Downgrading the version to 2.0.0 fixed the error so that it doesn't occur. Upgrading to 2.01. or later, the exception is thrown again.

I hope it helps to reproduce the situation.

Best regards,
Christian

Update slug of moved page

Via configuration it's possible to deactivate updating slug recursively when moving page.
But it's not possible to deactivate udating slug of main page.

Allow option to choose between nested array and simple array in generatorOptions:fields

Setting the pages_fields to a value "nav_title,title" results in a nested array.

The default behavior of Typo3, in this case, is taking nav_title, and only if this is empty use title:
https://docs.typo3.org/m/typo3/reference-tca/master/en-us/ColumnsConfig/Type/Slug/Properties/GeneratorOptions.html

I would assume that it is not set as a nested array but as a normal array, resulting in taking both fields into account.

Is it possible to have an option to control this behavior or at least make it transparent to write the string as array already "['nav_title','title]" ?

If we leave the field empty and set the configuration on our own there is an exception happening.

Thanks,
Sebastian

Redirect to pages with suffix

If suffix on site configuration is configured, e.g.
routeEnhancers: PageTypeSuffix: type: PageType default: /index.html
Pages can be called via '/path/' or alternative via '/path/index.html'.

When moving page or changing slug, sluggy doesn't generate a redirect to page with suffix, this calls won't work anymore.

sluggi is missing the extension-key property in the composer.json

This is a new error shown in TYPO3 10.4.16:

In future versions of TYPO3, it will be mandatory for extensions to provide a composer.json file. This will be needed to identify an extension and works as a replacement for the ext_emconf.php. Therefore, the composer.json file must also include the extension key under "extra > typo3/cms > extension-key". Please add a composer.json, including the extension-key property, in the corresponding extension folder. You can use the auto-generated proposal below and update the composer.json file extension.

It would be good practice to provide this key per default.

Backend Slug Rendering

DE: [www.example.at]/forschung/forscher/maxmuster
EN: [www.example.at/en/some/wrong/path/will/be/rendered/in/be]/research/researcher/maxmuster

It seems to be only a Problem with the rendering, the correct path will be saved/used.
This only happens for users without extra permissions (not for admin or whitelisted user group's).

Bug in Slug access restrictions for /

Hi,

thank you, for building the sluggi extension. It is realy usefull.

The problem:

/
demo Access group DEMO
test Access group Test
page1 Access group Test

This results in

[https://servername.de/demo]/test/page1

[] = Fixed part - can not be changed

That is correct. The user has no access to demo. So it can not be changed.

Slug on the test page

[https://servername.de/demo]/test/page1

Also correct.

But if the user is in the demo group and has no access (no mount) to / he gets:
[https://servername.de]/demo/test/page1

So the user can edit the slug and access the / namespace.

What i was expecting:
[https://servername.de/demo]/test/page1

Also locking the slug of the page demo1 does not block the subpages for editing the hole url path.

Copy whole pagetree to archiv page: slugs of subpages won't update

I have a typo3 website for a yearly filmfestival - when the festival is over the whole pagetree is copied to an archiv page and the actual main page is renamed.

Here is the page tree:

[1] vft
--[2] 2020
---[3] program
---[4] jury
-- [30] archiv

When I copy the whole pagetree '2020' to archiv folder the slug of the new 2020 Page in archiv is updates as soon as I make the page visible.
I'm expecting that the subpages 'program' and 'jury' will get updated slugs to "archiv/2020/program" and "archiv/2020/jury" but they have "2020/program-1" and "2020/jury-1"

So maybe this is a bug in sluggi or how can I get sluggi to do what I want? Copying single pages works fine - as soon as I make the copied page visible the slug is updated.

TYPO3 v9: Moving pages can lead to two entries

Hi @wazum,

we've implemented a trailing slash for a customer and noticed that two records will be added to sys_redirects. By looking into the code I have noticed that when a custom default PageTypeSuffix is configured two redirects will be added by the DatamapHook.

if ($currentSlug !== $slug) {

            if ($currentSlug !== $slug) {
                // Remove old redirects matching the previous slug
                $this->deleteRedirect($siteHost, $sitePath . $currentSlug);
                $this->createRedirect($siteHost, $sitePath . $currentSlug, $pageId);
                if (!empty($variant)) {
                    $this->deleteRedirect($siteHost, $sitePath . $currentSlug . $variant);
                    $this->createRedirect($siteHost, $sitePath . $currentSlug . $variant, $pageId);
                }
            }

TYPO3 10 compatibility

Hey there,

thanks for your work with sluggi. :-)

Will you add TYPO3 10 compatibility. I know they introduced the automatic updates for URL segments and redirects, but still, sluggi provides some nice additional features. :-)

ext:redirect should be dependency

Hey,
this ext should be part of core features for sure! Good work! Thanks!

Could be a good idea to make ext: redirects mandatory as Sluggi doesn't work without it.

Redirects for subpages does not get PageTypeSuffix

My pages have the slugs:

  • /test-1/
  • /test-1/unterseite/

We use '/' as default PageTypeSuffix.

When i rename /test-1/ to /test-2/ then 2 redirects are created:

  1. /test-1/ => /test-2/
  2. /test-1/unterseite => /test-2/unterseite

Issue is that the second redirect misses the slash at the end.


Another issue are translated pages. My page translation has the url path /pl-pl/polish-page/ where /pl-pl/ is the language prefix. When i rename the page this redirect is created:

/pl-pl/polish-page/ => /pl-pl/renamed-polish-page/pl-pl/

Maybe I'm wrong, but I think the problem is, that a slug $originalSlug is compared against a page path $generatedPath in \Wazum\Sluggi\Backend\Service\SlugService::getVariant(). There strpos($generatedPath, $originalSlug)... seems strange to me.

Ignore separator and folder pages in slug generation

TYPO3 9 by default ignores the slugs of separators and folders when generating a slug for a subpage. However the slug for separators and folders are not empty. This leads to a problem, e.g. when a subpage of a separator or folder is moved and EXT:sluggi automatically updates the slug.

The issue can be reproduced by the following steps:

  1. Create a separator named Separator Page
  2. Create two subpages Test 1 and Test 2
  3. Verify the slugs of Test 1 and Test 2 to be test-1 and test-2
  4. Change the order of the pages
  5. Check the slug of the moved page, it now includes the separator page: e.g. separator-page/test-2

sluggi

Redirect has wrong domain when changing translated page title

TYPO3 version: 10.4.26
sluggi version: 2.2

If you have a multi language site where each language has a different domain, the redirects that are created when changing a translated page always has the domain for the main language.

For example:

The main language is English and has the domain example.com. The site also has the language Dutch, with the domain example.nl. If I change the title for a Dutch page translation, the redirect that is created is for the domain example.com.

Too many redirects occured top open […]

Renaming a page in the tree leads to:
"Too many redirects occured top open […]"

I use TYPO3 10.4.12 and this problem is in the dev-master version of the exention.

Documentation: recursively update slugs on subpages

Auto-Updating of slugs for subpages when editing the parent page only works if the
parent page slug string actually occurs in the slug of the subpage. I think this is a good feature, but maybe you can give a hint in the readme.

Disabled redirect options cause a database error

Incorrect integer value: '' for column 'force_https'

diff --git a/Classes/Backend/Hook/DatamapHook.php b/Classes/Backend/Hook/DatamapHook.php
index 964f90a..7c74e0f 100644
--- a/Classes/Backend/Hook/DatamapHook.php
+++ b/Classes/Backend/Hook/DatamapHook.php
@@ -342,9 +342,9 @@ class DatamapHook
     {
         $redirectLifetime = strtotime((string)Configuration::get('redirect_lifetime'));
         $redirectHttpStatusCode = (int)Configuration::get('redirect_code');
-        $redirectForceHttps = (bool)Configuration::get('redirect_force_https');
-        $redirectRespectQueryParameters = (bool)Configuration::get('redirect_respect_query_parameters');
-        $redirectKeepQueryParameters = (bool)Configuration::get('redirect_keep_query_parameters');
+        $redirectForceHttps = (int)Configuration::get('redirect_force_https');
+        $redirectRespectQueryParameters = (int)Configuration::get('redirect_respect_query_parameters');
+        $redirectKeepQueryParameters = (int)Configuration::get('redirect_keep_query_parameters');
         $this->connection->insert(
             'sys_redirect',
             [

getPrefix() has been removed in v10

Hi, looks like the getPrefix-method inside the permission check has been removed in Typo3 v10 in \TYPO3\CMS\Backend\Form\Element\InputSlugElement.

https://github.com/wazum/sluggi/blob/master/Classes/Backend/Form/InputSlugElement.php#L50

It's working for me to simple insert the code snippet from v9 in Wazum\Sluggi\Backend\Form\InputSlugElement

     * Render the prefix for the input field.
     *
     * @param SiteInterface $site
     * @param int $requestLanguageId
     * @return string
     */
    protected function getPrefix(SiteInterface $site, int $requestLanguageId = 0): string
    {
        $language = ($requestLanguageId < 0) ? $site->getDefaultLanguage() : $site->getLanguageById($requestLanguageId);
        $base = $language->getBase();
        $baseUrl = (string)$base;
        $baseUrl = rtrim($baseUrl, '/');
        if (!empty($baseUrl) && empty($base->getScheme()) && $base->getHost() !== '') {
            $baseUrl = 'http:' . $baseUrl;
        }
        return $baseUrl;
    }

InvalidArgumentException in redirects after rename a slug of a page twice

Hi,
I checked out the version 1.2.1 of sluggi but I have following problems:
I renamed a page to a new slug, and renamed it back to the slug before.
After this I tried to open the redirect module.

(1/1) #1526127158 InvalidArgumentException
Uid must be a positive integer, given.

in /app/web/typo3/sysext/backend/Classes/ViewHelpers/Link/EditRecordViewHelper.php line 69

The slug fields on child pages are not changed too. I thought, they will be changed recursively if I change the slug on parent page. There is those setting (Rename slug segments recursively) in extension configuration. It doesn't work for the moment?

Interoperation with extension internetgalerie/ig_slug

The extension "ig_slug" also offers a "slug lock" feature, the field is called "slug_locked" there. Sluggi's field is "tx_sluggi_lock". The sluggi lock field is not shown if ig_slug is installed, so both extensions are incompatible to each other. It would actually be nice if both extensions could share the same field since it behaves the same, because ig_slug features a nice backend module which is useful in combination with sluggi. Maybe you could get in touch with each other. I've created an issue there too: internetgalerie/ig_slug#7

Make it possible to create shorter URLs - even with last_segment_only setting

I like this extension.

However, I am trying to figure out a way to use it and / or avoid current problems with 10.4 and redirects.

We recently updated to 10. 4 already had several cases with unusable pages due to several changes of URLs and automatically created redirects.

I thought this extension was an option, but we would like to continue to give editors the possibility of creating shorter URLs for a subpage, e.g. you have

/university/faculty1/institutea/project-something and want this and the subpages to start with:

/project-something

If you restrict the editing to the last segment, this is not possible. We could deactivate the setting basic.last_segment_only, but what I am looking for is not a hard restriction, but rather a "suggestion / hint" but still be able to replace complete path if clicking on a button if necessary.

I like the current behaviour with the restriction to the last segment because it makes it clearer that this segment belongs to this page, the rest depends on the parent pages and (usually) not the entire path should be changed.

My idea

This could be made configurable so current behaviour is still default.

You could just edit the last segment, but you can click on a button to get the option to edit the whole path.

Current behaviour:

image

E.g. add additional button "Edit entire path".

This way it is still intuitively clear that you should just edit the segment for this page by default, but you still have the option to do otherwise.

Create redirects without endtime

It would be great to skip adding an endtime on redirect records in case the extension setting redirect_lifetime is empty.

Currently, there is always an endtime set with

'endtime' => $redirectLifetime !== false ? $redirectLifetime : strtotime('+1 month')

inside DatamapHook.php.

Exception thrown when a sysfolder on root level is renamed

Dear Wolfgang,

i found a little bug today in ext::sluggi.

First of all: I wonder if - hopefully - typo3 takes your extension into the core! Why does this not work out of the box what your extension does like a charm!

The error occurs when

  • having a sysfolder on root level
  • sysfolder is not a root-page
  • sysfolder has a slug (is not "/")
  • you want to rename the sysfolder

There is the exception:

`(1/1) #1521716622 TYPO3\CMS\Core\Exception\SiteNotFoundException
No site found in root line of page 8

in /html/site/public/typo3/sysext/core/Classes/Site/SiteFinder.php line 135
if (isset($this->mappingRootPageIdToIdentifier[(int)$pageInRootLine['uid']])) {
return $this->sites[$this->mappingRootPageIdToIdentifier[(int)$pageInRootLine['uid']]];
}
}
throw new SiteNotFoundException('No site found in root line of page ' . $pageId, 1521716622);
}

/**
 * @param bool $useCache

at TYPO3\CMS\Core\Site\SiteFinder->getSiteByPageId(8)
in /html/site/public/typo3/sysext/redirects/Classes/Service/SlugService.php line 140
}

protected function initializeSettings(int $pageId): void
{
    $this->site = $this->siteFinder->getSiteByPageId($pageId);
    $settings = $this->site->getConfiguration()['settings']['redirects'] ?? [];
    $this->autoUpdateSlugs = $settings['autoUpdateSlugs'] ?? true;
    $this->autoCreateRedirects = $settings['autoCreateRedirects'] ?? true;
    if (!$this->context->getPropertyFromAspect('workspace', 'isLive')) {

at TYPO3\CMS\Redirects\Service\SlugService->initializeSettings(8)
in /html/site/public/typo3conf/ext/sluggi/Classes/Backend/Service/SlugService.php line 44
protected $redirectKeepQueryParameters;

protected function initializeSettings(int $pageId): void
{
    parent::initializeSettings($pageId);

    $settings = $this->site->getConfiguration()['settings']['redirects'] ?? [];
    $this->redirectForceHttps = (int)($settings['forceHttps'] ?? 0);
    $this->redirectRespectQueryParameters = (int)($settings['respectQueryParameters'] ?? 0);

at Wazum\Sluggi\Backend\Service\SlugService->initializeSettings(8)
in /html/site/public/typo3conf/ext/sluggi/Classes/Backend/Service/SlugService.php line 62
$currentPageRecord = BackendUtility::getRecord('pages', $pageId);
if ($currentPageRecord === null) {
return;
}
$this->initializeSettings($pageId);
if ($this->autoUpdateSlugs || $this->autoCreateRedirects) {
$this->createCorrelationIds($pageId, $correlationId);
if ($this->autoCreateRedirects) {
$this->createRedirectWithPageId(
at Wazum\Sluggi\Backend\Service\SlugService->rebuildSlugsForSlugChange(8, '/footer-navigation', '/', object(TYPO3\CMS\Core\DataHandling\Model\CorrelationId))
in /html/site/public/typo3/sysext/redirects/Classes/Hooks/DataHandlerSlugUpdateHook.php line 102
) {
return;
}

    $this->slugService->rebuildSlugsForSlugChange($id, $persistedSlugValue, $fieldArray['slug'], $dataHandler->getCorrelationId());
}

/**
 * Determines whether our identifier is part of correlation id aspects.

at TYPO3\CMS\Redirects\Hooks\DataHandlerSlugUpdateHook->processDatamap_postProcessFieldArray('update', 'pages', 8, array('title' => 'Footer navigation xx', 'slug' => '/', 'tx_sluggi_sync' => '1', 'tstamp' => 1612275261, 't3ver_stage' => 0), object(TYPO3\CMS\Core\DataHandling\DataHandler))
in /html/site/public/typo3/sysext/core/Classes/DataHandling/DataHandler.php line 1172
}
// Hook: processDatamap_postProcessFieldArray
foreach ($hookObjectsArr as $hookObj) {
if (method_exists($hookObj, 'processDatamap_postProcessFieldArray')) {
$hookObj->processDatamap_postProcessFieldArray($status, $table, $id, $fieldArray, $this);
}
}
// Performing insert/update. If fieldArray has been unset by some userfunction (see hook above), don't do anything
// Kasper: Unsetting the fieldArray is dangerous; MM relations might be saved already
at TYPO3\CMS\Core\DataHandling\DataHandler->process_datamap()
in /html/site/public/typo3/sysext/backend/Classes/Controller/EditDocumentController.php line 559
}

    // Perform the saving operation with DataHandler:
    if ($this->doSave === true) {
        $tce->process_datamap();
        $tce->process_cmdmap();
    }
    // If pages are being edited, we set an instruction about updating the page tree after this operation.
    if ($tce->pagetreeNeedsRefresh

at TYPO3\CMS\Backend\Controller\EditDocumentController->processData(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/backend/Classes/Controller/EditDocumentController.php line 419
|| isset($parsedBody['_savedokview'])
|| isset($parsedBody['_savedoknew'])
|| isset($parsedBody['_duplicatedoc'])
) {
if ($response = $this->processData($request)) {
return $response;
}
}

at TYPO3\CMS\Backend\Controller\EditDocumentController->mainAction(object(TYPO3\CMS\Core\Http\ServerRequest))
at call_user_func_array(array(object(TYPO3\CMS\Backend\Controller\EditDocumentController), 'mainAction'), array(object(TYPO3\CMS\Core\Http\ServerRequest)))
in /html/site/public/typo3/sysext/backend/Classes/Http/RouteDispatcher.php line 66
}
$targetIdentifier = $route->getOption('target');
$target = $this->getCallableFromTarget($targetIdentifier);
$arguments = [$request];
return call_user_func_array($target, $arguments);
}

/**
 * Wrapper method for static form protection utility

at TYPO3\CMS\Backend\Http\RouteDispatcher->dispatch(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/backend/Classes/Http/RequestHandler.php line 94
// there are Core classes that need the Request object but do not get it handed in
$this->resetGlobalsToCurrentRequest($request);
try {
// Check if the router has the available route and dispatch.
return $this->dispatcher->dispatch($request);
} catch (InvalidRequestTokenException $e) {
// When token was invalid redirect to login
$loginPage = GeneralUtility::makeInstance(UriBuilder::class)->buildUriFromRoute('login');
return new RedirectResponse((string)$loginPage);
at TYPO3\CMS\Backend\Http\RequestHandler->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/extbase/Classes/Middleware/SignalSlotDeprecator.php line 49
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$this->dispatcher->reportDeprecatedSignalSlots();
return $handler->handle($request);
}
}
at TYPO3\CMS\Extbase\Middleware\SignalSlotDeprecator->process(object(TYPO3\CMS\Core\Http\ServerRequest), object(TYPO3\CMS\Backend\Http\RequestHandler))
in /html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php line 172

            if (!$middleware instanceof MiddlewareInterface) {
                throw new \InvalidArgumentException(get_class($middleware) . ' does not implement ' . MiddlewareInterface::class, 1516821342);
            }
            return $middleware->process($request, $this->next);
        }
    };
}

}
at class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/backend/Classes/Middleware/SiteResolver.php line 69
}
$site = $this->siteMatcher->matchByPageId($pageId, $rootLine);
$request = $request->withAttribute('site', $site);
}
return $handler->handle($request);
}
}
at TYPO3\CMS\Backend\Middleware\SiteResolver->process(object(TYPO3\CMS\Core\Http\ServerRequest), object(class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b))
in /html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php line 172

            if (!$middleware instanceof MiddlewareInterface) {
                throw new \InvalidArgumentException(get_class($middleware) . ' does not implement ' . MiddlewareInterface::class, 1516821342);
            }
            return $middleware->process($request, $this->next);
        }
    };
}

}
at class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/backend/Classes/Middleware/AdditionalResponseHeaders.php line 41
* @return ResponseInterface
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$response = $handler->handle($request);
foreach ($GLOBALS['TYPO3_CONF_VARS']['BE']['HTTP']['Response']['Headers'] ?? [] as $header) {
[$headerName, $value] = explode(':', $header, 2);
$response = $response->withAddedHeader($headerName, trim($value));
}
at TYPO3\CMS\Backend\Middleware\AdditionalResponseHeaders->process(object(TYPO3\CMS\Core\Http\ServerRequest), object(class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b))
in /html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php line 172

            if (!$middleware instanceof MiddlewareInterface) {
                throw new \InvalidArgumentException(get_class($middleware) . ' does not implement ' . MiddlewareInterface::class, 1516821342);
            }
            return $middleware->process($request, $this->next);
        }
    };
}

}
at class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/backend/Classes/Middleware/OutputCompression.php line 47
ob_clean();
// Initialize output compression if configured
$this->initializeOutputCompression();

    return $handler->handle($request);
}

/**
 * Initialize output compression if configured

at TYPO3\CMS\Backend\Middleware\OutputCompression->process(object(TYPO3\CMS\Core\Http\ServerRequest), object(class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b))
in /html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php line 172

            if (!$middleware instanceof MiddlewareInterface) {
                throw new \InvalidArgumentException(get_class($middleware) . ' does not implement ' . MiddlewareInterface::class, 1516821342);
            }
            return $middleware->process($request, $this->next);
        }
    };
}

}
at class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/backend/Classes/Middleware/BackendUserAuthenticator.php line 78
$GLOBALS['LANG'] = LanguageService::createFromUserPreferences($GLOBALS['BE_USER']);
// Re-setting the user and take the workspace from the user object now
$this->setBackendUserAspect($GLOBALS['BE_USER']);

    $response = $handler->handle($request);

    // If no backend user is logged-in, the cookie should be removed
    if (!GeneralUtility::makeInstance(Context::class)->getAspect('backend.user')->isLoggedIn()) {
        $GLOBALS['BE_USER']->removeCookie($GLOBALS['BE_USER']->name);

at TYPO3\CMS\Backend\Middleware\BackendUserAuthenticator->process(object(TYPO3\CMS\Core\Http\ServerRequest), object(class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b))
in /html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php line 172

            if (!$middleware instanceof MiddlewareInterface) {
                throw new \InvalidArgumentException(get_class($middleware) . ' does not implement ' . MiddlewareInterface::class, 1516821342);
            }
            return $middleware->process($request, $this->next);
        }
    };
}

}
at class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/backend/Classes/Middleware/BackendRouteInitialization.php line 58

    // Add the route path to the request
    $request = $request->withAttribute('routePath', $pathToRoute);

    return $handler->handle($request);
}

}
at TYPO3\CMS\Backend\Middleware\BackendRouteInitialization->process(object(TYPO3\CMS\Core\Http\ServerRequest), object(class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b))
in /html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php line 172

            if (!$middleware instanceof MiddlewareInterface) {
                throw new \InvalidArgumentException(get_class($middleware) . ' does not implement ' . MiddlewareInterface::class, 1516821342);
            }
            return $middleware->process($request, $this->next);
        }
    };
}

}
at class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/backend/Classes/Middleware/ForcedHttpsBackendRedirector.php line 55
[$server, $address] = explode('/', $url, 2);
return new RedirectResponse('https://' . $server . $sslPortSuffix . '/' . $address);
}

    return $handler->handle($request);
}

}
at TYPO3\CMS\Backend\Middleware\ForcedHttpsBackendRedirector->process(object(TYPO3\CMS\Core\Http\ServerRequest), object(class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b))
in /html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php line 172

            if (!$middleware instanceof MiddlewareInterface) {
                throw new \InvalidArgumentException(get_class($middleware) . ' does not implement ' . MiddlewareInterface::class, 1516821342);
            }
            return $middleware->process($request, $this->next);
        }
    };
}

}
at class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/backend/Classes/Middleware/LockedBackendGuard.php line 73
$request->getAttribute('normalizedParams')->getRemoteAddress(),
trim((string)$GLOBALS['TYPO3_CONF_VARS']['BE']['IPmaskList'])
);

    return $handler->handle($request);
}

/**
 * Check adminOnly configuration variable and redirects to an URL in file typo3conf/LOCK_BACKEND

at TYPO3\CMS\Backend\Middleware\LockedBackendGuard->process(object(TYPO3\CMS\Core\Http\ServerRequest), object(class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b))
in /html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php line 172

            if (!$middleware instanceof MiddlewareInterface) {
                throw new \InvalidArgumentException(get_class($middleware) . ' does not implement ' . MiddlewareInterface::class, 1516821342);
            }
            return $middleware->process($request, $this->next);
        }
    };
}

}
at class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/core/Classes/Middleware/NormalizedParamsAttribute.php line 45
*/
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
$request = $request->withAttribute('normalizedParams', NormalizedParams::createFromRequest($request));
return $handler->handle($request);
}
}
at TYPO3\CMS\Core\Middleware\NormalizedParamsAttribute->process(object(TYPO3\CMS\Core\Http\ServerRequest), object(class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b))
in /html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php line 172

            if (!$middleware instanceof MiddlewareInterface) {
                throw new \InvalidArgumentException(get_class($middleware) . ' does not implement ' . MiddlewareInterface::class, 1516821342);
            }
            return $middleware->process($request, $this->next);
        }
    };
}

}
at class@anonymous/html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php0x7f24dfd1b41b->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/core/Classes/Http/MiddlewareDispatcher.php line 78
* @return ResponseInterface
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->tip->handle($request);
}

/**
 * Seed the middleware stack with the inner request handler

at TYPO3\CMS\Core\Http\MiddlewareDispatcher->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/core/Classes/Http/AbstractApplication.php line 85
* @return ResponseInterface
*/
protected function handle(ServerRequestInterface $request): ResponseInterface
{
return $this->requestHandler->handle($request);
}

/**
 * Set up the application and shut it down afterwards

at TYPO3\CMS\Core\Http\AbstractApplication->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/backend/Classes/Http/Application.php line 72
$request = $request->withAttribute('applicationType', $applicationType);

    // Set up the initial context
    $this->initializeContext();
    return parent::handle($request);
}

/**
 * Check if LocalConfiguration.php and PackageStates.php exist

at TYPO3\CMS\Backend\Http\Application->handle(object(TYPO3\CMS\Core\Http\ServerRequest))
in /html/site/public/typo3/sysext/core/Classes/Http/AbstractApplication.php line 97
final public function run(callable $execute = null)
{
try {
$response = $this->handle(
ServerRequestFactory::fromGlobals()
);
if ($execute !== null) {
call_user_func($execute);
}
at TYPO3\CMS\Core\Http\AbstractApplication->run()
in /html/site/public/typo3/index.php line 25
// Set up the application for the backend
call_user_func(function () {
$classLoader = require dirname(dirname(DIR)).'/vendor/autoload.php';
\TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(1, \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_BE);
\TYPO3\CMS\Core\Core\Bootstrap::init($classLoader)->get(\TYPO3\CMS\Backend\Http\Application::class)->run();
});
at {closure}()
in /html/site/public/typo3/index.php line 26
call_user_func(function () {
$classLoader = require dirname(dirname(DIR)).'/vendor/autoload.php';
\TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::run(1, \TYPO3\CMS\Core\Core\SystemEnvironmentBuilder::REQUESTTYPE_BE);
\TYPO3\CMS\Core\Core\Bootstrap::init($classLoader)->get(\TYPO3\CMS\Backend\Http\Application::class)->run();
});`

To much redirects if slug changed back to the first slug before the change

Hi, I tried your extension to update slug fields after changing the page title. Your extension also creates redirects after changing the slug. If I change the slug back to the title which was before then a new redirect will be created and those will end in an neverending redirect on that page.

Explanation:

  1. page title: "page-a" -> change to "page-b" after saving the new slug, a redirect will be created from page-a to page-b
  2. page title: "page-b" -> change to "page-a" after saving the slug, a second redirect will be created.

I'm using master branch with composer.

Option last_segment_only results in dublicate path part or slashes in slug

This is a great option, but it has some problems:

  1. Dublicate page slug in subpath:
    Given: [https://servername.de/demo/test]/page1
    Changing page1 to page1new
    Result: [https://servername.de/demo/demo/test]/page1new
    Changing again to page1new2
    Result: [https://servername.de/demo/demo/test]/page1new2

  2. Problems when using slug as admin

    Given: [https://servername.de]/demo/test/page1
    Changing page1 to page1new
    Result: [https://servername.de]/demo/test/demo-test-page1new and error message
    "You are not allowed to insert slashes into the URL!" (message.slashesNotAllowed)

New pages created by an non-admin gets wrong slug

When a non-admin creates a new page by right-clicking an existing page and choosing new, so not via the page-drop-wizard, and the setting last_segment_only is activated the page gets the wrong slug. Saving the page again after the first generation fixes the slug.

How to reproduce:

  • In the extension configuration set basic.last_segment_only to true
  • Change to a non-admin user
  • As the non-admin user create a new page by right-clicking an existing page and choosing new
  • save the page
  • the slug is now [base-url] / [number] which is wrong
  • save the page again, the slug gets fixed

Expected behaviour:

  • The slug is being generated correctly the first time saving

Sluggi 1.10.1 and TYPO3 9.5.22, also tested it with the CMS10 version from https://github.com/GaryWilsonJr/sluggi and there it has the same problem

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.