summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsko Nõmm <asko@nmm.ee>2025-01-03 21:54:17 +0200
committerAsko Nõmm <asko@nmm.ee>2025-01-03 21:54:17 +0200
commite1af30fad78b2740312d631b0d4a701e30d915df (patch)
tree4e1d531f70b2818f43ff07f39a96aa4d868e09fd
parent61c0b0d134d05c1647fa3356486d209bac87d8f6 (diff)
Implement `InnerPartial` and `OuterPartial` parsers.
-rw-r--r--README.md16
-rw-r--r--htmtl/expression_parser.py8
-rw-r--r--htmtl/htmtl.py4
-rw-r--r--htmtl/parser.py3
-rw-r--r--htmtl/parsers/inner_partial.py17
-rw-r--r--htmtl/parsers/outer_partial.py17
6 files changed, 58 insertions, 7 deletions
diff --git a/README.md b/README.md
index 7578e80..d002ea2 100644
--- a/README.md
+++ b/README.md
@@ -266,19 +266,25 @@ If the `slug` key is `hello-world`.
## Modifiers
-All interpolated values in expressions can be modified using modifiers. Modifiers are applied to the value of the attribute, and they can be chained, like so:
+All interpolated expressions can be modified using modifiers. Modifiers are applied to the value of the attribute, and they can be chained, like so:
```html
<h1 inner-text="{title | Uppercase | Reverse}"></h1>
```
-Note that if you have nothing other than the interpolated variable in the attribute, then you can omit the curly brackets, and so
-this would also work:
+Note that if you have nothing other than the interpolated variable in the attribute, then you can omit the curly brackets, and so this would also work:
```html
<h1 inner-text="title | Uppercase | Reverse"></h1>
```
+Modifiers can also take arguments which are passed within
+parentheses `(` and `)`, and can be either `int`, `float`, `str` or `bool`. For example:
+
+```html
+<h1 inner-text="some_var | SomeModifier(123, 'asd', true)"></h1>
+```
+
### `date`
Parses the value into a formatted date string.
@@ -342,10 +348,10 @@ HTMTL is built upon the [Dompa](https://github.com/askonomm/dompa) HTML parser,
- `htmtl.parsers.GenericValue` - Parser the `:*` attributes.
- `htmtl.parsers.If` - Parser the `if` attributes. (**soon**)
- `htmtl.parsers.Unless` - Parser the `unless` attributes. (**soon**)
-- `htmtl.parsers.InnerPartial` - Parser the `inner-partial` attributes. (**soon**)
+- `htmtl.parsers.InnerPartial` - Parser the `inner-partial` attributes.
- `htmtl.parsers.InnerHtml` - Parser the `inner-html` attributes.
- `htmtl.parsers.InnerText` - Parser the `inner-text` attributes.
-- `htmtl.parsers.OuterPartial` - Parser the `outer-partial` attributes. (**soon**)
+- `htmtl.parsers.OuterPartial` - Parser the `outer-partial` attributes.
- `htmtl.parsers.OuterHtml` - Parser the `outer-html` attributes.
- `htmtl.parsers.OuterText` - Parser the `outer-text` attributes.
- `htmtl.parsers.Foreach` - Parses the `foreach` attributes. (**soon**)
diff --git a/htmtl/expression_parser.py b/htmtl/expression_parser.py
index 795bde6..fc3aa8d 100644
--- a/htmtl/expression_parser.py
+++ b/htmtl/expression_parser.py
@@ -12,11 +12,15 @@ class ExpressionParser:
def parse(self, expression: str) -> Any:
# no curly brackets means that the whole thing is an interpolation
- if expression.count("{") != expression.count("}"):
+ if expression.count("{") == 0 and expression.count("}") == 0:
parsed_interpolation = self.__parse_interpolation(expression)
return parsed_interpolation
+ # uneven curly brackets means invalid syntax
+ if expression.count("{") != expression.count("}"):
+ return expression
+
# otherwise only parts of it are
parsed_expression = ""
interp_start = None
@@ -69,7 +73,7 @@ class ExpressionParser:
return value
@staticmethod
- def __parse_args_str_to_args(args_str) -> list[str]:
+ def __parse_args_str_to_args(args_str) -> list[str | int | float | bool]:
args = []
for idx, char in enumerate(args_str):
diff --git a/htmtl/htmtl.py b/htmtl/htmtl.py
index e5fa4f9..885fe94 100644
--- a/htmtl/htmtl.py
+++ b/htmtl/htmtl.py
@@ -3,8 +3,10 @@ from dompa import Dompa
from .parser import Parser
from .parsers.generic_value import GenericValue
from .parsers.inner_html import InnerHtml
+from .parsers.inner_partial import InnerPartial
from .parsers.inner_text import InnerText
from .parsers.outer_html import OuterHtml
+from .parsers.outer_partial import OuterPartial
from .parsers.outer_text import OuterText
from .modifier import Modifier
from .modifiers.truncate import Truncate
@@ -25,8 +27,10 @@ class Htmtl:
self.__attribute_parsers = [
InnerText,
InnerHtml,
+ InnerPartial,
OuterText,
OuterHtml,
+ OuterPartial,
GenericValue,
]
diff --git a/htmtl/parser.py b/htmtl/parser.py
index a91de0a..393a5bd 100644
--- a/htmtl/parser.py
+++ b/htmtl/parser.py
@@ -12,6 +12,9 @@ class Parser(ABC):
self.__data = data
self.__expression_parser = expression_parser
+ def data(self) -> dict[str, Any]:
+ return self.__data
+
def expression(self, expression: str) -> Any:
return self.__expression_parser.parse(expression)
diff --git a/htmtl/parsers/inner_partial.py b/htmtl/parsers/inner_partial.py
new file mode 100644
index 0000000..a2cd7f0
--- /dev/null
+++ b/htmtl/parsers/inner_partial.py
@@ -0,0 +1,17 @@
+from typing import Optional
+
+from dompa import Dompa
+from dompa.nodes import Node
+
+from ..parser import Parser
+import htmtl
+
+class InnerPartial(Parser):
+ def traverse(self, node: Node) -> Optional[Node]:
+ if "inner-partial" in node.attributes:
+ template = htmtl.Htmtl(self.expression(node.attributes["inner-partial"]), self.data())
+ child_nodes = Dompa(template.html()).nodes()
+ node.children = child_nodes
+ node.attributes.pop("inner-partial")
+
+ return node \ No newline at end of file
diff --git a/htmtl/parsers/outer_partial.py b/htmtl/parsers/outer_partial.py
new file mode 100644
index 0000000..de96771
--- /dev/null
+++ b/htmtl/parsers/outer_partial.py
@@ -0,0 +1,17 @@
+from typing import Optional
+
+from dompa import Dompa
+from dompa.nodes import Node, FragmentNode
+
+from ..parser import Parser
+import htmtl
+
+class OuterPartial(Parser):
+ def traverse(self, node: Node) -> Optional[Node]:
+ if "outer-partial" in node.attributes:
+ template = htmtl.Htmtl(self.expression(node.attributes["outer-partial"]), self.data())
+ replacement_nodes = Dompa(template.html()).nodes()
+
+ return FragmentNode(children=replacement_nodes)
+
+ return node \ No newline at end of file