private CharSequence iterableContext(Iterable<?> context, Options options) throws IOException {
    if (options.isFalsy(context)) {
      return options.inverse();
    }

    StringBuilder buffer = new StringBuilder();

    Iterator<?> iterator = reverse(context);
    int index = 0;
    Context parent = options.context;
    while (iterator.hasNext()) {
      Object element = iterator.next();

      boolean first = index == 0;
      boolean even = index % 2 == 0;
      boolean last = !iterator.hasNext();

      Context current =
          Context.newContext(parent, element)
              .data("index", index)
              .data("first", first ? "first" : "")
              .data("last", last ? "last" : "")
              .data("odd", even ? "" : "odd")
              .data("even", even ? "even" : "");
      buffer.append(options.fn(current));

      index++;
    }

    return buffer;
  }
Beispiel #2
0
  @SuppressWarnings("unchecked")
  @Override
  protected void merge(final Context context, final Writer writer) throws IOException {
    if (body == null) {
      return;
    }
    final String helperName;
    Helper<Object> helper = helper(name);
    Template template = body;
    final Object childContext;
    Context currentScope = context;
    if (helper == null) {
      childContext = transform(context.get(name));
      if (inverted) {
        helperName = UnlessHelper.NAME;
      } else if (childContext instanceof Iterable) {
        helperName = EachHelper.NAME;
      } else if (childContext instanceof Boolean) {
        helperName = IfHelper.NAME;
      } else if (childContext instanceof Lambda) {
        helperName = WithHelper.NAME;
        template =
            Lambdas.compile(
                handlebars,
                (Lambda<Object, Object>) childContext,
                context,
                template,
                startDelimiter,
                endDelimiter);
      } else {
        helperName = WithHelper.NAME;
        currentScope = Context.newContext(context, childContext);
      }
      // A built-in helper might be override it.
      helper = handlebars.helper(helperName);
    } else {
      helperName = name;
      childContext = transform(determineContext(context));
    }
    Options options =
        new Options.Builder(handlebars, helperName, TagType.SECTION, currentScope, template)
            .setInverse(inverse == null ? Template.EMPTY : inverse)
            .setParams(params(currentScope))
            .setHash(hash(context))
            .build();
    options.data(Context.PARAM_SIZE, this.params.size());

    CharSequence result = helper.apply(childContext, options);
    if (!isEmpty(result)) {
      writer.append(result);
    }
  }
  private CharSequence hashContext(Object context, Options options) throws IOException {
    StringBuilder buffer = new StringBuilder();

    Context parent = options.context;
    Iterator<Map.Entry<String, Object>> iterator = reverse(options.propertySet(context));
    while (iterator.hasNext()) {
      Map.Entry<String, Object> entry = iterator.next();
      Context current = Context.newContext(parent, entry.getValue()).data("key", entry.getKey());
      buffer.append(options.fn(current));
    }

    return buffer;
  }
 @Override
 public CharSequence apply(final Object context, final Options options) throws IOException {
   if (context == null) {
     return null;
   }
   if (options.params.length <= 0) {
     return context.toString();
   }
   Context ctx = Context.newBuilder(options.context, context).build();
   Object lookup = ctx.get(options.param(0).toString());
   if (lookup == null) {
     return null;
   }
   return lookup.toString();
 }