Closed lindeer closed 2 years ago
Can you write full stack trace. For recursive loop use {% for article in _articles recursive %}
and loop(article.articles)
.
My stack trace after running your example without getPageByPath
function and filters:
Tried calling: call
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5)
#1 Context.call (package:jinja/src/context.dart:27:27)
...
#5 Binary.resolve (package:jinja/src/nodes/expressions.dart:1143:56) < article...
#7 If.accept (package:jinja/src/nodes/statements.dart:113:20) < {% if article....
#13 For.accept (package:jinja/src/nodes/statements.dart:70:20) < {% for article...
#18 Include.accept (package:jinja/src/nodes/statements.dart:236:20) < {% includ...
#23 With.accept (package:jinja/src/nodes/statements.dart:167:20) < {% with _art...
There is one if statement with binary expression and one calling: {% if article.path and getPageByPath(article.path) %}
.
Can you write full stack trace. For recursive loop use
{% for article in _articles recursive %}
andloop(article.articles)
.My stack trace after running your example without
getPageByPath
function and filters:Tried calling: call #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5) #1 Context.call (package:jinja/src/context.dart:27:27) ... #5 Binary.resolve (package:jinja/src/nodes/expressions.dart:1143:56) < article... #7 If.accept (package:jinja/src/nodes/statements.dart:113:20) < {% if article.... #13 For.accept (package:jinja/src/nodes/statements.dart:70:20) < {% for article... #18 Include.accept (package:jinja/src/nodes/statements.dart:236:20) < {% includ... #23 With.accept (package:jinja/src/nodes/statements.dart:167:20) < {% with _art...
There is one if statement with binary expression and one calling:
{% if article.path and getPageByPath(article.path) %}
.
Thanks @ykmnkmi ,it almost works!
changed to {% for article in _articles recursive %}
and loop(article.articles)
, another exception was thrown:
Unhandled exception:
type 'String' is not a subtype of type 'int' of 'index'
#0 Environment.getAttribute (package:jinja/src/environment.dart:297:20)
#1 Attribute.resolve (package:jinja/src/nodes/expressions.dart:852:32)
#2 Compare.resolve (package:jinja/src/nodes/expressions.dart:1002:22)
#3 StringSinkRenderer.visitIf (package:jinja/src/renderer.dart:544:27)
#4 If.accept (package:jinja/src/nodes/statements.dart:113:20)
...
#10 For.accept (package:jinja/src/nodes/statements.dart:70:20)
#15 Include.accept (package:jinja/src/nodes/statements.dart:236:20)
#18 Output.accept (package:jinja/src/nodes.dart:55:20)
#20 With.accept (package:jinja/src/nodes/statements.dart:167:20)
I found the error occured when rendering mock data part.articles.articles
on template {% if article.articles.length > 0 %}
(aaa.html:20), trying to call return fieldGetter(object, field);
(environment.dart:291), and context is object=[], field=length, type=String
, so 'length' is actually a built-in method, but code run directly as object's attribute return object[field];
(environment.dart:293).
I changed code locally as below:
} on NoSuchMethodError {
if (field == 'length') {
return object.length;
}
return object[field];
}
it works. It only help me locate the issue, but I have no idea what is correct fix.
Another question, when I append another article
item to deepest children, error still occur.
{
'file': {
},
'part': {
'articles': [
{
'path': '/user/to/file',
'anchor': "#nice",
'url': 'https://www.github.com',
'level': 0,
'title': 'That is Why You Go Away!',
'articles': [
{
'path': '/user/to/file2',
'anchor': "#good",
'url': 'https://www.reddit.com',
'level': 1,
'title': 'Title in depth 2',
'articles': [
],
},
],
},
],
}
}
and
Unhandled exception:
NoSuchMethodError: Closure call with mismatched arguments: function 'LoopContext.call'
Receiver: Closure: (Object?) => String from Function 'call':.
Tried calling: LoopContext.call(Instance(length:1) of '_GrowableList', _LinkedHashMap len:0, _LinkedHashMap len:4)
Found: LoopContext.call(Object?) => String
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:38:5)
#1 _objectNoSuchMethod (dart:core-patch/object_patch.dart:85:9)
#2 Function._apply (dart:core-patch/function_patch.dart:11:73)
#3 Function.apply (dart:core-patch/function_patch.dart:34:12)
#4 Context.call (package:jinja/src/context.dart:29:21)
#5 Call.resolve.<anonymous closure> (package:jinja/src/nodes/expressions.dart:614:21)
#6 Callable.apply (package:jinja/src/nodes/expressions.dart:498:20)
#7 Call.resolve (package:jinja/src/nodes/expressions.dart:613:12)
#14 If.accept (package:jinja/src/nodes/statements.dart:113:20)
#20 For.accept (package:jinja/src/nodes/statements.dart:70:20)
try this {% if article.articles %}
here is my working test code:
import 'package:jinja/jinja.dart';
void main() {
const raw = '''
{% with _articles=part.articles, file=file, config=config %}
{% include "aaa.html" %}
{% endwith %}''';
final tpl = Environment(
leftStripBlocks: true,
trimBlocks: true,
loader: MapLoader({
'aaa.html': '''
{% for article in _articles recursive %}
<li class="chapter{{ ' active' if article.path == file.path and not article.anchor }}" data-level="{{ article.level }}" {{ 'data-path="' ~ article.path ~ '"' if article.path }}>
{% if article.path %}
<a href="{{ article.path ~ article.anchor }}">
{% elif article.url %}
<a target="_blank" href="{{ article.url }}">
{% else %}
<span>
{% endif %}
{% if article.level != "0" %}
<b>{{ article.level }}.</b>
{% endif %}
{{ article.title }}
{% if article.path or article.url %}
</a>
{% else %}
</span>
{% endif %}
{% if article.articles %}
<ul class="articles">
{{ loop(article.articles) }}
</ul>
{% endif %}
</li>
{% endfor %}''',
}),
).fromString(raw);
final r = tpl.render(<String, dynamic>{
'file': {},
'part': {
'articles': [
{
'path': '/user/to/file',
'anchor': '#nice',
'url': 'https://www.github.com',
'level': 0,
'title': 'That is Why You Go Away!',
'articles': [
{
'path': '/user/to/file2',
'anchor': '#good',
'url': 'https://www.reddit.com',
'level': 1,
'title': 'Title in depth 2',
'articles': [],
},
],
},
],
}
});
print(r);
}
thanks @ykmnkmi, when I changed {{ loop(article.articles, file, config) }}
to {{ loop(article.articles) }}
, everything is OK :+1:
By the way, actually I was going to use 'macro' to implement this small function, but currently 'macro' is not available, so could I ask when this feature would be done~ :smile:
Of course this is case for macro. Maybe in this version.
I got this error when I tried to load a 'with' template, I am not sure my usage is correct: jinjia version 0.4.0-dev.31
but code throw exception as below:
aaa.html:
How could I fix it? My mock data should be right, 'case other templates could run without error. Thanks.