https://discord.umbraco.com logo
Hands up if you think the "Redirect
# umbraco-chat
s
Hands up if you think the "Redirect Management" should be in "Settings" and not "Content" ?
l
I'm not sure. The issue is that you don't want to give a lot of editors access to the settings section. So from that perspective I would say: no, it shouldn't be in settings.
s
I get it the other way around, when editors start deleting redirects. Its one of those "piggy in the middle" scenarios, probably on a "per client" basis.
j
My editors want to update their redirects often. I wouldn't want to put it in settings for them. But also they want finer control so we usualy have Skybrud Redirects installed for them.
They used to manually update the IIS files themselves That's so much worse.
How many times has there been an XML tag that wasn't closed and the site broke...
d
r
This
m
Remembering a time (pre v8) when this was as easy as moving an xml node..
config/tree.config
And we used to move the
dictionary
out of
settings
, for a editor to access. Though dictionary happily sits in the translation section these days so not such an issue... But I wonder if you can do the same these days with other areas like Redirectmanagement.... Something along the lines of 🤷
Copy code
csharp
public class DictionaryTreeComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        // Remove the default dictionary tree controller
        builder.Trees().RemoveTreeController<DictionaryTreeController>();
        
        // Add your custom tree controller 
        // where we've inhertited the default one and chaged the section?
        builder.Trees().AddTreeController<CustomDictionaryTreeController>();
    }
}
https://cdn.discordapp.com/attachments/1527688481172754563/1528685477589160028/trees.config?ex=6a5f32cb&is=6a5de14b&hm=391ec2148d6291bb7b77eaad3185666e05ad0297eec268b289c750a69c1ece9e&
Ah actually RedirectManagement is a dashboard..
Copy code
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Dashboards;

public class MoveRedirectDashboardComposer : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        // Option A: Modify the existing dashboard's section mapping programmatically
        builder.Dashboards.Configure(collection =>
        {
            var dashboard = collection.FirstOrDefault(x => x.Alias == "redirectUrlManagement");
            if (dashboard != null)
            {
                // Change which section(s) the dashboard appears in 
                // (e.g., moving it from "content" to a custom section alias like "translation" or "settings")
                dashboard.Sections = new[] { "translation" }; 
            }
        });
    }
}
or package.manifest?
Copy code
{
  "dashboards": [
    {
      "alias": "redirectUrlManagement",
      "sections": [
        "translation"
      ],
      "view": "/umbraco/backoffice/views/dashboard/redirecturlmanagement.html",
      "weight": 10
    }
  ]
}
j
Yeah its not "right" for it, but its because its used by content editors who as was said above should not see settings, it would be alright if Umbraco's permissions were able to be more granular
Although having said that, you'd then pretty much end up with the whole settings section only having that in it if you did it anyway
s
@Mike Chambers This seems to work for v17 and v18. You basically de-register the dashboard extension, then assign it to the section you want it displayed in.
Copy code
javascript
export const onInit = (_host, extensionRegistry) => {
    const coreRedirectManagementManifest =
        extensionRegistry.getByAlias("Umb.Dashboard.RedirectManagement");

    extensionRegistry.exclude("Umb.Dashboard.RedirectManagement");

    extensionRegistry.register({
        type: "dashboard",
        alias: "DashboardTweaks.RedirectManagement",
        name: "Redirect Management",
        element: coreRedirectManagementManifest?.element,
        weight: 100,
        meta: {
            label: "Redirect Management",
            pathname: "redirect-management"
        },
        conditions: [
            {
                alias: "Umb.Condition.SectionAlias",
                match: "Umb.Section.Settings" // Or Library, etc.
            }
        ]
    });
};
m
Ah ok.. so use replace with https://github.com/umbraco/Umbraco-CMS/blob/main/src/Umbraco.Web.UI.Client/src/packages/documents/documents/redirect-management/info-app/manifests.ts the only change being
match: UMB_DOCUMENT_WORKSPACE_ALIAS,
with any other workspace alias.. though might have to update those import filepaths too? though that introduces a make sure we keep in sync with any umbraco future updates.. (though looks fairly simple so hopefully not constantly changing) I think I do prefer @User of grab the existing element and replace by reuse... rather than reimplement?
r
I’m going to asks stupid question here is there an actual benefit to one approach or the other Speed Reusability Code cleanliness Other Please tick which and explain more Ie is it situational Are there metrics we can use etc Are there reasons for one rather than the other
s
Depends if you see it as "replacing" or "moving". I think I still prefer my method, as it takes the extension by its named alias - meaning you don't need to worry if Umbraco decide to move the underpinning JS filepaths across versions v19+.... (import('./document-redirect-management-workspace-info-app.element.js'),)
m
@suedeapple (Paul) had a play (to minimize what needs to be re-declared... (and just straight js over ts...)
Copy code
json
{
  "name": "Dashboard Customization",
  "version": "1.0.0",
  "extensions": [
    {
      "type": "backofficeEntryPoint",
      "alias": "DashboardCustomization.EntryPoint",
      "name": "Dashboard Customization Entry Point",
      "js": "/App_Plugins/MoveRedirectManagementDashboard/dashboards-setup.js"
    }
  ]
}
wwwroot\App_Plugins\MoveRedirectManagementDashboard\dashboards-setup.js
Copy code
js
import { UMB_SETTINGS_SECTION_ALIAS } from '@umbraco-cms/backoffice/settings';
import { UMB_SECTION_ALIAS_CONDITION_ALIAS } from '@umbraco-cms/backoffice/section';

const REDIRECT_MANAGEMENT_DASHBOARD_ALIAS = 'Umb.Dashboard.RedirectManagement';

export const onInit = (_host, extensionRegistry) => {
    
    const coreManifest = extensionRegistry.getByAlias(REDIRECT_MANAGEMENT_DASHBOARD_ALIAS);

    if (!coreManifest) return;

    coreManifest.conditions = [{
        alias: UMB_SECTION_ALIAS_CONDITION_ALIAS,
        match: UMB_SETTINGS_SECTION_ALIAS,
    }];
};
we do also have
Copy code
js
extensionRegistry.appendCondition(REDIRECT_MANAGEMENT_DASHBOARD_ALIAS, {
      alias: UMB_SECTION_ALIAS_CONDITION_ALIAS,
      match: UMB_SETTINGS_SECTION_ALIAS,
  });
which could be even simpler.. but no corresponding
replaceCondition
.
@Luuk Peters (Proud Nerds) I also did try..
Copy code
json
{
  "name": "Dashboard Customization",
  "version": "1.0.0",
  "extensions": [
    {
      "type": "dashboard",
      "alias": "MoveRedirectManagementDashboard.Override",
      "name": "Redirect Management (Moved)",
      "weight": 10,
      "overwrites": "Umb.Dashboard.RedirectManagement",
      "element": "/App_Plugins/UmbracoRedirectManagement/redirect-management-dashboard.element.js",
      "meta": {
        "label": "Redirect Management",
        "pathname": "redirect-management"
      },
      "conditions": [
        {
          "alias": "Umb.Condition.SectionAlias",
          "match": "Umb.Section.Settings"
        }
      ]
    }
  ]
}
but that didn't seem to do anything šŸ™
l
Ah I think it might be because they are in different sections based on the condition.
r
Situational
m
surely
"overwrites": "Umb.Dashboard.RedirectManagement",
is the driver.. so whatever else the default implementation should be removed? I did think afterwards that the element would be cache busted, and checking the actuall request is..
/umbraco/backoffice/038d249741fdfbfa54eab7e101085aeed912c022/packages/documents/dashboard-redirect-management.element-BULrrh_Z.js
But still not sure why the
overwrites
is doing nothing... Are you saying that the conditions are some how different with an overwrites.. and only overwrites when the condition is met? Rather than the overwrites being mutually exclusive and the condition working as normal for when the package should display? That might make sense though would preclude overwriting to change conditions šŸ™‚ and overwriting only for functionality change (or specifically weight)?
s
What did I start?? lol šŸ•³ļø šŸ‡
2 Views