diff --git a/spring-data-neo4j-examples/todos/.gitignore b/spring-data-neo4j-examples/todos/.gitignore new file mode 100644 index 000000000..126bde297 --- /dev/null +++ b/spring-data-neo4j-examples/todos/.gitignore @@ -0,0 +1,9 @@ +target/ +.idea +*.iml +.project +.classpath +.settings/ +*.swp +*~ +.DS_Store diff --git a/spring-data-neo4j-examples/todos/Procfile b/spring-data-neo4j-examples/todos/Procfile new file mode 100644 index 000000000..845910083 --- /dev/null +++ b/spring-data-neo4j-examples/todos/Procfile @@ -0,0 +1 @@ +web: sh target/bin/webapp diff --git a/spring-data-neo4j-examples/todos/bin/todo b/spring-data-neo4j-examples/todos/bin/todo new file mode 100755 index 000000000..0d140bc2d --- /dev/null +++ b/spring-data-neo4j-examples/todos/bin/todo @@ -0,0 +1,60 @@ +#!/bin/sh + +while getopts ":r" opt; do + case $opt in + r) + export APP_URL=`heroku info --raw | sed -n 's/^web_url=\(.*\)$/\1/p'` + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + ;; + esac + shift +done + +APP_URL=${APP_URL:="http://localhost:8080/"} +REST_ENDPOINT="${APP_URL}api/todos" +CURL_OPTS="--verbose --fail -H Accept:application/json -H Content-Type:application/json" + +list() { + curl ${CURL_OPTS} ${REST_ENDPOINT} +} + +make() { + TITLE=$1 + curl -d "{ \"title\" :\"${TITLE}\"}" ${CURL_OPTS} ${REST_ENDPOINT} +} + +remove() { + ID=$1 + REST_ENDPOINT="${REST_ENDPOINT}/${ID}" + curl -X DELETE ${CURL_OPTS} ${REST_ENDPOINT} +} + +usage() { + echo "Usage: $0 { list | mk | rm }" +} + +if [ "$1" == "" ]; then + usage + exit 1 +fi + + +case "$1" in + list) + list + ;; + + mk) + if [ "$2" == "" ]; then usage; echo " mk \"text\""; exit 1; fi + make "$2" + ;; + rm) + if [ "$2" == "" ]; then usage; echo " rm {id}"; exit 1; fi + remove "$2" + ;; + *) + usage + ;; +esac diff --git a/spring-data-neo4j-examples/todos/pom.xml b/spring-data-neo4j-examples/todos/pom.xml new file mode 100644 index 000000000..e0603aa67 --- /dev/null +++ b/spring-data-neo4j-examples/todos/pom.xml @@ -0,0 +1,362 @@ + + 4.0.0 + + org.neo4j.app + sdn-todos + 1.0-SNAPSHOT + jar + + sdn-todos + + + UTF-8 + 1.5 + 3.0.6.RELEASE + 2.0.0.RC1 + 1.6.12 + 1.6.1 + + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + neo4j-public-repository + http://m2.neo4j.org/ + Publicly available Maven 2 repository for Neo4j + + + spring-maven-milestone + http://maven.springframework.org/milestone + Spring Framework Maven MILESTONE Repository + + true + + + + spring-maven-snapshot + http://maven.springframework.org/snapshot + Springframework Maven SNAPSHOT Repository + + true + + + + + + spring-maven-release + Spring Maven Release Repository + http://maven.springframework.org/release + + + spring-maven-milestone + Spring Maven Milestone Repository + http://maven.springframework.org/milestone + + + + + + junit + junit + 4.8.2 + test + + + log4j + log4j + 1.2.16 + + + org.slf4j + slf4j-api + ${slf4j.version} + + + org.slf4j + jcl-over-slf4j + ${slf4j.version} + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjweaver + ${aspectj.version} + + + javax.servlet + servlet-api + 2.5 + compile + + + net.sf.flexjson + flexjson + 2.1 + + + + org.eclipse.jetty + jetty-webapp + 7.4.4.v20110707 + + + org.mortbay.jetty + jsp-2.1-glassfish + 2.1.v20100127 + + + + + org.springframework + spring-core + ${spring.version} + + + commons-logging + commons-logging + + + + + org.springframework + spring-test + ${spring.version} + test + + + commons-logging + commons-logging + + + + + org.springframework + spring-context + ${spring.version} + + + org.springframework + spring-aop + ${spring.version} + + + org.springframework + spring-aspects + ${spring.version} + + + org.springframework + spring-tx + ${spring.version} + + + org.springframework.data + spring-data-neo4j-aspects + ${spring-data-neo4j.version} + + + org.springframework.data + spring-data-neo4j-rest + ${spring-data-neo4j.version} + + + javax.validation + validation-api + 1.0.0.GA + + + org.neo4j + neo4j + ${neo4j.version} + + + org.neo4j + neo4j-udc + + + + + org.springframework + spring-web + ${spring.version} + + + + commons-logging + commons-logging + + + + + org.springframework + spring-webmvc + ${spring.version} + + + + commons-logging + commons-logging + + + + + + + + org.codehaus.mojo + appassembler-maven-plugin + 1.1.1 + + + package + assemble + + target + -Xmx512m + + + Main + webapp + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.6 + 1.6 + UTF-8 + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.2 + + + + org.aspectj + aspectjrt + ${aspectj.version} + + + org.aspectj + aspectjtools + ${aspectj.version} + + + + + + compile + test-compile + + + + + true + + + org.springframework + spring-aspects + + + org.springframework.data + spring-data-neo4j-aspects + + + 1.6 + 1.6 + + + + org.apache.maven.plugins + maven-resources-plugin + 2.5 + + UTF-8 + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.8 + + false + true + + + + + org.apache.maven.plugins + maven-eclipse-plugin + 2.7 + + true + false + 2.0 + + + org.eclipse.ajdt.core.ajbuilder + + org.springframework.aspects + + + + org.springframework.ide.eclipse.core.springbuilder + + + + org.eclipse.ajdt.ui.ajnature + org.springframework.ide.eclipse.core.springnature + + + + + org.apache.maven.plugins + maven-idea-plugin + 2.2 + + true + true + + + + org.codehaus.mojo + tomcat-maven-plugin + 1.1 + + + org.mortbay.jetty + jetty-maven-plugin + 7.4.2.v20110526 + + + /${project.name} + + + + + + + diff --git a/spring-data-neo4j-examples/todos/readme.md b/spring-data-neo4j-examples/todos/readme.md new file mode 100644 index 000000000..fb4fbbe38 --- /dev/null +++ b/spring-data-neo4j-examples/todos/readme.md @@ -0,0 +1,87 @@ +Spring Data Neo4j Todos +======================= + +A simple todo list using Spring Data Neo4j, configured for easy deployment to Heroku. + +Get Ready +--------- + +To prepare for deploying to Heroku, you must first become a Hero: + +* Create an account on [Heroku](http://heroku.com) +* Install the `heroku` command-line client +* See the [Heroku Quickstart](http://devcenter.heroku.com/articles/quickstart) for details + +Feel ready? OK, then get a copy of this project and checkout the heroku-deploy branch: + +```bash +git clone git://github.com/akollegger/sdn-todos.git +cd sdn-todos +git checkout heroku-deploy +``` + +Local build and run +------------------- + +* Run a local Neo4j server (using default config) + +```bash +export NEO4J_REST_URL=http://localhost:7474/db/data +export NEO4J_LOGIN="" +export NEO4J_PASSWORD="" +``` +* Build, then run locally + +```bash +mvn package +sh target/bin/webapp +``` + +* check that it is working + +```bash +./bin/todo mk "tweet high praises to @neo4j" +./bin/todo list +``` + +Satisfied? Then `ctrl-c` to kill the application. + + +Deploy on Heroku +---------------- + +Create a new provisioning stack on Heroku for the app. + +```bash +heroku create --stack cedar` +heroku addons:add neo4j +git push heroku heroku-deploy:master +``` + +Check to make sure it is running with `heroku ps`, which should show a `web.1` process with an "up" state. + +Finally try it out using the `-r` flag to indicate remote access. + +```bash +./bin/todo -r mk "tweet thanks for the good work @mesirii @akollegger" +./bin/todo -r list +``` + +To see the Neo4j graph you just created through Heroku, use `heroku config` to reveal the NEO4J_URL +which can take you to Neo4j's Webadmin. Have fun! + +For a detailed play-by-play, read [Becoming a Heroku](https://github.com/akollegger/sdn-todos/wiki/Becoming-a-Hero(ku)) + +CLI Tool +-------- + +A simplistic `todo` script in the `bin` directory can directly create, delete and list todos. + + Usage: todo [-r] [ list | mk | rm ] + + todo -r - access the remote (Heroku) todo application + todo list - list current todos + todo mk "a new todo" - to create a todo + todo rm 1 - to remove the todo with id 1 + + diff --git a/spring-data-neo4j-examples/todos/src/main/java/Main.java b/spring-data-neo4j-examples/todos/src/main/java/Main.java new file mode 100644 index 000000000..b34ddc186 --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/java/Main.java @@ -0,0 +1,23 @@ +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.webapp.WebAppContext; +public class Main +{ + public static void main(String[] args) throws Exception + { + String webappDirLocation = "src/main/webapp/"; + String webPort = System.getenv("PORT"); + if(webPort == null || webPort.isEmpty()) { + webPort = "8080"; + } + Server server = new Server(Integer.valueOf(webPort)); + WebAppContext root = new WebAppContext(); + root.setContextPath("/"); + root.setDescriptor(webappDirLocation+"/WEB-INF/web.xml"); + root.setResourceBase(webappDirLocation); + root.setParentLoaderPriority(true); + server.setHandler(root); + server.start(); + server.join(); + } +} + diff --git a/spring-data-neo4j-examples/todos/src/main/java/org/neo4j/app/todos/Todo.java b/spring-data-neo4j-examples/todos/src/main/java/org/neo4j/app/todos/Todo.java new file mode 100644 index 000000000..acafebb11 --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/java/org/neo4j/app/todos/Todo.java @@ -0,0 +1,76 @@ +package org.neo4j.app.todos; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.neo4j.graphdb.Node; +import org.springframework.beans.factory.annotation.Configurable; +import org.springframework.data.neo4j.annotation.GraphId; +import org.springframework.data.neo4j.annotation.NodeEntity; + +import flexjson.JSONDeserializer; +import flexjson.JSONSerializer; + +@NodeEntity +@Configurable +public class Todo { + + @SuppressWarnings("unused") + @GraphId + private Long id; + + private String title; + + private Boolean isDone = false; + + public Todo() {;} + + public Todo(Node n) { + setPersistentState(n); + } + + public Long getId() { + return getNodeId(); + } + + public String getTitle() { + return this.title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Boolean getIsDone() { + return this.isDone; + } + + public void setIsDone(Boolean done) { + this.isDone = done; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Done: ").append(getIsDone()).append(", "); + sb.append("Title: ").append(getTitle()); + return sb.toString(); + } + + public String toJson() { + return new JSONSerializer().exclude("*.class", "*.persistentState", "*.entityState").serialize(this); + } + + public static String toJsonArray(Iterable collection) { + return new JSONSerializer().exclude("*.class", "*.persistentState", "*.entityState").serialize(collection); + } + + public static Todo fromJsonToTodo(String json) { + return new JSONDeserializer().use(null, Todo.class).deserialize(json); + } + + public static Collection fromJsonArrayToTodoes(String json) { + return new JSONDeserializer>().use(null, ArrayList.class).use("values", Todo.class).deserialize(json); + } + +} diff --git a/spring-data-neo4j-examples/todos/src/main/java/org/neo4j/app/todos/TodoController.java b/spring-data-neo4j-examples/todos/src/main/java/org/neo4j/app/todos/TodoController.java new file mode 100644 index 000000000..a747f87c7 --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/java/org/neo4j/app/todos/TodoController.java @@ -0,0 +1,127 @@ +package org.neo4j.app.todos; + +import java.io.UnsupportedEncodingException; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.util.UriUtils; +import org.springframework.web.util.WebUtils; + +@RequestMapping("/todos") +@Controller +public class TodoController { + + @Autowired TodoRepository todos; + + /** + * POST /todos { "title": "text of the todo" } + * + * Creates a new todo. + * + * @param json + * @return json containing the id of the newly created todo + */ + @RequestMapping(method = RequestMethod.POST, headers = "Accept=application/json") + public ResponseEntity createFromJson(@RequestBody String json) { + Todo createdTodo = todos.save(Todo.fromJsonToTodo(json)); + HttpHeaders headers= new HttpHeaders(); + headers.add("Content-Type", "application/text"); + return new ResponseEntity("{\"id\":" + createdTodo.getId() + "}", headers, HttpStatus.CREATED); + } + + /** + * GET /todos/{id} + * + * Gets the full json for a todo. + * + * @param id + * @return json representation of the requested todo, or HttpStatus.NOT_FOUND + */ + @RequestMapping(value = "/{id}", method = RequestMethod.GET, headers = "Accept=application/json") + @ResponseBody + public ResponseEntity showJson(@PathVariable("id") Long id) { + Todo todo = todos.findOne(id); + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type", "application/text; charset=utf-8"); + if (todo == null) { + return new ResponseEntity(headers, HttpStatus.NOT_FOUND); + } + return new ResponseEntity(todo.toJson(), headers, HttpStatus.OK); + } + + /** + * Get /todos/ + * + * Gets a json array of all todos. + * + * @return json array representation of all todos + */ + @RequestMapping(headers = "Accept=application/json") + @ResponseBody + public ResponseEntity listJson() { + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type", "application/text; charset=utf-8"); + return new ResponseEntity(Todo.toJsonArray(todos.findAll()), headers, HttpStatus.OK); + } + + /** + * PUT /todos/ { "id": id, "title": "text of todo", idDone: true|false } + * + * Updates an existing todo. + * + * @param json full json representation of the todo to update + * @return + */ + @RequestMapping(method = RequestMethod.PUT, headers = "Accept=application/json") + public ResponseEntity updateFromJson(@RequestBody String json) { + HttpHeaders headers= new HttpHeaders(); + headers.add("Content-Type", "application/text"); + if (todos.save(Todo.fromJsonToTodo(json)) == null) { + return new ResponseEntity(headers, HttpStatus.NOT_FOUND); + } + return new ResponseEntity(headers, HttpStatus.OK); + } + + /** + * DELETE /todos/{id} + * + * Deletes an existing todo. + * + * @param id + * @return + */ + @RequestMapping(value = "/{id}", method = RequestMethod.DELETE, headers = "Accept=application/json") + public ResponseEntity deleteFromJson(@PathVariable("id") Long id) { + Todo todo = todos.findOne(id); + HttpHeaders headers= new HttpHeaders(); + headers.add("Content-Type", "application/text"); + if (todo == null) { + return new ResponseEntity(headers, HttpStatus.NOT_FOUND); + } + todos.delete(todo); + return new ResponseEntity(headers, HttpStatus.OK); + } + + String encodeUrlPathSegment(String pathSegment, HttpServletRequest httpServletRequest) { + String enc = httpServletRequest.getCharacterEncoding(); + if (enc == null) { + enc = WebUtils.DEFAULT_CHARACTER_ENCODING; + } + try { + pathSegment = UriUtils.encodePathSegment(pathSegment, enc); + } + catch (UnsupportedEncodingException uee) {} + return pathSegment; + } + +} diff --git a/spring-data-neo4j-examples/todos/src/main/java/org/neo4j/app/todos/TodoRepository.java b/spring-data-neo4j-examples/todos/src/main/java/org/neo4j/app/todos/TodoRepository.java new file mode 100644 index 000000000..be2bf1228 --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/java/org/neo4j/app/todos/TodoRepository.java @@ -0,0 +1,7 @@ +package org.neo4j.app.todos; + +import org.springframework.data.neo4j.repository.GraphRepository; + +public interface TodoRepository extends GraphRepository { + +} diff --git a/spring-data-neo4j-examples/todos/src/main/resources/META-INF/spring/applicationContext-graph.xml b/spring-data-neo4j-examples/todos/src/main/resources/META-INF/spring/applicationContext-graph.xml new file mode 100644 index 000000000..c6c1e230f --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/resources/META-INF/spring/applicationContext-graph.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/todos/src/main/resources/META-INF/spring/applicationContext.xml b/spring-data-neo4j-examples/todos/src/main/resources/META-INF/spring/applicationContext.xml new file mode 100644 index 000000000..4ad95b926 --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/resources/META-INF/spring/applicationContext.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + diff --git a/spring-data-neo4j-examples/todos/src/main/resources/log4j.properties b/spring-data-neo4j-examples/todos/src/main/resources/log4j.properties new file mode 100644 index 000000000..5014b358b --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/resources/log4j.properties @@ -0,0 +1,17 @@ +log4j.rootLogger=error, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Print the date in ISO 8601 format +log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n + +log4j.appender.R=org.apache.log4j.RollingFileAppender +log4j.appender.R.File=application.log + +log4j.appender.R.MaxFileSize=100KB +# Keep one backup file +log4j.appender.R.MaxBackupIndex=1 + +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/404.html b/spring-data-neo4j-examples/todos/src/main/webapp/404.html new file mode 100755 index 000000000..a24448f41 --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/404.html @@ -0,0 +1,47 @@ + + + + + + + + + + Your Page Title Here :) + + + + + + + + + + + + + + + + + + + + + + +
+

Sorry. Couldn't Find That Page!

+
+ + + + \ No newline at end of file diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/classes/alt.properties b/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/classes/alt.properties new file mode 100644 index 000000000..48df87ff7 --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/classes/alt.properties @@ -0,0 +1 @@ +styleSheet=resources/styles/alt.css diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/classes/standard.properties b/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/classes/standard.properties new file mode 100644 index 000000000..d8dc0164d --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/classes/standard.properties @@ -0,0 +1 @@ +styleSheet=resources/styles/standard.css diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/spring/webmvc-config.xml b/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/spring/webmvc-config.xml new file mode 100644 index 000000000..18d9cf3b1 --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/spring/webmvc-config.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/web.xml b/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..25ccf72ae --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,88 @@ + + + + + sdn-todos + + Neo4j SDN Todo Application + + + + + defaultHtmlEscape + true + + + + contextConfigLocation + classpath*:META-INF/spring/applicationContext*.xml + + + + CharacterEncodingFilter + org.springframework.web.filter.CharacterEncodingFilter + + encoding + UTF-8 + + + forceEncoding + true + + + + + + + HttpMethodFilter + org.springframework.web.filter.HiddenHttpMethodFilter + + + CharacterEncodingFilter + /* + + + + HttpMethodFilter + /* + + + + + org.springframework.web.context.ContextLoaderListener + + + + + dispatcher + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + /WEB-INF/spring/webmvc-config.xml + + 1 + + + + dispatcher + /api/* + + + + 10 + + + + index.jsp + + + + java.lang.Exception + /uncaughtException + + + + 404 + /resourceNotFound + + diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/images/apple-touch-icon-114x114.png b/spring-data-neo4j-examples/todos/src/main/webapp/images/apple-touch-icon-114x114.png new file mode 100755 index 000000000..1c956e0b8 Binary files /dev/null and b/spring-data-neo4j-examples/todos/src/main/webapp/images/apple-touch-icon-114x114.png differ diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/images/apple-touch-icon-72x72.png b/spring-data-neo4j-examples/todos/src/main/webapp/images/apple-touch-icon-72x72.png new file mode 100755 index 000000000..45469aa17 Binary files /dev/null and b/spring-data-neo4j-examples/todos/src/main/webapp/images/apple-touch-icon-72x72.png differ diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/images/apple-touch-icon.png b/spring-data-neo4j-examples/todos/src/main/webapp/images/apple-touch-icon.png new file mode 100755 index 000000000..a3e9bcbc9 Binary files /dev/null and b/spring-data-neo4j-examples/todos/src/main/webapp/images/apple-touch-icon.png differ diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/images/favicon.ico b/spring-data-neo4j-examples/todos/src/main/webapp/images/favicon.ico new file mode 100644 index 000000000..12fab2490 Binary files /dev/null and b/spring-data-neo4j-examples/todos/src/main/webapp/images/favicon.ico differ diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/images/icon_neo4j.png b/spring-data-neo4j-examples/todos/src/main/webapp/images/icon_neo4j.png new file mode 100644 index 000000000..d41005e7b Binary files /dev/null and b/spring-data-neo4j-examples/todos/src/main/webapp/images/icon_neo4j.png differ diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/images/icon_sdn.png b/spring-data-neo4j-examples/todos/src/main/webapp/images/icon_sdn.png new file mode 100644 index 000000000..fc5290869 Binary files /dev/null and b/spring-data-neo4j-examples/todos/src/main/webapp/images/icon_sdn.png differ diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/index.jsp b/spring-data-neo4j-examples/todos/src/main/webapp/index.jsp new file mode 100644 index 000000000..042033731 --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/index.jsp @@ -0,0 +1,107 @@ + + + + + + + + + + SDN Todos + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+

Spring Data Neo4j: Todos

+
heroku-deploy
+
+
+
+ + + +
+ + +
+
Todos (a simply jquery pull from the json endpoint):
+ +
+
+ +
+
+ + +
+
+ +
+
+ +
+
+ +
+ + + + + + + + + + diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/javascripts/sdn-todos.js b/spring-data-neo4j-examples/todos/src/main/webapp/javascripts/sdn-todos.js new file mode 100755 index 000000000..f693369bb --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/javascripts/sdn-todos.js @@ -0,0 +1,25 @@ +$(document).ready(function() { + + $.ajaxSetup ({ + cache: false + }); + + var jsonUrl = "api/todos"; + + $.getJSON( + jsonUrl, + function(json) { + var items = []; + + $.each(json, function(i, todo) { + items.push('
  • ' + todo.title + '
  • '); + }); + + $('
      ', { + 'class': 'disc', + html: items.join('') + }).appendTo('div#todos'); + } + ); + +}); \ No newline at end of file diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/javascripts/tabs.js b/spring-data-neo4j-examples/todos/src/main/webapp/javascripts/tabs.js new file mode 100755 index 000000000..8a74b100d --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/javascripts/tabs.js @@ -0,0 +1,42 @@ +/* +* Skeleton V1.1 +* Copyright 2011, Dave Gamache +* www.getskeleton.com +* Free to use under the MIT license. +* http://www.opensource.org/licenses/mit-license.php +* 8/17/2011 +*/ + + +$(document).ready(function() { + + /* Tabs Activiation + ================================================== */ + + var tabs = $('ul.tabs'); + + tabs.each(function(i) { + + //Get all tabs + var tab = $(this).find('> li > a'); + tab.click(function(e) { + + //Get Location of tab's content + var contentLocation = $(this).attr('href'); + + //Let go if not a hashed one + if(contentLocation.charAt(0)=="#") { + + e.preventDefault(); + + //Make Tab Active + tab.removeClass('active'); + $(this).addClass('active'); + + //Show Tab Content & add active class + $(contentLocation).show().addClass('active').siblings().hide().removeClass('active'); + + } + }); + }); +}); \ No newline at end of file diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/log4j.properties b/spring-data-neo4j-examples/todos/src/main/webapp/log4j.properties new file mode 100644 index 000000000..5014b358b --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/log4j.properties @@ -0,0 +1,17 @@ +log4j.rootLogger=error, stdout + +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout + +# Print the date in ISO 8601 format +log4j.appender.stdout.layout.ConversionPattern=%d [%t] %-5p %c - %m%n + +log4j.appender.R=org.apache.log4j.RollingFileAppender +log4j.appender.R.File=application.log + +log4j.appender.R.MaxFileSize=100KB +# Keep one backup file +log4j.appender.R.MaxBackupIndex=1 + +log4j.appender.R.layout=org.apache.log4j.PatternLayout +log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/robots.txt b/spring-data-neo4j-examples/todos/src/main/webapp/robots.txt new file mode 100755 index 000000000..d310d070b --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/robots.txt @@ -0,0 +1,5 @@ +# www.robotstxt.org/ +# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 + +User-agent: * + diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/stylesheets/base.css b/spring-data-neo4j-examples/todos/src/main/webapp/stylesheets/base.css new file mode 100755 index 000000000..4533d8903 --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/stylesheets/base.css @@ -0,0 +1,338 @@ +/* +* Skeleton V1.1 +* Copyright 2011, Dave Gamache +* www.getskeleton.com +* Free to use under the MIT license. +* http://www.opensource.org/licenses/mit-license.php +* 8/17/2011 +*/ + + +/* Table of Content +================================================== + #Reset & Basics + #Basic Styles + #Site Styles + #Typography + #Links + #Lists + #Images + #Buttons + #Tabs + #Forms + #Misc */ + + +/* #Reset & Basics (Inspired by E. Meyers) +================================================== */ + html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; } + article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { + display: block; } + body { + line-height: 1; } + ol, ul { + list-style: none; } + blockquote, q { + quotes: none; } + blockquote:before, blockquote:after, + q:before, q:after { + content: ''; + content: none; } + table { + border-collapse: collapse; + border-spacing: 0; } + + +/* #Basic Styles +================================================== */ + body { + background: #fff; + font: 14px/21px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #444; + -webkit-font-smoothing: antialiased; /* Fix for webkit rendering */ + -webkit-text-size-adjust: 100%; + } + + +/* #Typography +================================================== */ + h1, h2, h3, h4, h5, h6 { + color: #181818; + font-family: "Georgia", "Times New Roman", Helvetica, Arial, sans-serif; + font-weight: normal; } + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { font-weight: inherit; } + h1 { font-size: 46px; line-height: 50px; margin-bottom: 14px;} + h2 { font-size: 35px; line-height: 40px; margin-bottom: 10px; } + h3 { font-size: 28px; line-height: 34px; margin-bottom: 8px; } + h4 { font-size: 21px; line-height: 30px; margin-bottom: 4px; } + h5 { font-size: 17px; line-height: 24px; } + h6 { font-size: 14px; line-height: 21px; } + .subheader { color: #777; } + + p { margin: 0 0 20px 0; } + p img { margin: 0; } + p.lead { font-size: 21px; line-height: 27px; color: #777; } + + em { font-style: italic; } + strong { font-weight: bold; color: #333; } + small { font-size: 80%; } + +/* Blockquotes */ + blockquote, blockquote p { font-size: 17px; line-height: 24px; color: #777; font-style: italic; } + blockquote { margin: 0 0 20px; padding: 9px 20px 0 19px; border-left: 1px solid #ddd; } + blockquote cite { display: block; font-size: 12px; color: #555; } + blockquote cite:before { content: "\2014 \0020"; } + blockquote cite a, blockquote cite a:visited, blockquote cite a:visited { color: #555; } + + hr { border: solid #ddd; border-width: 1px 0 0; clear: both; margin: 10px 0 30px; height: 0; } + + +/* #Links +================================================== */ + a, a:visited { color: #333; text-decoration: underline; outline: 0; } + a:hover, a:focus { color: #000; } + p a, p a:visited { line-height: inherit; } + + +/* #Lists +================================================== */ + ul, ol { margin-bottom: 20px; } + ul { list-style: none outside; } + ol { list-style: decimal; } + ol, ul.square, ul.circle, ul.disc { margin-left: 30px; } + ul.square { list-style: square outside; } + ul.circle { list-style: circle outside; } + ul.disc { list-style: disc outside; } + ul ul, ul ol, + ol ol, ol ul { margin: 4px 0 5px 30px; font-size: 90%; } + ul ul li, ul ol li, + ol ol li, ol ul li { margin-bottom: 6px; } + li { line-height: 18px; margin-bottom: 12px; } + ul.large li { line-height: 21px; } + li p { line-height: 21px; } + +/* #Images +================================================== */ + + img.scale-with-grid { + max-width: 100%; + height: auto; } + + +/* #Buttons +================================================== */ + + a.button, + button, + input[type="submit"], + input[type="reset"], + input[type="button"] { + background: #eee; /* Old browsers */ + background: #eee -moz-linear-gradient(top, rgba(255,255,255,.2) 0%, rgba(0,0,0,.2) 100%); /* FF3.6+ */ + background: #eee -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.2)), color-stop(100%,rgba(0,0,0,.2))); /* Chrome,Safari4+ */ + background: #eee -webkit-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Chrome10+,Safari5.1+ */ + background: #eee -o-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* Opera11.10+ */ + background: #eee -ms-linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* IE10+ */ + background: #eee linear-gradient(top, rgba(255,255,255,.2) 0%,rgba(0,0,0,.2) 100%); /* W3C */ + border: 1px solid #aaa; + border-top: 1px solid #ccc; + border-left: 1px solid #ccc; + padding: 4px 12px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + color: #444; + display: inline-block; + font-size: 11px; + font-weight: bold; + text-decoration: none; + text-shadow: 0 1px rgba(255, 255, 255, .75); + cursor: pointer; + margin-bottom: 20px; + line-height: 21px; + font-family: "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; } + + a.button:hover, + button:hover, + input[type="submit"]:hover, + input[type="reset"]:hover, + input[type="button"]:hover { + color: #222; + background: #ddd; /* Old browsers */ + background: #ddd -moz-linear-gradient(top, rgba(255,255,255,.3) 0%, rgba(0,0,0,.3) 100%); /* FF3.6+ */ + background: #ddd -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.3)), color-stop(100%,rgba(0,0,0,.3))); /* Chrome,Safari4+ */ + background: #ddd -webkit-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Chrome10+,Safari5.1+ */ + background: #ddd -o-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* Opera11.10+ */ + background: #ddd -ms-linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* IE10+ */ + background: #ddd linear-gradient(top, rgba(255,255,255,.3) 0%,rgba(0,0,0,.3) 100%); /* W3C */ + border: 1px solid #888; + border-top: 1px solid #aaa; + border-left: 1px solid #aaa; } + + a.button:active, + button:active, + input[type="submit"]:active, + input[type="reset"]:active, + input[type="button"]:active { + border: 1px solid #666; + background: #ccc; /* Old browsers */ + background: #ccc -moz-linear-gradient(top, rgba(255,255,255,.35) 0%, rgba(10,10,10,.4) 100%); /* FF3.6+ */ + background: #ccc -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(255,255,255,.35)), color-stop(100%,rgba(10,10,10,.4))); /* Chrome,Safari4+ */ + background: #ccc -webkit-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Chrome10+,Safari5.1+ */ + background: #ccc -o-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* Opera11.10+ */ + background: #ccc -ms-linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* IE10+ */ + background: #ccc linear-gradient(top, rgba(255,255,255,.35) 0%,rgba(10,10,10,.4) 100%); /* W3C */ } + + .button.full-width, + button.full-width, + input[type="submit"].full-width, + input[type="reset"].full-width, + input[type="button"].full-width { + width: 100%; + padding-left: 0 !important; + padding-right: 0 !important; + text-align: center; } + + +/* #Tabs (activate in tabs.js) +================================================== */ + ul.tabs { + display: block; + margin: 0 0 20px 0; + padding: 0; + border-bottom: solid 1px #ddd; } + ul.tabs li { + display: block; + width: auto; + height: 30px; + padding: 0; + float: left; + margin-bottom: 0; } + ul.tabs li a { + display: block; + text-decoration: none; + width: auto; + height: 29px; + padding: 0px 20px; + line-height: 30px; + border: solid 1px #ddd; + border-width: 1px 1px 0 0; + margin: 0; + background: #f5f5f5; + font-size: 13px; } + ul.tabs li a.active { + background: #fff; + height: 30px; + position: relative; + top: -4px; + padding-top: 4px; + border-left-width: 1px; + margin: 0 0 0 -1px; + color: #111; + -moz-border-radius-topleft: 2px; + -webkit-border-top-left-radius: 2px; + border-top-left-radius: 2px; + -moz-border-radius-topright: 2px; + -webkit-border-top-right-radius: 2px; + border-top-right-radius: 2px; } + ul.tabs li:first-child a.active { + margin-left: 0; } + ul.tabs li:first-child a { + border-width: 1px 1px 0 1px; + -moz-border-radius-topleft: 2px; + -webkit-border-top-left-radius: 2px; + border-top-left-radius: 2px; } + ul.tabs li:last-child a { + -moz-border-radius-topright: 2px; + -webkit-border-top-right-radius: 2px; + border-top-right-radius: 2px; } + + ul.tabs-content { margin: 0; display: block; } + ul.tabs-content > li { display:none; } + ul.tabs-content > li.active { display: block; } + + /* Clearfixing tabs for beautiful stacking */ + ul.tabs:before, + ul.tabs:after { + content: '\0020'; + display: block; + overflow: hidden; + visibility: hidden; + width: 0; + height: 0; } + ul.tabs:after { + clear: both; } + ul.tabs { + zoom: 1; } + + +/* #Forms +================================================== */ + + form { + margin-bottom: 20px; } + fieldset { + margin-bottom: 20px; } + input[type="text"], + input[type="password"], + input[type="email"], + textarea, + select { + border: 1px solid #ccc; + padding: 6px 4px; + outline: none; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + border-radius: 2px; + font: 13px "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif; + color: #777; + margin: 0; + width: 210px; + max-width: 100%; + display: block; + margin-bottom: 20px; + background: #fff; } + select { + padding: 0; } + input[type="text"]:focus, + input[type="password"]:focus, + input[type="email"]:focus, + textarea:focus { + border: 1px solid #aaa; + color: #444; + -moz-box-shadow: 0 0 3px rgba(0,0,0,.2); + -webkit-box-shadow: 0 0 3px rgba(0,0,0,.2); + box-shadow: 0 0 3px rgba(0,0,0,.2); } + textarea { + min-height: 60px; } + label, + legend { + display: block; + font-weight: bold; + font-size: 13px; } + select { + width: 220px; } + input[type="checkbox"] { + display: inline; } + label span, + legend span { + font-weight: normal; + font-size: 13px; + color: #444; } + +/* #Misc +================================================== */ + .remove-bottom { margin-bottom: 0 !important; } + .half-bottom { margin-bottom: 10px !important; } + .add-bottom { margin-bottom: 20px !important; } + + +/* #SDN styling +================================================== */ + #footer { background: #eee; } \ No newline at end of file diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/stylesheets/layout.css b/spring-data-neo4j-examples/todos/src/main/webapp/stylesheets/layout.css new file mode 100755 index 000000000..aff5b477e --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/stylesheets/layout.css @@ -0,0 +1,58 @@ +/* +* Skeleton V1.1 +* Copyright 2011, Dave Gamache +* www.getskeleton.com +* Free to use under the MIT license. +* http://www.opensource.org/licenses/mit-license.php +* 8/17/2011 +*/ + +/* Table of Content +================================================== + #Site Styles + #Page Styles + #Media Queries + #Font-Face */ + +/* #Site Styles +================================================== */ + +/* #Page Styles +================================================== */ + +/* #Media Queries +================================================== */ + + /* Smaller than standard 960 (devices and browsers) */ + @media only screen and (max-width: 959px) {} + + /* Tablet Portrait size to standard 960 (devices and browsers) */ + @media only screen and (min-width: 768px) and (max-width: 959px) {} + + /* All Mobile Sizes (devices and browser) */ + @media only screen and (max-width: 767px) {} + + /* Mobile Landscape Size to Tablet Portrait (devices and browsers) */ + @media only screen and (min-width: 480px) and (max-width: 767px) {} + + /* Mobile Portrait Size to Mobile Landscape Size (devices and browsers) */ + @media only screen and (max-width: 479px) {} + + +/* #Font-Face +================================================== */ +/* This is the proper syntax for an @font-face file + Just create a "fonts" folder at the root, + copy your FontName into code below and remove + comment brackets */ + +/* @font-face { + font-family: 'FontName'; + src: url('../fonts/FontName.eot'); + src: url('../fonts/FontName.eot?iefix') format('eot'), + url('../fonts/FontName.woff') format('woff'), + url('../fonts/FontName.ttf') format('truetype'), + url('../fonts/FontName.svg#webfontZam02nTh') format('svg'); + font-weight: normal; + font-style: normal; } +*/ \ No newline at end of file diff --git a/spring-data-neo4j-examples/todos/src/main/webapp/stylesheets/skeleton.css b/spring-data-neo4j-examples/todos/src/main/webapp/stylesheets/skeleton.css new file mode 100755 index 000000000..d0264a40b --- /dev/null +++ b/spring-data-neo4j-examples/todos/src/main/webapp/stylesheets/skeleton.css @@ -0,0 +1,236 @@ +/* +* Skeleton V1.1 +* Copyright 2011, Dave Gamache +* www.getskeleton.com +* Free to use under the MIT license. +* http://www.opensource.org/licenses/mit-license.php +* 8/17/2011 +*/ + + +/* Table of Contents +================================================== + #Base 960 Grid + #Tablet (Portrait) + #Mobile (Portrait) + #Mobile (Landscape) + #Clearing */ + + + +/* #Base 960 Grid +================================================== */ + + .container { position: relative; width: 960px; margin: 0 auto; padding: 0; } + .column, .columns { float: left; display: inline; margin-left: 10px; margin-right: 10px; } + .row { margin-bottom: 20px; } + + /* Nested Column Classes */ + .column.alpha, .columns.alpha { margin-left: 0; } + .column.omega, .columns.omega { margin-right: 0; } + + /* Base Grid */ + .container .one.column { width: 40px; } + .container .two.columns { width: 100px; } + .container .three.columns { width: 160px; } + .container .four.columns { width: 220px; } + .container .five.columns { width: 280px; } + .container .six.columns { width: 340px; } + .container .seven.columns { width: 400px; } + .container .eight.columns { width: 460px; } + .container .nine.columns { width: 520px; } + .container .ten.columns { width: 580px; } + .container .eleven.columns { width: 640px; } + .container .twelve.columns { width: 700px; } + .container .thirteen.columns { width: 760px; } + .container .fourteen.columns { width: 820px; } + .container .fifteen.columns { width: 880px; } + .container .sixteen.columns { width: 940px; } + + .container .one-third.column { width: 300px; } + .container .two-thirds.column { width: 620px; } + + /* Offsets */ + .container .offset-by-one { padding-left: 60px; } + .container .offset-by-two { padding-left: 120px; } + .container .offset-by-three { padding-left: 180px; } + .container .offset-by-four { padding-left: 240px; } + .container .offset-by-five { padding-left: 300px; } + .container .offset-by-six { padding-left: 360px; } + .container .offset-by-seven { padding-left: 420px; } + .container .offset-by-eight { padding-left: 480px; } + .container .offset-by-nine { padding-left: 540px; } + .container .offset-by-ten { padding-left: 600px; } + .container .offset-by-eleven { padding-left: 660px; } + .container .offset-by-twelve { padding-left: 720px; } + .container .offset-by-thirteen { padding-left: 780px; } + .container .offset-by-fourteen { padding-left: 840px; } + .container .offset-by-fifteen { padding-left: 900px; } + + + +/* #Tablet (Portrait) +================================================== */ + + /* Note: Design for a width of 768px */ + + @media only screen and (min-width: 768px) and (max-width: 959px) { + .container { width: 768px; } + .container .column, + .container .columns { margin-left: 10px; margin-right: 10px; } + .column.alpha, .columns.alpha { margin-left: 0; margin-right: 10px; } + .column.omega, .columns.omega { margin-right: 0; margin-left: 10px; } + + .container .one.column { width: 28px; } + .container .two.columns { width: 76px; } + .container .three.columns { width: 124px; } + .container .four.columns { width: 172px; } + .container .five.columns { width: 220px; } + .container .six.columns { width: 268px; } + .container .seven.columns { width: 316px; } + .container .eight.columns { width: 364px; } + .container .nine.columns { width: 412px; } + .container .ten.columns { width: 460px; } + .container .eleven.columns { width: 508px; } + .container .twelve.columns { width: 556px; } + .container .thirteen.columns { width: 604px; } + .container .fourteen.columns { width: 652px; } + .container .fifteen.columns { width: 700px; } + .container .sixteen.columns { width: 748px; } + + .container .one-third.column { width: 236px; } + .container .two-thirds.column { width: 492px; } + + /* Offsets */ + .container .offset-by-one { padding-left: 48px; } + .container .offset-by-two { padding-left: 96px; } + .container .offset-by-three { padding-left: 144px; } + .container .offset-by-four { padding-left: 192px; } + .container .offset-by-five { padding-left: 240px; } + .container .offset-by-six { padding-left: 288px; } + .container .offset-by-seven { padding-left: 336px; } + .container .offset-by-eight { padding-left: 348px; } + .container .offset-by-nine { padding-left: 432px; } + .container .offset-by-ten { padding-left: 480px; } + .container .offset-by-eleven { padding-left: 528px; } + .container .offset-by-twelve { padding-left: 576px; } + .container .offset-by-thirteen { padding-left: 624px; } + .container .offset-by-fourteen { padding-left: 672px; } + .container .offset-by-fifteen { padding-left: 720px; } + } + + +/* #Mobile (Portrait) +================================================== */ + + /* Note: Design for a width of 320px */ + + @media only screen and (max-width: 767px) { + .container { width: 300px; } + .columns, .column { margin: 0; } + + .container .one.column, + .container .two.columns, + .container .three.columns, + .container .four.columns, + .container .five.columns, + .container .six.columns, + .container .seven.columns, + .container .eight.columns, + .container .nine.columns, + .container .ten.columns, + .container .eleven.columns, + .container .twelve.columns, + .container .thirteen.columns, + .container .fourteen.columns, + .container .fifteen.columns, + .container .sixteen.columns, + .container .one-third.column, + .container .two-thirds.column { width: 300px; } + + /* Offsets */ + .container .offset-by-one, + .container .offset-by-two, + .container .offset-by-three, + .container .offset-by-four, + .container .offset-by-five, + .container .offset-by-six, + .container .offset-by-seven, + .container .offset-by-eight, + .container .offset-by-nine, + .container .offset-by-ten, + .container .offset-by-eleven, + .container .offset-by-twelve, + .container .offset-by-thirteen, + .container .offset-by-fourteen, + .container .offset-by-fifteen { padding-left: 0; } + + } + + +/* #Mobile (Landscape) +================================================== */ + + /* Note: Design for a width of 480px */ + + @media only screen and (min-width: 480px) and (max-width: 767px) { + .container { width: 420px; } + .columns, .column { margin: 0; } + + .container .one.column, + .container .two.columns, + .container .three.columns, + .container .four.columns, + .container .five.columns, + .container .six.columns, + .container .seven.columns, + .container .eight.columns, + .container .nine.columns, + .container .ten.columns, + .container .eleven.columns, + .container .twelve.columns, + .container .thirteen.columns, + .container .fourteen.columns, + .container .fifteen.columns, + .container .sixteen.columns, + .container .one-third.column, + .container .two-thirds.column { width: 420px; } + } + + +/* #Clearing +================================================== */ + + /* Self Clearing Goodness */ + .container:after { content: "\0020"; display: block; height: 0; clear: both; visibility: hidden; } + + /* Use clearfix class on parent to clear nested columns, + or wrap each row of columns in a
      */ + .clearfix:before, + .clearfix:after, + .row:before, + .row:after { + content: '\0020'; + display: block; + overflow: hidden; + visibility: hidden; + width: 0; + height: 0; } + .row:after, + .clearfix:after { + clear: both; } + .row, + .clearfix { + zoom: 1; } + + /* You can also use a
      to clear columns */ + .clear { + clear: both; + display: block; + overflow: hidden; + visibility: hidden; + width: 0; + height: 0; + } + +