summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md31
-rw-r--r--htmtl/htmtl.py17
-rw-r--r--htmtl/parsers/__init__.py10
-rw-r--r--htmtl/parsers/iterate.py67
-rw-r--r--pyproject.toml2
5 files changed, 105 insertions, 22 deletions
diff --git a/README.md b/README.md
index 31bc1a0..032228e 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ you to use any editor without needing any additional editor extensions.
<h1 inner-text="{title}"></h1>
<div class="posts" when="posts">
- <div foreach="posts as post">
+ <div iterate="posts as post">
<h2 class="post-title">
<a :href="/blog/{post.url}" inner-text="{post.title | Capitalize}"></a>
</h2>
@@ -50,8 +50,8 @@ A simple example of how to use HTMTL with default configuration looks like this:
```python
from htmtl import Htmtl
-htmtl = Htmtl('<p inner-text="Hello {who}"></p>', {'who': 'World'})
-html = htmtl.html() # returns: <p>Hello World</p>
+template = Htmtl('<p inner-text="Hello {who}"></p>', {'who': 'World'})
+html = template.to_html() # returns: <p>Hello World</p>
```
## Attributes
@@ -214,15 +214,14 @@ Results in:
<!-- Empty -->
```
-### `foreach`
+### `iterate`
Loops anything iterable.
-For example, to loop over a collection of `posts` and then use `post` as the variable of each iteration, you can do something
-like this:
+For example, to loop over a collection of `posts` and then use `post` as the variable of each iteration, you can do something like this:
```php
-<div foreach="posts as post">
+<div iterate="posts as post">
<h2 inner-text="post.title"></h2>
</div>
```
@@ -231,7 +230,7 @@ If you do not care about using any of the iteration data, you can also entirely
like so:
```php
-<div foreach="posts">
+<div iterate="posts">
...
</div>
```
@@ -239,7 +238,7 @@ like so:
And, you can also assign the key of the iteration to a variable, like so:
```php
-<div foreach="posts as index:post">
+<div iterate="posts as index:post">
<h2 :class="post-{post.index}" inner-text="post.title"></h2>
</div>
```
@@ -313,12 +312,12 @@ You can add (or replace) parsers in HTMTL when creating a new instance of the `H
from htmtl import Htmtl
from htmtl.parsers import InnerText
-htmtl = Htmtl('<p inner-text="Hello {who}"></p>', {'who': 'World'})
-htmtl.set_parsers([
+template = Htmtl('<p inner-text="Hello {who}"></p>', {'who': 'World'})
+template.set_parsers([
InnerText,
])
-html = htmtl.html() # returns: <p>Hello World</p>
+html = template.to_html() # returns: <p>Hello World</p>
```
Prsers must extend the `Parser` class, like so:
@@ -354,7 +353,7 @@ HTMTL is built upon the [Dompa](https://github.com/askonomm/dompa) HTML parser,
- `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**)
+- `htmtl.parsers.Iterate` - Parses the `iterate` attributes.
### Modifiers
@@ -364,12 +363,12 @@ You can add (or replace) modifiers in HTMTL when creating a new instance of the
from htmtl import Htmtl
from htmtl.modifiers import Truncate
-htmtl = Htmtl('<p inner-text="Hello {who}"></p>', {'who': 'World'})
-htmtl.set_modifiers([
+template = Htmtl('<p inner-text="Hello {who}"></p>', {'who': 'World'})
+template.set_modifiers([
Truncate,
])
-html = htmtl.html() # returns: <p>Hello World</p>
+html = template.to_html() # returns: <p>Hello World</p>
```
Mdifiers must extend the `Modifier` class, like so:
diff --git a/htmtl/htmtl.py b/htmtl/htmtl.py
index 7732f06..6570e11 100644
--- a/htmtl/htmtl.py
+++ b/htmtl/htmtl.py
@@ -1,18 +1,21 @@
from typing import Any
from dompa import Dompa
+from dompa.actions import ToHtml
+from dompa.nodes import Node
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.iterate import Iterate
from .parsers.outer_html import OuterHtml
from .parsers.outer_partial import OuterPartial
from .parsers.outer_text import OuterText
+from .parsers.when import When
+from .parsers.when_not import WhenNot
from .modifier import Modifier
from .modifiers.truncate import Truncate
from .expression_parser import ExpressionParser
-from .parsers.when import When
-from .parsers.when_not import WhenNot
class Htmtl:
@@ -27,6 +30,7 @@ class Htmtl:
# set default attribute parsers
self.__attribute_parsers = [
+ Iterate,
InnerText,
InnerHtml,
InnerPartial,
@@ -64,7 +68,12 @@ class Htmtl:
parser_instance = parser(self.__data, expression_parser)
self.__dom.traverse(parser_instance.traverse)
- def html(self) -> str:
+ def to_html(self) -> str:
+ self.__parse()
+
+ return self.__dom.action(ToHtml)
+
+ def nodes(self) -> list[Node]:
self.__parse()
- return self.__dom.html() \ No newline at end of file
+ return self.__dom.get_nodes() \ No newline at end of file
diff --git a/htmtl/parsers/__init__.py b/htmtl/parsers/__init__.py
index 4ad8185..5c98cba 100644
--- a/htmtl/parsers/__init__.py
+++ b/htmtl/parsers/__init__.py
@@ -1,2 +1,10 @@
from .inner_text import InnerText
-from .outer_text import OuterText \ No newline at end of file
+from .inner_html import InnerHtml
+from .inner_partial import InnerPartial
+from .outer_text import OuterText
+from .outer_html import OuterHtml
+from .outer_partial import OuterPartial
+from .generic_value import GenericValue
+from .when import When
+from .when_not import WhenNot
+from .iterate import Iterate \ No newline at end of file
diff --git a/htmtl/parsers/iterate.py b/htmtl/parsers/iterate.py
new file mode 100644
index 0000000..a70d026
--- /dev/null
+++ b/htmtl/parsers/iterate.py
@@ -0,0 +1,67 @@
+from collections.abc import Iterable
+from typing import Optional
+
+from dompa.nodes.actions import ToHtml
+from dompa.nodes import Node, FragmentNode
+from ..parser import Parser
+import htmtl
+
+class IterateOp:
+ var: str
+ iter_var_as: Optional[str]
+ iter_index_as: Optional[str]
+
+ def __init__(self, var: str, iter_var_as: Optional[str] = None, iter_index_as: Optional[str] = None):
+ self.var = var
+ self.iter_var_as = iter_var_as or None
+ self.iter_index_as = iter_index_as or None
+
+
+class Iterate(Parser):
+ def traverse(self, node: Node) -> Optional[Node]:
+ if "iterate" in node.attributes:
+ replacement_nodes = []
+ iterate_op = self.__parse_exp(node.attributes["iterate"])
+ collection = self.expression(iterate_op.var)
+ node.attributes.pop("iterate")
+
+ if isinstance(collection, Iterable):
+ data = self.data()
+
+ for idx, item in enumerate(collection):
+ if iterate_op.iter_var_as:
+ data[iterate_op.iter_var_as] = item
+
+ if iterate_op.iter_index_as:
+ data[iterate_op.iter_index_as] = idx
+
+ template = htmtl.Htmtl(node.action(ToHtml), data)
+ template_nodes = template.nodes()
+
+ if len(template_nodes) > 0:
+ replacement_nodes.append(template_nodes[0])
+
+ return FragmentNode(children=replacement_nodes)
+
+ return node
+
+ @staticmethod
+ def __parse_exp(exp: str) -> IterateOp:
+ parts = exp.split(" ")
+
+ if len(parts) == 3:
+ if parts[2].count(":") == 1:
+ return IterateOp(
+ var=parts[0].strip(),
+ iter_index_as=parts[2].split(":")[0].strip(),
+ iter_var_as=parts[2].split(":")[1].strip()
+ )
+
+ return IterateOp(
+ var=parts[0].strip(),
+ iter_var_as=parts[2].strip()
+ )
+
+ return IterateOp(
+ var=parts[0]
+ )
diff --git a/pyproject.toml b/pyproject.toml
index 440dc07..88142bd 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -8,7 +8,7 @@ authors = [
{ name = "Asko Nõmm", email = "asko@nmm.ee" }
]
dependencies = [
- "dompa>0.6.1"
+ "dompa>0.8.1"
]
classifiers = [
"Programming Language :: Python :: 3",