Better front-end development in Atlassian plugins

  • 2,893 views
Uploaded on

Traditionally the UI of Atlassian plugins have been based on a typical old-school MVC frameworks (webwork, Struts) with little dynamic behaviour. But no more! JIRA Team Lead Wociech Seliga will show …

Traditionally the UI of Atlassian plugins have been based on a typical old-school MVC frameworks (webwork, Struts) with little dynamic behaviour. But no more! JIRA Team Lead Wociech Seliga will show you have to develop sexier and more user-friendly plugins based on a modern stack using AUI, Soy templates, Backbone.js and friends.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,893
On Slideshare
0
From Embeds
0
Number of Embeds
2

Actions

Shares
Downloads
17
Comments
0
Likes
2

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Tuesday, April 3, 2012
  • 2. Better front-end development in Atlassian plugins The road from back-end to front-end programming Wojciech Seliga JIRA Development Team Lead, Atlassian Co-founder, Spartez 2Tuesday, April 3, 2012
  • 3. About me • 4+ years with Atlassian • 6+ years doing Atlassian plugin development: • JIRA Importers Plugin • JIRA Drag & Drop Attachments Plugin • JIRA Mail Plugin • ScreenSnipe for JIRA, ScreenSnipe for Confluence ... • Veteran of old-school web development (Java) 3Tuesday, April 3, 2012
  • 4. A bit of history 4Tuesday, April 3, 2012
  • 5. A bit of history • 2002 - 2006 - Awesome UI, Web 1.0 4Tuesday, April 3, 2012
  • 6. A bit of history • 2002 - 2006 - Awesome UI, Web 1.0 WebWork, XWork, JSP, Velocity, Freemarker 4Tuesday, April 3, 2012
  • 7. A bit of history • 2002 - 2006 - Awesome UI, Web 1.0 WebWork, XWork, JSP, Velocity, Freemarker • 2006 - 2009 - Features, features, features! 4Tuesday, April 3, 2012
  • 8. A bit of history • 2002 - 2006 - Awesome UI, Web 1.0 WebWork, XWork, JSP, Velocity, Freemarker • 2006 - 2009 - Features, features, features! Mostly back-end technologies 4Tuesday, April 3, 2012
  • 9. A bit of history • 2002 - 2006 - Awesome UI, Web 1.0 WebWork, XWork, JSP, Velocity, Freemarker • 2006 - 2009 - Features, features, features! Mostly back-end technologies • 2009 - now - new Atlassian UI, Web 2.0+ 4Tuesday, April 3, 2012
  • 10. Evolution Step 1 - AUI • Confluence 3.0+, JIRA 3.13.5+ • Forms, Controls, Tabs, Inline Dialogs, ..., AJS 5Tuesday, April 3, 2012
  • 11. Evolution Step 1 - AUI • Confluence 3.0+, JIRA 3.13.5+ • Forms, Controls, Tabs, Inline Dialogs, ..., AJS 5Tuesday, April 3, 2012
  • 12. Evolution Step 1 - AUI • Confluence 3.0+, JIRA 3.13.5+ • Forms, Controls, Tabs, Inline Dialogs, ..., AJS 5Tuesday, April 3, 2012
  • 13. Evolution Step 1 - AUI • Confluence 3.0+, JIRA 3.13.5+ • Forms, Controls, Tabs, Inline Dialogs, ..., AJS 5Tuesday, April 3, 2012
  • 14. Evolution Step 2 - REST • Plugin Framework v2 only (JIRA 4+, Confluence 3.1+) • Easier AJAX for plugin developers unleashed <rest key="helloWorldRest" path="/helloworld" version="1.0"> <description>Hello world sample.</description> </rest> • World of Java annotations (Jersey) 6Tuesday, April 3, 2012
  • 15. @Path ("priority") @AnonymousAllowed @Consumes ({ MediaType.APPLICATION_JSON }) @Produces ({ MediaType.APPLICATION_JSON }) public class PriorityResource { // injected dependencies and the constructor here ... @GET @Path ("{id}") public Response getPriority(@PathParam ("id") final String id){ final Priority priority = constManager.getPriorityObject(id); if (priority == null) { throw new NotFoundWebException(ErrorCollection.of( i18n.getText("rest.priority.error.not.found", id))); } return Response.ok(PriorityJsonBean.fullBean(priority, baseUrls)) .cacheControl(never()).build(); } } 7Tuesday, April 3, 2012
  • 16. injectable JS & CSS + REST = WIN 8Tuesday, April 3, 2012
  • 17. Evolution Step 3 (2010) web resource contexts • Confluence 2.10+, JIRA 4.2+ • Easy resource injection to popular destinations • Easy to define own contexts <web-resource key="quick-edit-issue"> <context>jira.view.issue</context> <context>jira.navigator.advanced</context> <context>jira.navigator.simple</context> <!-- ... --> </web-resource> 9Tuesday, April 3, 2012
  • 18. Evolution Step 4 (2010) web-resource-transformer <web-resource-transformer key="my-key" class="fqcn.must.implement.WebResourceTransformer"/> 10Tuesday, April 3, 2012
  • 19. Evolution Step 4 (2010) web-resource-transformer <web-resource-transformer key="my-key" class="fqcn.must.implement.WebResourceTransformer"/> public interface WebResourceTransformer { DownloadableResource transform(Element configElement, ResourceLocation location, String filePath, DownloadableResource nextResource); } 10Tuesday, April 3, 2012
  • 20. web-resource-transformers 11Tuesday, April 3, 2012
  • 21. web-resource-transformers • I18n 11Tuesday, April 3, 2012
  • 22. web-resource-transformers • I18n • L&F 11Tuesday, April 3, 2012
  • 23. web-resource-transformers • I18n • L&F • context path 11Tuesday, April 3, 2012
  • 24. web-resource-transformers • I18n • L&F • context path • SASS, LESS 11Tuesday, April 3, 2012
  • 25. web-resource-transformers • I18n • L&F • context path • SASS, LESS • Soy 11Tuesday, April 3, 2012
  • 26. I18N 12Tuesday, April 3, 2012
  • 27. I18N i18n resource file defined in atlassian-plugin.xml hello.world=Hello World from.atlascamp=from AtlasCamp {0} 12Tuesday, April 3, 2012
  • 28. I18N - web resource transformation definition 13Tuesday, April 3, 2012
  • 29. I18N - web resource transformation definition <resource name="ourname" type="i18n" location="path/to/i18n/properties/file/no/ext"/> <web-resource key="our-key"> <dependency>com.atlassian.auiplugin:ajs</dependency> <transformation extension="js"> <transformer key="jsI18n"/> </transformation> <resource type="download" name="filename.js" location="path/to/filename.js"/> </web-resource> 13Tuesday, April 3, 2012
  • 30. I18N transformation 14Tuesday, April 3, 2012
  • 31. I18N transformation var helloText = AJS.I18n.getText("hello.world") + " " + AJS.I18n.getText("from.atlascamp", 2012) 14Tuesday, April 3, 2012
  • 32. I18N transformation var helloText = AJS.I18n.getText("hello.world") + " " + AJS.I18n.getText("from.atlascamp", 2012) 14Tuesday, April 3, 2012
  • 33. I18N transformation var helloText = AJS.I18n.getText("hello.world") + " " + AJS.I18n.getText("from.atlascamp", 2012) var helloText = "Hello World" + " " + AJS.format("from AtlasCamp {0}", 2012) 14Tuesday, April 3, 2012
  • 34. Times of Hacking 15Tuesday, April 3, 2012
  • 35. Times of Hacking Javascript hacks freestyle AJAX JQuery Javascript hacks JQuery JQuery JQuery JQuery JQuery JQuery JQuery Javascript hacks JQuery JQuery JQuery JQuery JQuery JQuery underscore.js Javascript hacks JQuery JQuery JQuery JQuery JQuery JQuery JQuery JQuery Prototype JQuery JQuery JQuery JQuery JQuery JQuery JQuery Javascript hacks JQuery Javascript hacks underscore.js JQuery JQuery JQuery JQuery freestyle AJAX JQuery JQuery JQuery JQuery underscore.js 15Tuesday, April 3, 2012 JQu
  • 36. “ Its all too easy to create JavaScript applications that end up as tangled piles of jQuery selectors and callbacks, all trying frantically to keep data in sync between the HTML UI, your JavaScript logic, and the database on your server. For rich client-side applications, a more structured approach is often ” helpful.. Introduction to Backbone.js 16Tuesday, April 3, 2012
  • 37. Evolution Step 5 (2011) Structure on the client side 17Tuesday, April 3, 2012
  • 38. Evolution Step 5 (2011) Structure on the client side For speed, beauty and maintainability 17Tuesday, April 3, 2012
  • 39. Evolution Step 5 (2011) Structure on the client side For speed, beauty and maintainability FTW 17Tuesday, April 3, 2012
  • 40. More structured approach in JS • Backbone.js • Ember.js • SproutCore • Angular.js • Sammy.js • Batman.js • Spine.js • Mustache • Cappucino • Handlebars • Javascript MVC • Soy (Google Closure Templates) 18Tuesday, April 3, 2012
  • 41. More structured approach in JS • Backbone.js • Soy (Google Closure Templates) 19Tuesday, April 3, 2012
  • 42. More structured approach in JS • Backbone.js • Soy (Google Closure Templates) MV C 19Tuesday, April 3, 2012
  • 43. More structured approach in JS M Backbone.js • • Soy (Google Closure Templates) VC 19Tuesday, April 3, 2012
  • 44. More structured approach in JS M Backbone.js • V • Soy (Google Closure Templates) C 19Tuesday, April 3, 2012
  • 45. More structured approach in JS M Backbone.js C • V • Soy (Google Closure Templates) 19Tuesday, April 3, 2012
  • 46. More structured approach in JS • Backbone.js • Soy (Google Closure Templates) 19Tuesday, April 3, 2012
  • 47. More structured approach in JS • Soy (Google Closure Templates) 19Tuesday, April 3, 2012
  • 48. More structured approach in JS 19Tuesday, April 3, 2012
  • 49. Our Road to Soy 20Tuesday, April 3, 2012
  • 50. Our Road to Soy • AJS.template 20Tuesday, April 3, 2012
  • 51. Our Road to Soy • AJS.template • Mustache 20Tuesday, April 3, 2012
  • 52. Our Road to Soy • AJS.template • Mustache • Soy 20Tuesday, April 3, 2012
  • 53. Soy Features 21Tuesday, April 3, 2012
  • 54. Soy Features • Simplicity 21Tuesday, April 3, 2012
  • 55. Soy Features • Simplicity • Logic and display separation 21Tuesday, April 3, 2012
  • 56. Soy Features • Simplicity • Logic and display separation • Client and server side (Javascript and Java) 21Tuesday, April 3, 2012
  • 57. Soy Features • Simplicity • Logic and display separation • Client and server side (Javascript and Java) • Client-side speed 21Tuesday, April 3, 2012
  • 58. Soy Features • Simplicity • Logic and display separation • Client and server side (Javascript and Java) • Client-side speed • Security (auto-escaping) 21Tuesday, April 3, 2012
  • 59. Soy Features • Simplicity • Logic and display separation • Client and server side (Javascript and Java) • Client-side speed • Security (auto-escaping) • Battle-tested by Google 21Tuesday, April 3, 2012
  • 60. Soy - Example {namespace examples.simple} /**  * Greets a person using "Hello" by default.  * @param name The name of the person.  * @param? greetingWord Optional greeting word to use instead of "Hello".  */ {template .helloName} {if not $greetingWord} Hello {$name}! {else} {$greetingWord} {$name}! {/if} {/template} 22Tuesday, April 3, 2012
  • 61. Soy Syntax - Types Type Examples null null Boolean false, true Integer 123, -857, 0x123 Float 0.5, 123.0, 10.1e4 String Atlassian, , foo-bar List [], [1, two, 3, [4, five]] Map [:], [key: value, key2: value2] 23Tuesday, April 3, 2012
  • 62. Soy Syntax - Operators • - (unary) not • * / % • + - (binary) • < > <= >= • == != • and • or • ?: (ternary) 24Tuesday, April 3, 2012
  • 63. Soy - Commands 25Tuesday, April 3, 2012
  • 64. Soy - Commands • {template}{/template} 25Tuesday, April 3, 2012
  • 65. Soy - Commands • {template}{/template} • {literal}{/literal} 25Tuesday, April 3, 2012
  • 66. Soy - Commands • {template}{/template} • {literal}{/literal} • {print <expression>} 25Tuesday, April 3, 2012
  • 67. Soy - Commands • {template}{/template} • {literal}{/literal} • {print <expression>} • {<expression>} 25Tuesday, April 3, 2012
  • 68. Soy - Commands • {template}{/template} • {literal}{/literal} • {print <expression>} • {<expression>} • {if <expression>}, {elseif}, {else}, {/if} 25Tuesday, April 3, 2012
  • 69. Soy - Commands • {template}{/template} • {foreach}, {ifempty}, {/foreach} • {literal}{/literal} • {print <expression>} • {<expression>} • {if <expression>}, {elseif}, {else}, {/if} 25Tuesday, April 3, 2012
  • 70. Soy - Commands • {template}{/template} • {foreach}, {ifempty}, {/foreach} • {literal}{/literal} • {for}, {/for} • {print <expression>} • {<expression>} • {if <expression>}, {elseif}, {else}, {/if} 25Tuesday, April 3, 2012
  • 71. Soy - Commands • {template}{/template} • {foreach}, {ifempty}, {/foreach} • {literal}{/literal} • {for}, {/for} • {print <expression>} • {call}, {/call}, {param}, {/param} • {<expression>} • {if <expression>}, {elseif}, {else}, {/if} 25Tuesday, April 3, 2012
  • 72. Soy - Commands • {template}{/template} • {foreach}, {ifempty}, {/foreach} • {literal}{/literal} • {for}, {/for} • {print <expression>} • {call}, {/call}, {param}, {/param} • {<expression>} • {sp}, {n}, {lb}, {rb} • {if <expression>}, {elseif}, {else}, {/if} 25Tuesday, April 3, 2012
  • 73. Soy - defining variables 26Tuesday, April 3, 2012
  • 74. Soy - defining variables 26Tuesday, April 3, 2012
  • 75. Soy - defining variables Not Supported! Keep business logic away from view! 26Tuesday, April 3, 2012
  • 76. Useful functions • {getText(i18n-key, ....) • {contextPath} • {$data|truncate:30} 27Tuesday, April 3, 2012
  • 77. Soy Javascript Compilation {namespace JIRA.Templates.Demo} /** * Simplest Hello world demo * @param name */ {template .helloWorld} <div>Hello World, {$name}</div> {/template} 28Tuesday, April 3, 2012
  • 78. 28Tuesday, April 3, 2012
  • 79. 29Tuesday, April 3, 2012
  • 80. // This file was automatically generated from demo.soy. // Please dont edit this file by hand. if (typeof JIRA == undefined) { var JIRA = {}; } if (typeof JIRA.Templates == undefined) { JIRA.Templates = {}; } if (typeof JIRA.Templates.Demo == undefined) { JIRA.Templates.Demo = {}; } JIRA.Templates.Demo.helloWorld = function(opt_data, opt_sb) { var output = opt_sb || new soy.StringBuilder(); output.append(<div>Hello World, , soy.$$escapeHtml(opt_data.name), </div>); return opt_sb ? : output.toString(); }; 29Tuesday, April 3, 2012
  • 81. // This file was automatically generated from demo.soy. // Please dont edit this file by hand. if (typeof JIRA == undefined) { var JIRA = {}; } if (typeof JIRA.Templates == undefined) { JIRA.Templates = {}; } if (typeof JIRA.Templates.Demo == undefined) { JIRA.Templates.Demo = {}; } JIRA.Templates.Demo.helloWorld = function(opt_data, opt_sb) { var output = opt_sb || new soy.StringBuilder(); output.append(<div>Hello World, , soy.$$escapeHtml(opt_data.name), </div>); return opt_sb ? : output.toString(); }; 29Tuesday, April 3, 2012
  • 82. Auto-escaping • implicit by default to HTML escaping • {namespace com.example autoescape="XXX"} XXX may be true, false, contextual • disable for a single case with {$templateData|noAutoescape} • sanitized data 30Tuesday, April 3, 2012
  • 83. Contextual Auto-escaping 31Tuesday, April 3, 2012
  • 84. Contextual Auto-escaping /** * @param name */ {template .helloWorld autoescape="contextual"} <a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a> {/template} 31Tuesday, April 3, 2012
  • 85. Contextual Auto-escaping /** * @param name */ {template .helloWorld autoescape="contextual"} <a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a> {/template} 31Tuesday, April 3, 2012
  • 86. Contextual Auto-escaping /** * @param name */ {template .helloWorld autoescape="contextual"} <a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a> {/template} {“name”: "><script>alert("x&xx")</script>"} 31Tuesday, April 3, 2012
  • 87. Contextual Auto-escaping /** * @param name */ {template .helloWorld autoescape="contextual"} <a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a> {/template} {“name”: "><script>alert("x&xx")</script>"} <a href="/Demo?name=%3E%3Cscript%3Ealert%28%22x%26xx%22%29%3C%2Fscript%3E" onclick="var x = x3ex3cscriptx3ealert(x22xx26xxx22)x3c/scriptx3e"> &gt;&lt;script&gt;alert(&quot;x&amp;xx&quot;)&lt;/script&gt;</a> 31Tuesday, April 3, 2012
  • 88. Contextual Auto-escaping /** * @param name */ {template .helloWorld autoescape="contextual"} <a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a> {/template} {“name”: "><script>alert("x&xx")</script>"} <a href="/Demo?name=%3E%3Cscript%3Ealert%28%22x%26xx%22%29%3C%2Fscript%3E" onclick="var x = x3ex3cscriptx3ealert(x22xx26xxx22)x3c/scriptx3e"> &gt;&lt;script&gt;alert(&quot;x&amp;xx&quot;)&lt;/script&gt;</a> 31Tuesday, April 3, 2012
  • 89. Contextual Auto-escaping /** * @param name */ {template .helloWorld autoescape="contextual"} <a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a> {/template} {“name”: "><script>alert("x&xx")</script>"} <a href="/Demo?name=%3E%3Cscript%3Ealert%28%22x%26xx%22%29%3C%2Fscript%3E" onclick="var x = x3ex3cscriptx3ealert(x22xx26xxx22)x3c/scriptx3e"> &gt;&lt;script&gt;alert(&quot;x&amp;xx&quot;)&lt;/script&gt;</a> 31Tuesday, April 3, 2012
  • 90. Contextual Auto-escaping /** * @param name */ {template .helloWorld autoescape="contextual"} <a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a> {/template} {“name”: "><script>alert("x&xx")</script>"} <a href="/Demo?name=%3E%3Cscript%3Ealert%28%22x%26xx%22%29%3C%2Fscript%3E" onclick="var x = x3ex3cscriptx3ealert(x22xx26xxx22)x3c/scriptx3e"> &gt;&lt;script&gt;alert(&quot;x&amp;xx&quot;)&lt;/script&gt;</a> 31Tuesday, April 3, 2012
  • 91. Contextual Auto-escaping /** * @param name */ {template .helloWorld autoescape="contextual"} <a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a> {/template} {“name”: "><script>alert("x&xx")</script>"} <a href="/Demo?name=%3E%3Cscript%3Ealert%28%22x%26xx%22%29%3C%2Fscript%3E" onclick="var x = x3ex3cscriptx3ealert(x22xx26xxx22)x3c/scriptx3e"> &gt;&lt;script&gt;alert(&quot;x&amp;xx&quot;)&lt;/script&gt;</a> 31Tuesday, April 3, 2012
  • 92. Soy @ Atlassian • JIRA (gadgets, new project administration, mails, ...) • GreenHopper • PAC • ... 32Tuesday, April 3, 2012
  • 93. Soy and Atlassian Plugins <web-resource key="my-key"> <transformation extension="soy"> <transformer key="soyTransformer"/> </transformation> <resource type="download" name="my-name.js" location="path/to/my/template.soy"/> </web-resource> 33Tuesday, April 3, 2012
  • 94. Server-side Soy • Atlassian Plugin Framework favours Velocity • SoyTemplateRenderer/SoyTemplateRendererProvider • DefaultVelocityContextProvider (jira-core) • SoyData, SoyDataList, SoyDataMap, SoyData.createFromExistingData() 34Tuesday, April 3, 2012
  • 95. Soy - Coding Example 35Tuesday, April 3, 2012
  • 96. Soy - Template Library • {call} in Soy • web-resource <dependency> 36Tuesday, April 3, 2012
  • 97. Backbone.js 37Tuesday, April 3, 2012
  • 98. Backbone.js • Event-driven • Models • Views (responsible for keeping markup in sync with model) 38Tuesday, April 3, 2012
  • 99. Our story with backbone.js 39Tuesday, April 3, 2012
  • 100. Our story with backbone.js • Version/Component/People management in JIRA (Ignite) - 2011 39Tuesday, April 3, 2012
  • 101. Our story with backbone.js • Version/Component/People management in JIRA (Ignite) - 2011 • JIRA Importers Plugin, JIRA Mail Plugin - 2011 39Tuesday, April 3, 2012
  • 102. Our story with backbone.js • Version/Component/People management in JIRA (Ignite) - 2011 • JIRA Importers Plugin, JIRA Mail Plugin - 2011 • RAB - 2011 39Tuesday, April 3, 2012
  • 103. Our story with backbone.js • Version/Component/People management in JIRA (Ignite) - 2011 • JIRA Importers Plugin, JIRA Mail Plugin - 2011 • RAB - 2011 • GH RapidBoard, New Issue Nav - 2011, 2012 39Tuesday, April 3, 2012
  • 104. Why Backbone 40Tuesday, April 3, 2012
  • 105. Why Backbone backbone.js 40Tuesday, April 3, 2012
  • 106. Why Backbone backbone.js JIRA is a backbone 40Tuesday, April 3, 2012
  • 107. Why Backbone JIRA is a backbone backbone.js 40Tuesday, April 3, 2012
  • 108. Why Backbone.js 41Tuesday, April 3, 2012
  • 109. Why Backbone.js • Small 41Tuesday, April 3, 2012
  • 110. Why Backbone.js • Small • Flexible 41Tuesday, April 3, 2012
  • 111. Why Backbone.js • Small • Flexible • Does not impose any templating technologies 41Tuesday, April 3, 2012
  • 112. Why Backbone.js • Small • Flexible • Does not impose any templating technologies • Well documented 41Tuesday, April 3, 2012
  • 113. Why Backbone.js • Small • Flexible • Does not impose any templating technologies • Well documented • Popular 41Tuesday, April 3, 2012
  • 114. Why Backbone.js • Small • Flexible • Does not impose any templating technologies • Well documented • Popular • Liked by us 41Tuesday, April 3, 2012
  • 115. 42Tuesday, April 3, 2012
  • 116. DOM / Markup 42Tuesday, April 3, 2012
  • 117. Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 118. Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 119. JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 120. JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 121. AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 122. AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 123. AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 124. AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 125. Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 126. Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 127. Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 128. Backbone.js Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 129. Backbone.js Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 130. Backbone.js Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 131. Backbone.js Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 132. Backbone.js Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 133. REST API Backbone.js Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 134. REST API Backbone.js Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 135. REST API Backbone.js Services Managers Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 136. REST API Backbone.js Services Managers Soy (client) AUI JQuery Javascript DOM / Markup 42Tuesday, April 3, 2012
  • 137. Possible Future • Easier, more powerful and efficient web resource transformations • Better support for Soy on the server side (like Velocity or FreeMarker) • (?) Dynamic injection of needed resources on-the-fly (inline dialogs) 43Tuesday, April 3, 2012
  • 138. Looking back... 44Tuesday, April 3, 2012
  • 139. Looking back... 2.5 years ago... 44Tuesday, April 3, 2012
  • 140. Looking back... 2.5 years ago... most of this stuff was not possible 44Tuesday, April 3, 2012
  • 141. “ Don’t underestimate the power of the client-side programming. Time to learn Javascript and related frameworks, you old Java fellow ” Master Joda, Javascript convert 45Tuesday, April 3, 2012
  • 142. TAKE-AWAYS “ Atlassian is moving fast to client-side programming. Technology is there. Are you ready? ” #atlascamp 46Tuesday, April 3, 2012
  • 143. Thank you!Tuesday, April 3, 2012