Skip to content

Commit

Permalink
Make it possible to add Razor HTML content to the shape as a property (
Browse files Browse the repository at this point in the history
…#14867)

Co-authored-by: Zoltán Lehóczky <[email protected]>
Co-authored-by: Hisham Bin Ateya <[email protected]>
  • Loading branch information
3 people authored Jul 24, 2024
1 parent af59baa commit 79a0853
Show file tree
Hide file tree
Showing 7 changed files with 100 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,13 @@ public async Task<ActionResult> DisplayShape(string contentItemId)
return NotFound();
}

var shape = Shape
.Foo()
.Line(contentItem.As<TestContentPartA>().Line);
var shape = await Shape.Foo(Line: contentItem.As<TestContentPartA>().Line);

return View(shape);
}

public IActionResult AddProperty() => View();

public ActionResult Raw()
{
return View();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@using Microsoft.AspNetCore.Html

<div class="border">
<p>The content is inserted below this line.</p>
<p>@Model.HtmlContent</p>
<p>The content is inserted above this line.</p>

@if (Model.SomeProperty != null)
{
<p>And here is another property: @Model.SomeProperty.</p>
}

@if (Model.OtherContent is IHtmlContent otherContent)
{
<div class="border">
<p>Another property called "OtherContent" starts here.</p>
<p>@otherContent</p>
<p>Another property called "OtherContent" ends here.</p>
</div>
}
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
@using Microsoft.AspNetCore.Html

<shape type="EmbedContentInShape">
<add-property name="HtmlContent">
The inner HTML of the <code>&lt;add-property name="propertyName"&gt;</code> tag helper (which is a direct child
of the <code>&lt;shape&gt;</code> tag helper) is converted into HTML and then passed to the shape as a model
property. The property's name is the string passed into the <code>name</code> attribute.
<shape type="TestContentPartA" Line="Sample Data" Creating="Now" Processing="Later"/>
Even other shapes can be included!
</add-property>
<add-property name="OtherContent">
You can have multiple, they are just <code>@nameof(IHtmlContent)</code> type shape properties.
</add-property>
<add-property name="SomeProperty" value="Some value passed to the attribute." />
</shape>

<shape type="EmbedContentInShape" HtmlContent="This property is ignored.">
<add-property name="HtmlContent">
If a <code>&lt;add-property&gt;</code> tag helper exists, it takes precedence over any matching attribute of the
<code>&lt;shape&gt;</code> tag helper. This is because child tag helpers are evaluated after the shape is
created, right before it's displayed.
</add-property>
</shape>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Threading.Tasks;

namespace OrchardCore.DisplayManagement.TagHelpers;

[HtmlTargetElement("add-property", Attributes = "name", TagStructure = TagStructure.NormalOrSelfClosing)]
public class AddPropertyTagHelper : TagHelper
{
[HtmlAttributeName("name")]
public string Name { get; set; }

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
if (string.IsNullOrWhiteSpace(Name))
{
return;
}

var content = await output.GetChildContentAsync(useCachedResult: false);
var shape = (IShape)context.Items[typeof(IShape)];
shape.Properties[Name.Trim()] = output.Attributes.ContainsName("value")
? output.Attributes["value"].Value
: new HtmlString(content.GetContent());

output.SuppressOutput();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public override async Task ProcessAsync(TagHelperContext tagHelperContext, TagHe
shape.Metadata.Wrappers.Add(Convert.ToString(output.Attributes["wrapper"].Value));
}

tagHelperContext.Items.Add(typeof(IShape), shape);
tagHelperContext.Items[typeof(IShape)] = shape;

if (!string.IsNullOrWhiteSpace(Cache))
{
Expand Down
20 changes: 20 additions & 0 deletions src/docs/reference/core/Placement/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,26 @@ Metadata tag helper example:
</menu>
```

#### Adding properties with additional tag helpers

Properties can be passed to a shape by adding attributes to the shape tag helper, as mentioned above. But you can also use the `<add-property>` tag helper inside `<shape>`. This even lets you pass Razor code as properties with the `IHtmlContent` value, if you omit the `value` attribute. Something that can't be easily done otherwise.

```xml
<shape type="MyShape">
<add-property name="foo" value="1" />
<add-property name="bar" value="a" />
<add-property name="content">
<h2>Some complicated HTML</h2>
<div>
You can even include shapes:
<shape type="AnotherShape" prop-count="10" />
</div>
</add-property>
</shape>
```

This is the same as `<shape type="MyShape" pro-foo="1" prop-bar="a" prop-content="@someHtmlContentVariable" />` where you'd have to construct `someHtmlContentVariable` separately. Of course, you can mix and match the different formats, for example, to only use `<add-property>` when you want to pass HTML content as property.

### Date Time shapes

#### `DateTime`
Expand Down
4 changes: 4 additions & 0 deletions src/docs/releases/2.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,10 @@ A new filter named `supported_cultures` was added to allow you to get a list of
</ul>
```

### Adding properties with additional tag helpers

The new `<add-property>` tag helper can be placed inside the `<shape>` tag helpers to add properties to the shape. This is similar to `prop-*` attributes, but you can also include Razor code as the `IHtmlContent` property value, which was impossible before. See more details [here](../reference/core/Placement/README.md#adding-properties-with-additional-tag-helpers).

### Sealing Types

Many type commonly used by modules can be `sealed`, which improves runtime performance. While it's not mandatory, we recommend that you consider applying this improvement to your own extensions as well. We've implemented this enhancement in the following pull-requests:
Expand Down

0 comments on commit 79a0853

Please sign in to comment.