Skip to content

Commit

Permalink
Merge pull request #25 from askonomm/24-allow-interpolated-expression…
Browse files Browse the repository at this point in the history
…s-in-partial-related-attributes

24 allow interpolated expressions in partial related attributes
  • Loading branch information
askonomm authored Nov 6, 2024
2 parents 357a8c2 + 58e9f82 commit e6d499c
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 2 deletions.
4 changes: 3 additions & 1 deletion Htmt/AttributeParsers/InnerPartialAttributeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ public override void Parse(XmlNodeList? nodes)
n.RemoveAttribute("x:inner-partial");

if (string.IsNullOrEmpty(innerPartial)) continue;

var innerPartialValue = ParseExpression(innerPartial);

if (Utils.FindValueByKeys(Data, innerPartial.Split('.')) is not string partial) continue;
if (Utils.FindValueByKeys(Data, innerPartialValue.Split('.')) is not string partial) continue;

n.InnerXml = new Parser { Data = Data, Template = partial }.ToXml().OuterXml;
}
Expand Down
4 changes: 3 additions & 1 deletion Htmt/AttributeParsers/OuterPartialAttributeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ public override void Parse(XmlNodeList? nodes)
n.RemoveAttribute("x:outer-partial");

if (string.IsNullOrEmpty(outerPartial)) continue;

var outerPartialValue = ParseExpression(outerPartial);

if (Utils.FindValueByKeys(Data, outerPartial.Split('.')) is not string partial) continue;
if (Utils.FindValueByKeys(Data, outerPartialValue.Split('.')) is not string partial) continue;

var newNode = new Parser { Data = Data, Template = partial }.ToXml();
var parent = n.ParentNode;
Expand Down
52 changes: 52 additions & 0 deletions HtmtTests/AttributeParserTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,32 @@ public void TestInnerPartialAttributeParserWithHtmlEntities()
Assert.AreEqual("<html><body><div><h1>This way →</h1></div></body></html>", html);
}

[TestMethod]
public void TestInnerPartialAttributeParserWithInterpolatedExpression()
{
const string template = "<html><body><div x:inner-partial=\"partials.{partial}\" /></body></html>";
const string partial = "<h1>Hello, World!</h1>";
var partials = new Dictionary<string, object?> { { "something", partial } };
var data = new Dictionary<string, object?> { { "partials", partials }, { "partial", "something" } };
var parser = new Parser { Template = template, Data = data };
var html = parser.ToHtml();

Assert.AreEqual("<html><body><div><h1>Hello, World!</h1></div></body></html>", html);
}

[TestMethod]
public void TestInnerPartialAttributeParserWithInterpolatedExpressionNoData()
{
const string template = "<html><body><div x:inner-partial=\"partials.{partial}\" /></body></html>";
const string partial = "<h1>Hello, World!</h1>";
var partials = new Dictionary<string, object?> { { "something", partial } };
var data = new Dictionary<string, object?> { { "partials", partials } };
var parser = new Parser { Template = template, Data = data };
var html = parser.ToHtml();

Assert.AreEqual("<html><body><div /></body></html>", html);
}

[TestMethod]
public void TestOuterPartialAttributeParser()
{
Expand Down Expand Up @@ -363,4 +389,30 @@ public void TestOuterPartialAttributeParserWithHtmlEntities()

Assert.AreEqual("<html><body><h1>This way →</h1></body></html>", html);
}

[TestMethod]
public void TestOuterPartialAttributeParserWithInterpolatedExpression()
{
const string template = "<html><body><div x:outer-partial=\"partials.{partial}\" /></body></html>";
const string partial = "<h1>Hello, World!</h1>";
var partials = new Dictionary<string, object?> { { "something", partial } };
var data = new Dictionary<string, object?> { { "partials", partials }, { "partial", "something" } };
var parser = new Parser { Template = template, Data = data };
var html = parser.ToHtml();

Assert.AreEqual("<html><body><h1>Hello, World!</h1></body></html>", html);
}

[TestMethod]
public void TestOuterPartialAttributeParserWithInterpolatedExpressionNoData()
{
const string template = "<html><body><div x:outer-partial=\"partials.{partial}\" /></body></html>";
const string partial = "<h1>Hello, World!</h1>";
var partials = new Dictionary<string, object?> { { "something", partial } };
var data = new Dictionary<string, object?> { { "partials", partials } };
var parser = new Parser { Template = template, Data = data };
var html = parser.ToHtml();

Assert.AreEqual("<html><body><div /></body></html>", html);
}
}
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ The `partial` key has to be inside the Data dictionary, and it has to be a strin

The partial will inherit the data dictionary that the parent template has, so you can use the same data in the partial as you can in the parent template.

Inner partials also support interpolated expressions, so you can get partials dynamically, like so:

```html
<div x:inner-partial="parts.{partial}"></div>
```

Where `partial` is `{ "partial", "something" }`, and then `parts.something` would be the partial template it will load.

### `x:outer-partial`

Sets the outer HTML of the element to the value of the attribute, which is a partial template.
Expand All @@ -170,6 +178,14 @@ The `partial` key has to be inside the Data dictionary, and it has to be a strin

The partial will inherit the data dictionary that the parent template has, so you can use the same data in the partial as you can in the parent template.

Outer partials also support interpolated expressions, so you can get partials dynamically, like so:

```html
<div x:outer-partial="parts.{partial}"></div>
```

Where `partial` is `{ "partial", "something" }`, and then `parts.something` would be the partial template it will load.

### `x:if`

Removes the element if the attribute is falsey.
Expand Down

0 comments on commit e6d499c

Please sign in to comment.