All Projects → wttech → Slice

wttech / Slice

Licence: other
Slice - a framework which simplifies Sling/AEM development by using dependency injection pattern and mapping Sling resources into Java objects

Programming Languages

java
68154 projects - #9 most used programming language
groovy
2714 projects
CSS
56736 projects

Projects that are alternatives of or similar to Slice

aemtools
AEM Tools is Intellij IDEA plugin containing Adobe Experience Manager related features
Stars: ✭ 49 (-23.44%)
Mutual labels:  aem, htl, sightly
kotlin-guiced
Convenience Kotlin API over the Google Guice DI Library
Stars: ✭ 17 (-73.44%)
Mutual labels:  dependency-injection, guice, google-guice
google-guice-tutorials
4 part tutorial series on Google Guice
Stars: ✭ 28 (-56.25%)
Mutual labels:  dependency-injection, google-guice
AEM-DataLayer
Simple DataLayer API for Adobe Experience Manager
Stars: ✭ 33 (-48.44%)
Mutual labels:  aem, apache-sling
gradle-sling-plugin
Build rapidly Sling applications using Gradle Build System
Stars: ✭ 14 (-78.12%)
Mutual labels:  apache-sling, sling
gradle-aem-multi
Example Multi-Module AEM application built by Gradle Build System
Stars: ✭ 31 (-51.56%)
Mutual labels:  aem, apache-sling
noicejs
extremely thin async dependency injection
Stars: ✭ 16 (-75%)
Mutual labels:  dependency-injection, guice
di speed
Speed comparison of Dependency Injection Container
Stars: ✭ 18 (-71.87%)
Mutual labels:  dependency-injection
redi
💉 A dependency injection library for TypeScript & JavaScript, along with a binding for React.
Stars: ✭ 29 (-54.69%)
Mutual labels:  dependency-injection
BESTV
Android TV App powered by TMDb. It is a easy way to find the best TV content, the top movies, series... all of that in your TV.
Stars: ✭ 49 (-23.44%)
Mutual labels:  dependency-injection
react-obsidian
Dependency injection framework for React and React Native applications
Stars: ✭ 17 (-73.44%)
Mutual labels:  dependency-injection
inject
A simple Kotlin multi-platform abstraction around the javax.inject annotations.
Stars: ✭ 42 (-34.37%)
Mutual labels:  dependency-injection
rodi
Implementation of dependency injection for Python 3
Stars: ✭ 42 (-34.37%)
Mutual labels:  dependency-injection
HypertextLiteral.jl
Julia library for the string interpolation of HTML and SVG
Stars: ✭ 43 (-32.81%)
Mutual labels:  htl
ThunderboltIoc
One of the very first IoC frameworks for .Net that has no reflection. An IoC that casts its services before thunder casts its bolts.
Stars: ✭ 40 (-37.5%)
Mutual labels:  dependency-injection
wedi
[Deprecated] A lightweight dependency injection (DI) library for TypeScript, along with a binding for React.
Stars: ✭ 22 (-65.62%)
Mutual labels:  dependency-injection
vertx-mybatis
vertx sqlclient template using mybatis NON-BLOCK & ASYNCHRONOUS
Stars: ✭ 23 (-64.06%)
Mutual labels:  guice
vue-ioc
IoC and DI for Vue powered by InversifyJS and inspired by Angular Module syntactic sugar.
Stars: ✭ 39 (-39.06%)
Mutual labels:  dependency-injection
AzureFunctions.Extensions
This provides some useful extensions for Azure Functions.
Stars: ✭ 81 (+26.56%)
Mutual labels:  dependency-injection
graphql-server-typed
Using typescript and gql-code-gen for easy graphql setup
Stars: ✭ 32 (-50%)
Mutual labels:  dependency-injection

Wunderman Thompson Technology logo

Build Status Coverity Status Coverage Status Latest release

Slice


Slice Logo


Purpose

Slice is a framework which simplifies Sling/Adobe AEM development by using dependency injection pattern (DI). It glues Sling and Google Guice together, allowing developers to create a code with a clean separation of concerns. You can map resources to Java models seamlessly and thanks to DI arrange your application in easily testable and maintainable code.

What can you gain?

  • Lean and neat code, slicker design!
  • Improved testability of your code - thanks to dependency injection it can be easily unit-tested.
  • Improved maintenance of your code - all business logic arranged in clean and simple Java classes (POJOs)
  • Easy to start with! Slice is easy to learn and if you use it in all your projects, your developers know exactly how to start.
  • Faster development – code reuse, dependency injection and simplicity make you more efficient than ever.
  • Overall costs reduced!

Features

Separation of concerns

No more business logic in your view (JSP, HTL scripts) - business logic's place is in Java classes and Slice knows it!

Slice loves HTL. HTL loves Slice. They go together like strawberries and cream! Seamless integration you will love:

<div data-sly-use.model="com.example.components.text.TextModel">
    <p>${model.text}<p>
</div>

JSPs made clean and tidy - no more ugly scriptlets.

<slice:lookup var="model" type="<%=com.example.components.text.TextModel%>" />
<p>${model.text}</p>

Reusable Java models which expose data for your view - note that the same model can be used by HTL and JSP components - one model to feed them all!

@SliceResource
public class TextModel {
  
    @JcrProperty
    private String text;
  
    public String getText() {
        return text;
    }
}

Interested in details? Read about Slice concepts and how it works internally on our Wiki.

Mapping resources to Java objects

Slice allows you to map a resource to a plain Java object. It's annotation-driven, very easy to use and fully extensible, so you can write your own ways of mapping if a set of available features is not enough for your needs. Slice supports mapping of:

  • simple properties (String, Long, Boolean, etc.) into primitives and objects
  • simple properties into enums.
  • multi-value properties to arrays or lists
  • child resources to a Java object or list of objects
  • nested resources/classes hierarchy

The following code snippet demonstrates all of the above features in one model. It's simple - just annotate a class with @SliceResource and its fields with @JcrProperty to get auto mapping of resource properties to class fields:

@SliceResource
public class ComplexTextModel {

	@JcrProperty
	private String text;
	
	@JcrProperty
	private String[] styles;

	@JcrProperty
	private AlignmentEnum alignment;

	@Children(LinkModel.class)
	@JcrProperty
	private List<LinkModel> links;
	
	@JcrProperty
	private ImageModel image;

	//... do whatever business logic you want in your model
}

public enum AlignmentEnum {
	LEFT, RIGHT, CENTER;
}

@SliceResource(MappingStrategy.ALL)
public class LinkModel {
	private String path;
	private String label;
	//...
}

@SliceResource(MappingStrategy.ALL)
public class ImageModel {
	private String imagePath;
	private String altText;
	//...
}

Read more about mapping on our Wiki.

Dependency Injection with Google Guice

If your AEM components are more than simple text/image/title components (and they certainly are), then you probably need to combine their functionality with some external data or more complex business logic provided by other classes. Dependency injection allows you to do this easily and keep your code testable without boiler-plate code and unneeded arguments in methods used only to propagate a value down into the class hierarchy.

We took Guice as a DI container. Why it's awesome? Take a look here: Google I/O 2009 - Big Modular Java with Guice, and here to check motivation of Google Guice creators

To demonstrate an example of a complex component which combines use of Slice features with power of DI, take a look at the following code which is an implementation of a Twitter component.

<div data-sly-use.model="com.example.components.twitter.TwitterModel">
	<ul data-sly-list="${model.tweets}">
		<li>${item}</li>
	</ul>
</div>
@SliceResource
public class TwitterModel {

	@JcrProperty
	private int limit;

	private final TwitterHandler twitterHandler;
	
	@Inject
	public TwitterModel(TwitterHandler twitterHandler) {
		this.twitterHandler = twitterHandler;
	}

	//returns list of tweets limited by number configurable by authors
	public List<String> getTweets() {
		List<String> tweets = twitterHandler.readTweets();
		return tweets.subList(0, Math.max(tweets.size(), limit));
	}
	
	//...
}

The model of the component is fairly simple and fully testable because you can easily mock the TwitterHandler in your unit test case.

TwitterHandler is also very simple as it uses Twitter client (from Twitter4j library). Please note that this client is injected by Guice and you don't have to care about its configuration in the handler itself.

public class TwitterHandler {

	@Inject
	private Twitter twitterClient; //Twitter4j client

	public List<String> readTweets() {
		List<String> tweets = new ArrayList<String>();
		List<Status> statuses = twitterClient.getHomeTimeline();
		for (Status status : statuses) {
			tweets.add(status.getText());
		}
		return tweets;
	}
}

The configuration is set while instantiating the twitter client by Guice. To instruct Guice how to create the client object we need to create a so called provider. You can do this in module configuration. It reads some configuration properties from repository (using ModelProvider). ContextScope instructs Guice to create such an object only once per request or OSGi service call - yes, you can reuse the TwitterHandler in you OSGi services which are request/resource agnostic - that's the power of Slice!.

public class MyModule extends AbstractModule {

	private static final String TWITTER_CONFIG_PATH = "/etc/twitter/configuration/jcr:content/twitterConfig";

	@Provides
	@ContextScoped
	public Twitter getTwitter(ModelProvider modelProvider) {
		TwitterConfiguration config = modelProvider.get(TwitterConfiguration.class,
				TWITTER_CONFIG_PATH);
		ConfigurationBuilder builder = new ConfigurationBuilder(); // from Twitter4j
		builder.setOAuthConsumerKey(config.getOAuthKey())
				.setOAuthConsumerSecret(config.getOAuthSecret());
		TwitterFactory factory = new TwitterFactory(builder.build());
		return factory.getInstance();
	}

	//...

}

Prerequisites

  • AEM / Apache Sling 2
  • Maven 2.x, 3.x

Installation

Slice is available from the Maven Central Repo. However if you want to check out the newest development version, do the following:

Checkout the source code:

cd [folder of your choice]
git clone git://github.com/wttech/Slice.git
cd Slice

Compile and install:

mvn install

Usage

Add dependencies to your POM file:

(...)
<dependency>
	<groupId>com.cognifide.slice</groupId>
	<artifactId>slice-core-api</artifactId>
	<version>4.4.0</version>
</dependency>
<dependency>
	<groupId>com.cognifide.slice</groupId>
	<artifactId>slice-core</artifactId>
	<version>4.4.0</version>
</dependency>
<dependency>
	<groupId>com.cognifide.slice</groupId>
	<artifactId>slice-mapper</artifactId>
	<version>4.4.0</version>
</dependency>
<dependency>
	<groupId>com.cognifide.slice</groupId>
	<artifactId>slice-mapper-api</artifactId>
	<version>4.4.0</version>
</dependency>
(...)

The last thing you need to do is to prepare an Injector of your application in its BundleActivator. Read more on how to do this on our Wiki

AEM/CQ related add-ons:

Commercial Support

Technical support can be made available if needed. Please contact us for more details.

We can:

  • prioritize your feature request,
  • tailor the product to your needs,
  • provide a training for your engineers,
  • support your development teams.

More documentation


Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].