Skip to content

Commit

Permalink
Add Widget alternates for alias and slug (OrchardCMS#16860)
Browse files Browse the repository at this point in the history
---------

Co-authored-by: Mike Alhayek <[email protected]>
  • Loading branch information
giannik and MikeAlhayek authored Oct 12, 2024
1 parent 2ce75ef commit b4ff27a
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace OrchardCore.Alias.Services;

public class AliasShapeTableProvider : ShapeTableProvider
public sealed class ContentAliasShapeTableProvider : ShapeTableProvider
{
public override ValueTask DiscoverAsync(ShapeTableBuilder builder)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using OrchardCore.Alias.Models;
using OrchardCore.ContentManagement;
using OrchardCore.DisplayManagement;
using OrchardCore.DisplayManagement.Descriptors;
using OrchardCore.DisplayManagement.Utilities;

namespace OrchardCore.Alias.Services;

public sealed class WidgetAliasShapeTableProvider : ShapeTableProvider
{
public override ValueTask DiscoverAsync(ShapeTableBuilder builder)
{
builder.Describe("Widget")
.OnDisplaying(displaying =>
{
var shape = displaying.Shape;
var contentItem = shape.GetProperty<ContentItem>("ContentItem");
var aliasPart = contentItem?.As<AliasPart>();
if (aliasPart != null)
{
var encodedAlias = aliasPart.Alias.EncodeAlternateElement();
// Widget__Alias__[Alias] e.g. Widget-Alias-example, Widget-Alias-my-page
displaying.Shape.Metadata.Alternates.Add("Widget__Alias__" + encodedAlias);
// Widget_[DisplayType]__Alias__[Alias] e.g. Widget-Alias-example.Summary, Widget-Alias-my-page.Summary
displaying.Shape.Metadata.Alternates.Add("Widget_" + displaying.Shape.Metadata.DisplayType + "__Alias__" + encodedAlias);
}
});

return ValueTask.CompletedTask;
}
}
19 changes: 18 additions & 1 deletion src/OrchardCore.Modules/OrchardCore.Alias/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using OrchardCore.ContentTypes.Editors;
using OrchardCore.Data;
using OrchardCore.Data.Migration;
using OrchardCore.DisplayManagement;
using OrchardCore.DisplayManagement.Descriptors;
using OrchardCore.Indexing;
using OrchardCore.Liquid;
Expand Down Expand Up @@ -71,7 +72,23 @@ public override void ConfigureServices(IServiceCollection services)

services.AddScoped<IContentPartIndexHandler, AliasPartIndexHandler>();
services.AddScoped<IContentTypePartDefinitionDisplayDriver, AliasPartSettingsDisplayDriver>();
}
}

services.AddScoped<IShapeTableProvider, AliasShapeTableProvider>();
[RequireFeatures("OrchardCore.Contents")]
public sealed class ContentAliasStartup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddShapeTableProvider<ContentAliasShapeTableProvider>();
}
}

[RequireFeatures("OrchardCore.Widgets")]
public sealed class WidgetAliasStartup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddShapeTableProvider<WidgetAliasShapeTableProvider>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace OrchardCore.Autoroute.Services;

public class AutorouteShapeTableProvider : ShapeTableProvider
public sealed class ContentAutorouteShapeTableProvider : ShapeTableProvider
{
public override ValueTask DiscoverAsync(ShapeTableBuilder builder)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using OrchardCore.Autoroute.Models;
using OrchardCore.ContentManagement;
using OrchardCore.DisplayManagement;
using OrchardCore.DisplayManagement.Descriptors;
using OrchardCore.DisplayManagement.Utilities;

namespace OrchardCore.Autoroute.Services;

public sealed class WidgetAutorouteShapeTableProvider : ShapeTableProvider
{
public override ValueTask DiscoverAsync(ShapeTableBuilder builder)
{
builder.Describe("Widget")
.OnDisplaying(displaying =>
{
var shape = displaying.Shape;
var contentItem = shape.GetProperty<ContentItem>("ContentItem");
var autoroutePart = contentItem?.As<AutoroutePart>();
if (autoroutePart != null)
{
var encodedSlug = autoroutePart.Path.EncodeAlternateElement().Replace("/", "__");
// Widget__Slug__[Slug] e.g. Widget-Slug-example, Widget-Slug-blog-my-post
displaying.Shape.Metadata.Alternates.Add("Widget__Slug__" + encodedSlug);
// Widget_[DisplayType]__Slug__[Slug] e.g. Widget-Slug-example.Summary, Widget-Slug-blog-my-post.Summary
displaying.Shape.Metadata.Alternates.Add("Widget_" + displaying.Shape.Metadata.DisplayType + "__Slug__" + encodedSlug);
}
});

return ValueTask.CompletedTask;
}
}
23 changes: 20 additions & 3 deletions src/OrchardCore.Modules/OrchardCore.Autoroute/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
using OrchardCore.ContentTypes.Editors;
using OrchardCore.Data;
using OrchardCore.Data.Migration;
using OrchardCore.DisplayManagement;
using OrchardCore.DisplayManagement.Descriptors;
using OrchardCore.Indexing;
using OrchardCore.Liquid;
Expand Down Expand Up @@ -54,7 +55,7 @@ public override void ConfigureServices(IServiceCollection services)
if (!slug.StartsWith('/'))
{
slug = "/" + slug;
slug = '/' + slug;
}
(var found, var entry) = await autorouteEntries.TryGetEntryByPathAsync(slug);
Expand Down Expand Up @@ -98,8 +99,6 @@ public override void ConfigureServices(IServiceCollection services)

services.AddSingleton<AutorouteTransformer>();
services.AddSingleton<IShellRouteValuesAddressScheme, AutorouteValuesAddressScheme>();

services.AddScoped<IShapeTableProvider, AutorouteShapeTableProvider>();
}

public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
Expand All @@ -117,3 +116,21 @@ public override void ConfigureServices(IServiceCollection services)
services.AddScoped<IRouteableContentTypeProvider, AutorouteContentTypeProvider>();
}
}

[RequireFeatures("OrchardCore.Contents")]
public sealed class ContentAutourouteStartup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddShapeTableProvider<ContentAutorouteShapeTableProvider>();
}
}

[RequireFeatures("OrchardCore.Widgets")]
public sealed class WidgetAutourouteStartup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddShapeTableProvider<WidgetAutorouteShapeTableProvider>();
}
}
36 changes: 36 additions & 0 deletions src/docs/reference/modules/Templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,42 @@ This template is called when a widget is rendered on a page.
| `Model.ContentItem.Content` | A JSON object containing all the data of the content item. |
| `Model.Classes` | An array of all the classes attached to the widget. |

### `Widget__Alias__[Alias]`

This template is called when displaying a widget content item with a specific alias. It needs to have the `AliasPart` attached to it.

#### Widget with Alias Examples

| Template | Filename |
|----------------------------|--------------------------------|
| `Widget__Alias__example` | `Widget-Alias-example.cshtml` |
| `Widget__Alias__my__page` | `Widget-Alias-my-page.cshtml` |

#### Widget with Alias and Display Type Examples

| Template | Filename |
|------------------------------------|----------------------------------------|
| `Widget_Summary__Alias__example` | `Widget-Alias-example.Summary.cshtml` |
| `Widget_Summary__Alias__my__page` | `Widget-Alias-my-page.Summary.cshtml` |

### `Widget__Slug__[Slug]`

This template is called when displaying a widget content item with a specific slug (i.e., a path is assigned to the item). It needs to have the `AutoroutePart` attached to it.

#### Widget with Slug Examples

| Template | Filename |
|---------------------------------|------------------------------------|
| `Widget__Slug__example` | `Widget-Slug-example.cshtml` |
| `Widget__Slug__blog__my__post` | `Widget-Slug-blog-my-post.cshtml` |

#### Widget with Slug and Display Type Examples

| Template | Filename |
|-----------------------------------|----------------------------------------|
| `Widget_Summary__Slug__example` | `Widget-Slug-example.Summary.cshtml` |
| `Widget_Summary__Slug__blog__my__post` | `Widget-Slug-blog-my-post.Summary.cshtml` |

## Content Part templates

Each driver is free to return a shape type of its choosing, but the usage is
Expand Down
4 changes: 2 additions & 2 deletions src/docs/releases/2.1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ Additionally, the configuration provider key for the default provider has change

### Autoroute Feature

#### Content Item Shape Alternates Based on Alias and Slug
#### Content Item Shape Alternates Based on Alias and Slug (Content and Widget shapes)

Content item shapes can be overridden by their alias if `AliasPart` is attached or by their slug if `AutoroutePart` is attached. For examples, refer to the [docs](../reference/modules/Templates/README.md).
Content item shapes (Content and Widget local zones) can be overridden by their alias if `AliasPart` is attached or by their slug if `AutoroutePart` is attached. For examples, refer to the [docs](../reference/modules/Templates/README.md).

### Recipes Feature

Expand Down

0 comments on commit b4ff27a

Please sign in to comment.