Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/martin-g/wicket-handlebars

Provides some specialized panels and some related utilities that enables users to work with Handlebars.js and Apache Wicket.
https://github.com/martin-g/wicket-handlebars

Last synced: about 2 months ago
JSON representation

Provides some specialized panels and some related utilities that enables users to work with Handlebars.js and Apache Wicket.

Awesome Lists containing this project

README

        

wicket-mustache
===============

Provides a specialized panel and some related utilities that enables users to work with Mustache and Apache Wicket.

Current build status: [![Build Status](https://buildhive.cloudbees.com/job/l0rdn1kk0n/job/wicket-mustache/badge/icon)](https://buildhive.cloudbees.com/job/l0rdn1kk0n/job/wicket-mustache/)

**wicket-mustache** dependes on [mustache.java](https://github.com/spullara/mustache.java).

Documentation:

- [Mustache.js manual](http://mustache.github.com/mustache.5.html)
- [Mustache.java manual](https://github.com/spullara/mustache.java)
- Passes all of the `mustache` [specification tests](https://github.com/mustache/spec) modulo whitespace differences

Add maven dependency:

```xml

de.agilecoders.wicket.mustache
wicket-mustache
0.1.0

```

Installation:

```java
/**
* @see org.apache.wicket.Application#init()
*/
@Override
public void init() {
super.init();

WicketMustache.install(this);
}
```

Usage
=====

Example template file:

{{#items}}
Name: {{name}}
Price: {{price}}
{{#features}}
Feature: {{description}}
{{/features}}
{{/items}}

Might be powered by some backing code:

```java
public class Context implements IScope {
List items() {
return Arrays.asList(
new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))),
new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly.")))
);
}

static class Item {
Item(String name, String price, List features) {
this.name = name;
this.price = price;
this.features = features;
}
String name, price;
List features;
}

static class Feature {
Feature(String description) {
this.description = description;
}
String description;
}
}
```

And would result in:

Name: Item 1
Price: $19.99
Feature: New!
Feature: Awesome!
Name: Item 2
Price: $29.99
Feature: Old.
Feature: Ugly.

Evaluation of the template proceeds serially. For instance, if you have blocking code within one of your callbacks
you the system will pause while executing them:

```java
static class Feature {
Feature(String description) {
this.description = description;
}

String description() throws InterruptedException {
Thread.sleep(1000);
return description;
}
}
```

If you change description to return a `Callable` instead it will automatically be executed in a separate
thread if you have provided an `ExecutorService` when you created your `MustacheFactory`.

```java
Callable description() throws InterruptedException {
return new Callable() {

@Override
public String call() throws Exception {
Thread.sleep(1000);
return description;
}
};
}
```

This enables scheduled tasks, streaming behavior and asynchronous i/o. Check out the `samples` module in order
to see a complete end-to-end example:

```java
package de.agilecoders.wicket;

import de.agilecoders.wicket.mustache.IScope;
import de.agilecoders.wicket.mustache.MustachePanel;
import org.apache.wicket.core.util.resource.PackageResourceStream;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.resource.IResourceStream;

import java.util.Arrays;
import java.util.List;

public class HomePage extends WebPage {
private static final long serialVersionUID = 1L;

public HomePage(final PageParameters parameters) {
super(parameters);

IModel scopeModel = new LoadableDetachableModel() {
@Override
public IScope load() {
return new Example();
}
};

add(new MustachePanel("template", scopeModel) {
@Override
protected IResourceStream newTemplateResourceStream() {
return new PackageResourceStream(HomePage.class, "template.mustache");
}
});
}

public static class Example implements IScope {

public List items() {
return Arrays.asList(
new Item("Item 1", "$19.99", Arrays.asList(new Feature("New!"), new Feature("Awesome!"))),
new Item("Item 2", "$29.99", Arrays.asList(new Feature("Old."), new Feature("Ugly.")))
);
}

static class Item {
Item(String name, String price, List features) {
this.name = name;
this.price = price;
this.features = features;
}

String name, price;
List features;
}

static class Feature {
Feature(String description) {
this.description = description;
}

String description;
}
}
}
```

Client Side Rendering
=====================

If you want to render your mustache template on client side you have two options: `ClientSideMustachePanel` and `LazyLoadingClientSideMustachePanel`.

```java
add(new ClientSideMustachePanel("template-client", scopeModel) {
@Override
protected IResourceStream newTemplateResourceStream() {
return new PackageResourceStream(HomePage.class, "template.mustache");
}
});

add(new LazyLoadingClientSideMustachePanel("template-lazy", scopeModel) {
@Override
protected IResourceStream newTemplateResourceStream() {
return new PackageResourceStream(HomePage.class, "template.mustache");
}

@Override
protected CharSequence loading() {
return "please wait...";
}

@Override
protected Duration delay() {
return Duration.seconds(5);
}
});
```