ykmnkmi / jinja.dart

Jinja2 template engine port for Dart.
https://pub.dev/packages/jinja
MIT License
51 stars 11 forks source link

type 'int' is not a subtype of type 'String' of 'value' template #24

Closed gslender closed 1 year ago

gslender commented 1 year ago

The following code produces an error (see below) and yet it should produce a valid result of 0

import 'package:jinja/jinja.dart';
void main() {
  String template =
      '{% if (value_json.value | int) == 0 %} 0 {% elif (value_json.value | int) <= 32 %} 24 {% elif (value_json.value | int) <= 66 %} 50 {% elif (value_json.value | int) <= 99 %} 99 {% endif %}';
  // using templates !!
  var env = Environment();
  var tmpl = env.fromString(template);
  Map<String, dynamic> jsonMap = {"time": 1675919717308, "value": 0};
  try {
    String data = tmpl.render({'value_json': jsonMap});
    print(data);
  } catch (e, s) {
    print('${e.toString()} template=$template jsonMap = $jsonMap');
    print(s);
  }
}

Error is produced as follows...

type 'int' is not a subtype of type 'String' of 'value' template={% if (value_json.value | int) == 0 %} 0 {% elif (value_json.value | int) <= 32 %} 24 {% elif (value_json.value | int) <= 66 %} 50 {% elif (value_json.value | int) <= 99 %} 99 {% endif %} jsonMap = {time: 1675919717308, value: 0}
#0      _TypeError._throwNew (dart:core-patch/errors_patch.dart:105:68)
#1      Function._apply (dart:core-patch/function_patch.dart:11:73)
#2      Function.apply (dart:core-patch/function_patch.dart:34:12)
#3      Environment.callCommon (package:jinja/src/environment.dart:291:21)
#4      Environment.callFilter (package:jinja/src/environment.dart:308:12)
#5      Context.filter (package:jinja/src/context.dart:94:24)
#6      Filter.resolve.callback (package:jinja/src/nodes/expressions.dart:706:22)
#7      Callable.apply (package:jinja/src/nodes/expressions.dart:539:20)
#8      Filter.resolve (package:jinja/src/nodes/expressions.dart:709:12)
#9      Compare.resolve (package:jinja/src/nodes/expressions.dart:1033:22)
#10     StringSinkRenderer.visitIf (package:jinja/src/renderer.dart:339:27)
#11     If.accept (package:jinja/src/nodes/statements.dart:114:20)
#12     StringSinkRenderer.visitTemplate (package:jinja/src/renderer.dart:385:15)
#13     Template.accept (package:jinja/src/environment.dart:567:20)
#14     Template.render (package:jinja/src/environment.dart:574:5)
#15     main (package:hub_mqtt/test.dart:11:24)
#16     _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#17     _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:192:26)
gslender commented 1 year ago

For reference, the template and values parse correctly using an online parser http://jinja.quantprogramming.com/

ykmnkmi commented 1 year ago

These are differences (not yet documented) from the original version - int filter accepts only String's. This filter is not needed if the values are integers or for comparison.

ykmnkmi commented 1 year ago

Of course you can overwrite int filter via Environment.

gslender commented 1 year ago

Of course you can overwrite int filter via Environment.

Can you point to an example or provide a hint ??

Unfortunately I cannot change the template or the values - I need the Jinja to work similar to the online version. Are you able to assist?

ykmnkmi commented 1 year ago

Yes, for example:

var env = Environment(
  filters: {
    // same as doInteger arguments with different value type
    'int': (Object? value, {int defaultValue = 0, int base = 10}) {
      print(value.runtimeType);

      if (value == null) {
        return defaultValue;
      }

      if (value is int) {
        return value;
      }

      if (value is num) {
        return value.toInt();
      }

      if (value is String) {
        return int.tryParse(value, radix: base) ?? defaultValue;
      }

      throw TypeError();
    },
  },
);
gslender commented 1 year ago

I tried this and something similar. There is now something wrong with the IF condition as it simply returns

int
int
int

Are you able to try the sample code I provided as it doesn't seem to work as expected.

EDIT: Expected result is 50

ykmnkmi commented 1 year ago

I put print to show that it works.

ykmnkmi commented 1 year ago

How it's equal to 50 if your value is 0. First if.

gslender commented 1 year ago

I believe this has resolved the issue for me. Thank you !!