├── .gitignore ├── screenshot.png ├── app ├── images │ ├── jl.png │ ├── david.png │ └── mathilde.png ├── _data │ ├── tags.json │ └── developers.json ├── controller.coffee ├── style.less └── index.html ├── README.md ├── .editorconfig ├── src ├── test │ └── protractor │ │ └── e2e.coffee └── main │ └── java │ └── com │ └── acme │ └── Server.java ├── protractor.conf.js ├── package.json ├── TODO.md ├── deroule.md ├── pom.xml └── workbook.md /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .idea/ 3 | *.iml 4 | node_modules 5 | -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeStory/devoxx-quickstart/master/screenshot.png -------------------------------------------------------------------------------- /app/images/jl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeStory/devoxx-quickstart/master/app/images/jl.png -------------------------------------------------------------------------------- /app/images/david.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeStory/devoxx-quickstart/master/app/images/david.png -------------------------------------------------------------------------------- /app/images/mathilde.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeStory/devoxx-quickstart/master/app/images/mathilde.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Run 2 | 3 | ``` 4 | mvn compile exec:java 5 | ``` 6 | 7 | # Build to deploy 8 | 9 | ``` 10 | mvn clean package dependency:copy-dependencies 11 | ``` -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | indent_style = space 7 | indent_size = 2 8 | charset = utf-8 9 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /app/_data/tags.json: -------------------------------------------------------------------------------- 1 | { 2 | "front": ["CoffeeScript", "Javascript", "Jsp", "Web"], 3 | "back": ["Java", "Jee", "Node", "Spring"], 4 | "database": ["Hibernate"], 5 | "test": ["Test"], 6 | "hipster": ["CoffeeScript", "Javascript", "Node"] 7 | } 8 | -------------------------------------------------------------------------------- /src/test/protractor/e2e.coffee: -------------------------------------------------------------------------------- 1 | describe 'E2E: Acceptance Testing', -> 2 | beforeEach -> 3 | browser.get '/' 4 | 5 | it 'should have a working welcome page', -> 6 | expect($('h1').getText()).toEqual 'Hello World!' 7 | expect(element.all(By.css('li')).count()).toBe 2 8 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | require('coffee-script').register(); 2 | 3 | exports.config = { 4 | 5 | seleniumAddress: "http://localhost:4444/wd/hub", 6 | 7 | specs: [ 8 | 'src/test/protractor/e2e.coffee' 9 | ], 10 | 11 | baseUrl: 'http://localhost:8080', 12 | 13 | onPrepare: function () { 14 | global.By = global.by; 15 | } 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "devoxx-quickstart", 3 | "version": "1.0.0", 4 | "description": "Node dependencies for devoxx-quickstart tests", 5 | "main": "protractor.conf.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/CodeStory/devoxx-quickstart.git" 12 | }, 13 | "author": "Jean-Laurent de Morlhon && David Gageot", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/CodeStory/devoxx-quickstart/issues" 17 | }, 18 | "homepage": "https://github.com/CodeStory/devoxx-quickstart", 19 | "devDependencies": { 20 | "protractor": "^0.20.1", 21 | "coffee-script": "^1.7.1", 22 | "grunt-cli": "^0.1.13", 23 | "grunt": "^0.4.4", 24 | "grunt-protractor-runner": "^0.2.4", 25 | "grunt-contrib-watch": "^0.6.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/controller.coffee: -------------------------------------------------------------------------------- 1 | devoxx = angular.module 'devoxx', ['ngAnimate'] 2 | 3 | .controller 'BasketController', class 4 | constructor: (@$http)-> 5 | @emails = JSON.parse(localStorage['emails'] || '[]') 6 | @basket = {} 7 | @refresh() 8 | 9 | add: (email) -> 10 | @emails.push email unless email in @emails 11 | @refresh() 12 | 13 | remove: (email) -> 14 | @emails = (mail for mail in @emails when mail isnt email) 15 | @refresh() 16 | 17 | refresh: -> 18 | localStorage['emails'] = JSON.stringify(@emails) 19 | @$http.get("/basket?emails=#{@emails}").success (data) => 20 | @basket = data 21 | 22 | range: (count) -> 23 | [0...count] 24 | 25 | maxRange: -> 26 | [1..5] 27 | 28 | starColor: (count) -> 29 | if count < 0 then 'red' else 'green' 30 | 31 | showRemove: (email) -> 32 | email in @emails 33 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # DGA 2 | 3 | + [ ] Extraire 10+ profils de Hopwork 4 | + [ ] Test Unitaire 5 | + [ ] Projet vide 6 | + [ ] Repo Maven 7 | + [ ] bouquins Java EE (Antonio) (dedicace) 8 | + [ ] Categories de mots clefs 9 | + [ ] Css 10 | + [ ] bout en bout - exercices 11 | + [ ] Clefs USB 12 | + [ ] Restassured 13 | 14 | 15 | # JLO 16 | 17 | + [ ] Slides 18 | + [ ] Slide handlebar (if, for, ...) 19 | + [ ] Test Karma 20 | + [ ] Test E2E 21 | + [ ] Clefs USB 22 | + [ ] Annonce formation! Date et pitch 23 | + [ ] bout en bout - exercices 24 | 25 | 26 | # Fluent-http: 27 | 28 | + [ ] LogFilterRequest uri + params 29 | + [ ] http://localhost:8080/basket?emails=david@gageot.net&emails=mathilde@lemee.net 30 | + [ ] live reload directement dans fluent-http : https://github.com/davidB/livereload-jvm 31 | + [ ] Barbarywatch 32 | 33 | 34 | # Divers 35 | 36 | + [ ] Fongo / Mongo 37 | + [ ] Projet à télécharger 38 | + [ ] Setup windows et linux 39 | + [ ] Goodies 40 | + [ ] Imprimer le déroulé 41 | + [ ] Transition de server-side templating vers client side templating pour le filtre sur les tags de la homepage 42 | 43 | # 0/ Install 44 | # 1/ Liste des développeurs (Atelier) (server side) 45 | # 2/ Mise en panier (Atelier) (angular) 46 | # 3/ 4 Tests (UT, IT, VIEW, E2E) (Atelier) 47 | -------------------------------------------------------------------------------- /app/_data/developers.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "email": "david@gageot.net", 4 | "prenom": "David", 5 | "job": "Développeur Java/Web", 6 | "ville": "Paris, France", 7 | "description1": "Bonjour, je suis développeur indépendant. Ma passion ? L'écriture de logiciels pointus mais simples. J'ai pour leitmotiv d'être un facilitateur qui, par ma créativité et mon expertise, aide les équipes à être plus innovantes et plus efficaces.", 8 | "description2": "Je participe à des projets depuis 1998, comme responsable R&D chez l'éditeur Adesoft puis, comme expert Java et Scrum chez Valtech, CTO chez Algodeal, un fond d'investissement quantitatif puis développeur chez SonarSource, la société derrière Sonar.", 9 | "tags": ["Java", "Web", "Javascript", "Agile"], 10 | "photo": "david", 11 | "price": 1000 12 | }, 13 | { 14 | "email": "mathilde@lemee.net", 15 | "prenom": "Mathilde", 16 | "job": "Ingénieur Mobile / Java", 17 | "ville": "Paris, France", 18 | "description1": "Freelance depuis plus de 3 ans, j'interviens sur des projets en tant que développeur / lead technique / scrum master.", 19 | "description2": "Je propose également des formations sur les tests (unitaire, intégration, systeme ...) et leurs mises en place dans un contexte d'intégration continue.", 20 | "tags": ["Java", "Jee", "Spring", "Hibernate", "Jsp"], 21 | "photo": "mathilde", 22 | "price": 700 23 | }, 24 | { 25 | "email": "jeanlaurent@morlhon.net", 26 | "prenom": "Jean-Laurent", 27 | "job": "Blogger du dimanche", 28 | "ville": "Houilles, France", 29 | "description1": "Freelance depuis plus de 1 an.", 30 | "description2": "", 31 | "tags": ["Java", "Test", "CoffeeScript", "Node", "Javascript"], 32 | "photo": "jl", 33 | "price": 1000 34 | } 35 | ] 36 | -------------------------------------------------------------------------------- /src/main/java/com/acme/Server.java: -------------------------------------------------------------------------------- 1 | package com.acme; 2 | 3 | import static java.util.stream.Stream.*; 4 | import static net.codestory.http.convert.TypeConvert.*; 5 | 6 | import java.util.*; 7 | import java.util.stream.*; 8 | 9 | import net.codestory.http.*; 10 | import net.codestory.http.templating.*; 11 | 12 | public class Server { 13 | public static void main(String[] args) { 14 | new WebServer(routes -> routes 15 | .get("/basket?emails=:emails", (context, emails) -> { 16 | Basket basket = new Basket(); 17 | 18 | Stream.of(emails.split(",")).map(Server::findDeveloper).filter(dev -> dev != null).forEach(developer -> { 19 | String[] tags = developer.tags; 20 | basket.front += count("front", tags); 21 | basket.back += count("back", tags); 22 | basket.database += count("database", tags); 23 | basket.test += count("test", tags); 24 | basket.hipster += count("hipster", tags); 25 | basket.sum += developer.price; 26 | }); 27 | 28 | return basket; 29 | }) 30 | ).start(); 31 | } 32 | 33 | static Developer findDeveloper(String email) { 34 | Developer[] developers = convertValue(Site.get().getData().get("developers"), Developer[].class); 35 | 36 | return of(developers).filter(developer -> developer.email.equals(email)).findFirst().orElse(null); 37 | } 38 | 39 | private static long count(String domain, String[] tags) { 40 | Map> tagsPerDomain = (Map>) Site.get().getData().get("tags"); 41 | return of(tags).filter((t) -> tagsPerDomain.get(domain).contains(t)).count(); 42 | } 43 | 44 | static class Developer { 45 | String email; 46 | String[] tags; 47 | long price; 48 | } 49 | 50 | static class Basket { 51 | long front; 52 | long back; 53 | long database; 54 | long test; 55 | long hipster; 56 | long sum; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/style.less: -------------------------------------------------------------------------------- 1 | [ng-cloak], .ng-cloack { 2 | display: none !important; 3 | } 4 | 5 | .profil { 6 | background-color: lighten(lightgrey, 10%); 7 | border-radius: 20px; 8 | padding: 5px 20px 20px 20px; 9 | } 10 | 11 | .text-center { 12 | img { 13 | margin: 0 auto; 14 | } 15 | } 16 | 17 | body { 18 | padding-top: 210px; 19 | } 20 | 21 | .navbar { 22 | height: 190px; 23 | 24 | .navbar-brand { 25 | font-size: 3em; 26 | margin-top: 1.5em; 27 | } 28 | } 29 | 30 | #basket { 31 | padding: 10px; 32 | margin-right: 20px; 33 | width: 250px; 34 | 35 | hr { 36 | margin: 6px 0; 37 | } 38 | 39 | li { 40 | color: #EDEDED; 41 | list-style: none; 42 | height: 22px; 43 | line-height: 22px; 44 | font-size: 18px; 45 | vertical-align: middle; 46 | font-weight: bold; 47 | position: relative; 48 | 49 | .box { 50 | position: absolute; 51 | width: 16px; 52 | height: 16px; 53 | top: 3px; 54 | } 55 | 56 | .box-1 { 57 | left: 90px; 58 | } 59 | 60 | .box-2 { 61 | left: 110px; 62 | } 63 | 64 | .box-3 { 65 | left: 130px; 66 | } 67 | 68 | .box-4 { 69 | left: 150px; 70 | } 71 | 72 | .box-5 { 73 | left: 170px; 74 | } 75 | } 76 | 77 | .front { 78 | background-color: gold; 79 | } 80 | 81 | .back { 82 | background-color: plum; 83 | } 84 | 85 | .database { 86 | background-color: lightsalmon; 87 | } 88 | 89 | .test { 90 | background-color: cornflowerblue; 91 | } 92 | 93 | .hipster { 94 | background-color: yellowgreen; 95 | } 96 | } 97 | 98 | .box.ng-hide-add, .box.ng-hide-remove { 99 | -webkit-transition: all linear 0.5s; 100 | -moz-transition: all linear 0.5s; 101 | transition: all linear 0.5s; 102 | display: block !important; 103 | } 104 | 105 | .box.ng-hide { 106 | opacity: 0; 107 | } 108 | -------------------------------------------------------------------------------- /deroule.md: -------------------------------------------------------------------------------- 1 | # Code Story Lab Devoxx 2014 2 | 3 | - 1h15 4 | * Intro 5 | * Requirements techniques 6 | * Se mettre par binome 7 | * INSTALL PARTY !! 8 | * (Java8, .m2 repo, node ?, Mongo) 9 | * Explication du sujet ( jesuisunrecruteur.io -> faire des petits slides ? ) 10 | * démo de l'objectif (on montre ce à quoi on veut aboutir) 11 | * LiveCoding -> bootstrap codestory http 12 | * Ouvrir un projet intellij jdk8 + plugin vide 13 | * chopper un pom via livetemplate (ou déjà pret) 14 | * ajouter la dep fluent-http 15 | * faire le main -> montrer la 404 16 | * ajouter un index.html dans /app -> montrer la page 17 | * on fait un hello world avec le hello world dans _data 18 | * Se mettre à l'aise avec CodeStory http 19 | ( A partir d'ici on fait les démos avec des données bidons, eux appliquent cela ensuite sur le sujet du lab) 20 | * Démarrer le serveur 21 | * Servir une page statique par défaut 22 | * Modifier la page statique en ajoutant un bout de texte dedans 23 | * Copier de la data dedans 24 | * Ajoute un style dans la balise yaml ( fournir au gens le fichier de data en json) 25 | * Ajouter webjar de bootstrap (démo bower) 26 | * Ajouter le style dans la page 27 | * petit tricks avec googlemaps 28 | * Dupliquer le dev 29 | * Extraire en YAML 30 | * déplacer le YAML dans data 31 | * convertir en JSON via yaml to json 32 | 33 | * 2nd Atelier: Panier 34 | * Je ng-click sur un acheter 35 | * je stocke en local-storage la liste des id des gus que j'ai acheté 36 | * Je fais un appel serveur pour me renvoyer le json du resultat du calcul de mon panier (compétences etc...) 37 | 38 | 39 | * 3rd Atelier: Testings 40 | * Unit Testing de la resource 41 | * test rest-assured de la resource 42 | * Test unit de controlleur 43 | * Test e2e du panier 44 | 45 | 46 | 47 | 48 | * Rendre une page dynamique coté serveur 49 | * Faire le controleur de developers 50 | * Faire un get json rest classique 51 | * Faire un post rest 52 | * Faire un client angular 53 | * Jouer avec plusieurs parametres + query string... 54 | - Pause 55 | - 1h15 56 | * Test Rest (restassured) 57 | * Angular ?? 58 | * Test controller 59 | * Test UI ? 60 | * Plug la base 61 | * Test fango 62 | * Java 8 (service + fun / avancé -> Grosse data ;)) 63 | * Mocco ?? 64 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | net.code-story 6 | devoxx 7 | 1.0-SNAPSHOT 8 | 9 | 10 | 3 11 | 12 | 13 | 14 | 1.8 15 | 1.8 16 | UTF-8 17 | com.acme.Server 18 | 19 | 20 | 21 | 22 | net.code-story 23 | http 24 | 1.38 25 | 26 | 27 | org.webjars 28 | bootstrap 29 | 3.1.1 30 | 31 | 32 | org.webjars 33 | angularjs 34 | 1.2.14 35 | 36 | 37 | junit 38 | junit 39 | 4.11 40 | test 41 | 42 | 43 | 44 | 45 | web 46 | 47 | 48 | 49 | 50 | maven-resources-plugin 51 | 2.6 52 | 53 | 54 | maven-clean-plugin 55 | 2.5 56 | 57 | 58 | maven-compiler-plugin 59 | 3.1 60 | 61 | 62 | maven-surefire-plugin 63 | 2.16 64 | 65 | 66 | maven-install-plugin 67 | 2.5.1 68 | 69 | 70 | maven-jar-plugin 71 | 2.4 72 | 73 | 74 | maven-deploy-plugin 75 | 2.8.1 76 | 77 | 78 | maven-site-plugin 79 | 3.3 80 | 81 | 82 | 83 | 84 | 85 | 86 | maven-jar-plugin 87 | 88 | 89 | 90 | ${main.class} 91 | true 92 | dependency/ 93 | 94 | 95 | 96 | 97 | 98 | maven-dependency-plugin 99 | 100 | 101 | copy-dependencies 102 | package 103 | 104 | copy-dependencies 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: Chasseur de dev.io 4 | styles: [/webjars/bootstrap/3.1.1/css/bootstrap.css, style.less] 5 | ng-app: devoxx 6 | --- 7 | 8 |
9 | 63 | 64 |
65 | [[#each site.data.developers]] 66 |
67 |
68 |
69 |
70 |
71 |

[[prenom]]

72 | 73 |
74 |

[[job]]

75 | 76 |

[[ville]]

77 | 78 |

[[description1]]

79 | 80 |

[[description2]]

81 | 82 | [[#each tags]] 83 | [[.]] 84 | [[/each]] 85 |
86 |
87 | 88 |
89 |
90 | 91 | 92 |

[[price]]€ / jour

93 | Chasser ! 95 | Virer ! 97 |
98 |
99 |
100 |
101 | [[/each]] 102 |
103 |
104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /workbook.md: -------------------------------------------------------------------------------- 1 | # Application Web Moderne en Java 2 | ## The CodeStory Way 3 | by David Gageot & Jean-Laurent de Morlhon 4 | 5 | Devoxx Hand's on Labs 6 | 7 | Louis Armstrong CD 8 | 9 | 13:30 - 16:30 10 | 11 | ## Abstract 12 | Venez participer à un Hand's On Lab de 3 heures. L'objectif est simple : apprendre à développer une application web moderne en Java. Rapidement, de manière pragmatique et en toute confiance. 13 | 14 | Avec l'assistance et les démos live de David Gageot et Jean-Laurent de Morlhon. 15 | 16 | Au menu : du Java 8, un poil d'Angular, un soupçon de CoffeeScript, du MongoDB, du pair-programming, des tests IHM, des hotkeys de malade, des plugins de fou et un cycle de développement ultra rapide. Oui vous ne rêvez pas on parle bien de Java. 17 | 18 | Lundi, au boulot, vous ne verrez plus votre projet java de la même manière. 19 | 20 | 21 | # Install party 22 | 23 | Pour faire cet atelier, tu as besoin : 24 | * d'un portable avec de la batterie pour durer 3h de coding 25 | * d'un binome 26 | * de logiciels : 27 | * Java 8 28 | * maven 3.1 29 | * node.js 0.10+ 30 | * un repo maven "chauffé" 31 | * d'un IDE 32 | * de quelques "assets" de données et graphiques 33 | 34 | Tu trouveras tout ça dans une clé USB que nous te distribuons au début de la session. 35 | 36 | # Recruteur.io 37 | 38 | Votre ami Jean-Claude de SupDeCo Aurillac a une idée de business de malade, Mark Zuckerberg en tremble encore : il s'agit de faire un site pour trouver des grouillots modernes (programmeurs) pour se faire une tonne de $$$ en les plaçant dans des structures qui font des projets web. 39 | 40 | Le truc c'est que visiblement les programmeurs ils ont des talents differents et que pour faire une bonne équipe, il faut mixer ces talents. 41 | Entre recherche de mots clé (ex: cherche stagiaire, 7 ans d'experience en j2ee, vba et golo est un plus) ce que tous les sites font, il faut plutot être sur qu'ils soient bons dans un certains nombre de caracteristiques utiles aux projets d'aujourd'hui. 42 | 43 | En 2013, il nous faut donc 4 talents et essayer de maximiser cela : `Front`, `Back`, `Database`, `Test` et pour faire chouette et parce que c'est plus vendeur `Hipster`. 44 | Donc le site doit optimiser le prix (le nerf de la guerre d'aprés Jean-Claude, et il sait de quoi il parle: il a une bm) mais aussi ces 4 caractéristiques. 45 | 46 | Ca pourrait ressembler à ça : 47 | 48 | ![Screenshot](./screenshot.png) 49 | 50 | Martine de la compta, a déjà acheté le nom de domaine, y'a plus qu'a. 51 | On t'a installé Frontpage et IIS, let's go ! T'as 2h. 52 | 53 | # Let's write some code 54 | 55 | ## Démarrer le serveur 56 | 57 | 1. Creer toi un repertoire tout neuf, dans lequel tu poserais un pom qui pourrait ressembler à ça dedans : 58 | 59 | ```xml 60 | 62 | 4.0.0 63 | 64 | net.devoxx 65 | chasseurdedevio 66 | 1.0-SNAPSHOT 67 | 68 | 69 | 1.8 70 | 1.8 71 | UTF-8 72 | 73 | 74 | 75 | 76 | net.code-story 77 | http 78 | 1.42 79 | 80 | 81 | junit 82 | junit 83 | 4.11 84 | test 85 | 86 | 87 | 88 | 89 | ``` 90 | 91 | 1. Ensuite tu te cree comme un grand les repertoires de sources et de tests qui vont bien. 92 | (tu peux aussi utiliser ta souris, mais ca fait moins hype) 93 | 94 | ```bash 95 | mkdir -p src/{main,test}/java 96 | ``` 97 | 1. On est là pour faire du web. Alors allons y pour un helloworld classique ( c'est bien le classique aussi parfois). 98 | Tu peux creer un fichier `index.md` à la racine d'une répertoire `app` a coté de ton `pom.xml` 99 | 100 | ```bash 101 | mkdir app 102 | touch index.md 103 | ``` 104 | 105 | Ensuite tu édites `index.md`(md c'est pour markdown mais tu le sais déjà, sauf qu'on commence avec un peu de YAML au début, ça s'appelle du YAML Front Matter) et tu colles dedans ça par exemple: 106 | 107 | ```Markdown 108 | title:hello devoxx 109 | --- 110 | # Hello Devoxx 111 | 112 | Je sers une page web avec un projet java en moins de 2 minutes... si si c'est possible 113 | ``` 114 | Dans fluent-http, tous ce qui est dans le repertoire app est servi par défaut à la racine de ton serveur. 115 | Si tu y mets du html il sera servi tel quel, comme pour le js, les images etc.. 116 | Si tu mets du less, il sera compilé en css, du coffee en js, du markdown en html, etc... 117 | 118 | 1. Bon on code du java ou pas ? : 119 | 120 | Dans src/main/java qqpart tu creés une classe `Server` par exemple comme celle là: 121 | 122 | ```java 123 | package com.acme; 124 | 125 | import net.codestory.http.*; 126 | 127 | public class Server { 128 | 129 | public static void main(String[] args) { 130 | new WebServer().start(); 131 | } 132 | } 133 | ``` 134 | 1. Execute la classe Server et pointe ton navigateur sur http://localhost:8080 135 | Normalement, là, tu as moins envie d'utiliser weblo et tomcat, lundi au boulot. 136 | 137 | 138 | ## Des moustaches coté serveur avec Handlebars 139 | Le repertoire `_data` à la racine de ton projet (a coté de ton `pom.xml` donc), peut contenir des fichiers json ou yaml 140 | qui sont directement accessible serverside. 141 | 142 | 1. Creer un fichier `hello.json` dans `_data` 143 | qui pourrait contenir les choses suivantes : 144 | ```json 145 | {"greetings":"Hello World"} 146 | ``` 147 | Tu peux ajouter dans une page html le code suivant: 148 | ```html 149 |

Exemple de fichier de données

150 | [[greetings]] 151 | ``` 152 | sans redémarer ton serveur, le fichier sera servi et le processing sera fait coté serveur. 153 | 154 | Le langage de template ici est du handlebars (http://handlebarsjs.com/) tu peux donc utiliser toutes les commandes handlebars comme par exemple: 155 | 156 | ### Boucle 157 | Avec une liste de personne comme cela : 158 | ```json 159 | { 160 | "people": [ 161 | {"firstName": "Yehuda", "lastName": "Katz", "author":true}, 162 | {"firstName": "Carl", "lastName": "Lerche","author":false}, 163 | {"firstName": "Alan", "lastName": "Johnson","author":true} 164 | ] 165 | } 166 | ``` 167 | tu peux les afficher avec une boucle comme ceci: 168 | ``` 169 | [[#each people]] 170 | [[firstName]] [[lastName]] 171 | [[/each]] 172 | ``` 173 | 174 | ### condition 175 | 176 | ```html 177 |
178 | [[#if author]] 179 |

[[firstName]] [[lastName]]

180 | [[/if]] 181 |
182 | ``` 183 | 184 | Il ya d'autres éléments (mais guère plus, que tu peux voir dans http://handlebarsjs.com/) 185 | 186 | ### Ajouter bootstrap 187 | 188 | Pour ajouter bootstrap tu peux utiliser les webjars 189 | 190 | tu ajoutes à ton pom 191 | 192 | ```xml 193 | 194 | org.webjars 195 | bootstrap 196 | 3.1.1 197 | 198 | ``` 199 | Tu peux acceder en utilisant le chemin `/webjars/bootstrap/3.1.1/css/bootstrap.css` dans une balise styles. 200 | Si tu utilise le YAML Front Matter tu peux carrement le rajouter dans celui ci : 201 | ```YAML 202 | --- 203 | title: Chasseur de dev.io 204 | styles: /webjars/bootstrap/3.1.1/css/bootstrap.css 205 | --- 206 | ``` 207 | Tu peux agir de la même manière avec toutes tes dépendances front. 208 | 209 | Sinon y'a bower c'est plus hype mais tu dois déplacer les fichiers à la main. 210 | 211 | # Server Side Stuff don't suck 212 | 213 | fluent-http expose en json vos beans par défaut. 214 | Par exemple pour retourner une persone qui pourrait être défini comme suis : 215 | ```Java 216 | public class Person { 217 | public String name; 218 | public int age 219 | 220 | public Person(String name, int age) { 221 | this.name = name; 222 | this.age = age; 223 | } 224 | } 225 | ``` 226 | 227 | Vous pouvez facilement ajouter une resource à votre serveur http comme suis : 228 | ```Java 229 | public class PersonResource { 230 | 231 | @Get("/douglas") 232 | public Person getPerson() { 233 | return new Person("Scott Adams",42); 234 | } 235 | } 236 | ``` 237 | Vous le brancher dans vos routes : 238 | ```Java 239 | package com.acme; 240 | 241 | import net.codestory.http.*; 242 | 243 | public class Server { 244 | 245 | public static void main(String[] args) { 246 | new WebServer(routes -> routes.add(PersonResource.class).start(); 247 | } 248 | } 249 | ``` 250 | Et en appellant http://localhost:8080/douglas vous obtenez : 251 | ```json 252 | { 253 | "name":"Scott Adams", 254 | "age":42 255 | } 256 | ``` 257 | # How I'm sure it works ? 258 | 259 | ## Tester unitairement ses resources avec JUnit 260 | 261 | ## Tester en intégration ses resources avec RestAssured 262 | 263 | ## Tester unitairement ses controlleurs Angular avec Karma 264 | 265 | ## Tester toute son application avec Protractor 266 | 267 | # You want more ? 268 | --------------------------------------------------------------------------------