Better front-end developmentin Atlassian pluginsThe road from back-end to front-end programmingWojciech SeligaJIRA Develop...
About me• 4+ years with Atlassian• 6+ years doing Atlassian plugin development: • JIRA Importers Plugin • JIRA Drag & Drop...
A bit of history                   4
A bit of history• 2002 - 2006 - Awesome UI, Web 1.0                                      4
A bit of history• 2002 - 2006 - Awesome UI, Web 1.0    WebWork, XWork, JSP, Velocity, Freemarker                          ...
A bit of history• 2002 - 2006 - Awesome UI, Web 1.0     WebWork, XWork, JSP, Velocity, Freemarker• 2006 - 2009 - Features,...
A bit of history• 2002 - 2006 - Awesome UI, Web 1.0     WebWork, XWork, JSP, Velocity, Freemarker• 2006 - 2009 - Features,...
A bit of history• 2002 - 2006 - Awesome UI, Web 1.0     WebWork, XWork, JSP, Velocity, Freemarker• 2006 - 2009 - Features,...
Evolution Step 1 - AUI• Confluence 3.0+, JIRA 3.13.5+• Forms, Controls, Tabs, Inline Dialogs, ..., AJS                     ...
Evolution Step 1 - AUI• Confluence 3.0+, JIRA 3.13.5+• Forms, Controls, Tabs, Inline Dialogs, ..., AJS                     ...
Evolution Step 1 - AUI• Confluence 3.0+, JIRA 3.13.5+• Forms, Controls, Tabs, Inline Dialogs, ..., AJS                     ...
Evolution Step 1 - AUI• Confluence 3.0+, JIRA 3.13.5+• Forms, Controls, Tabs, Inline Dialogs, ..., AJS                     ...
Evolution Step 2 - REST • Plugin Framework v2 only (JIRA 4+, Confluence 3.1+) • Easier AJAX for plugin developers unleashed...
@Path ("priority")@AnonymousAllowed@Consumes ({ MediaType.APPLICATION_JSON })@Produces ({ MediaType.APPLICATION_JSON })pub...
injectable JS & CSS+ REST = WIN                      8
Evolution Step 3 (2010)web resource contexts• Confluence 2.10+, JIRA 4.2+• Easy resource injection to popular destinations•...
Evolution Step 4 (2010)web-resource-transformer<web-resource-transformer key="my-key"      class="fqcn.must.implement.WebR...
Evolution Step 4 (2010)web-resource-transformer<web-resource-transformer key="my-key"      class="fqcn.must.implement.WebR...
web-resource-transformers                            11
web-resource-transformers• I18n                            11
web-resource-transformers• I18n• L&F                            11
web-resource-transformers• I18n• L&F• context path                            11
web-resource-transformers• I18n• L&F• context path• SASS, LESS                            11
web-resource-transformers• I18n• L&F• context path• SASS, LESS• Soy                            11
I18N       12
I18N   i18n resource file defined in atlassian-plugin.xml          hello.world=Hello World          from.atlascamp=from At...
I18N - web resourcetransformation definition                           13
I18N - web resource transformation definition<resource name="ourname" type="i18n"      location="path/to/i18n/properties/fi...
I18N transformation                      14
I18N transformationvar helloText = AJS.I18n.getText("hello.world") + " "     + AJS.I18n.getText("from.atlascamp", 2012)   ...
I18N transformationvar helloText = AJS.I18n.getText("hello.world") + " "     + AJS.I18n.getText("from.atlascamp", 2012)   ...
I18N transformationvar helloText = AJS.I18n.getText("hello.world") + " "     + AJS.I18n.getText("from.atlascamp", 2012)   ...
Times of Hacking                   15
Times of Hacking  Javascript hacks                                                            freestyle AJAX              ...
“    Its all too easy to create JavaScript applications    that end up as tangled piles of jQuery selectors and    callbac...
Evolution Step 5 (2011)      Structure on the client side                                     17
Evolution Step 5 (2011)      Structure on the client side For speed, beauty and maintainability                           ...
Evolution Step 5 (2011)      Structure on the client side For speed, beauty and maintainability                 FTW       ...
More structured approach in JS• Backbone.js      • Ember.js• SproutCore       • Angular.js• Sammy.js         • Batman.js• ...
More structured approach in JS         • Backbone.js         • Soy (Google Closure Templates)                             ...
More structured approach in JS         • Backbone.js         • Soy (Google Closure Templates)                 MV C        ...
More structured approach in JS        M Backbone.js         •         • Soy (Google Closure Templates)                    ...
More structured approach in JS        M Backbone.js         •                 V         • Soy (Google Closure Templates)  ...
More structured approach in JS        M Backbone.js C         •                 V         • Soy (Google Closure Templates)...
More structured approach in JS         • Backbone.js         • Soy (Google Closure Templates)                             ...
More structured approach in JS         • Soy (Google Closure Templates)                                            19
More structured approach in JS                                 19
Our Road to Soy                  20
Our Road to Soy• AJS.template                  20
Our Road to Soy• AJS.template• Mustache                  20
Our Road to Soy• AJS.template• Mustache• Soy                  20
Soy Features               21
Soy Features• Simplicity               21
Soy Features• Simplicity• Logic and display separation                                 21
Soy Features• Simplicity• Logic and display separation• Client and server side (Javascript and Java)                      ...
Soy Features• Simplicity• Logic and display separation• Client and server side (Javascript and Java)• Client-side speed   ...
Soy Features• Simplicity• Logic and display separation• Client and server side (Javascript and Java)• Client-side speed• S...
Soy Features• Simplicity• Logic and display separation• Client and server side (Javascript and Java)• Client-side speed• S...
Soy - Example{namespace examples.simple}/** * Greets a person using "Hello" by default. * @param name The name of the pers...
Soy Syntax - Types      Type                  Examples       null                     null     Boolean                fals...
Soy Syntax - Operators          •   - (unary) not          •   * / %          •   + - (binary)          •   < > <= >=     ...
Soy - Commands                 25
Soy - Commands• {template}{/template}                          25
Soy - Commands• {template}{/template}• {literal}{/literal}                          25
Soy - Commands• {template}{/template}• {literal}{/literal}• {print <expression>}                          25
Soy - Commands• {template}{/template}• {literal}{/literal}• {print <expression>}• {<expression>}                          25
Soy - Commands• {template}{/template}• {literal}{/literal}• {print <expression>}• {<expression>}• {if <expression>},  {els...
Soy - Commands• {template}{/template}     • {foreach}, {ifempty}, {/foreach}• {literal}{/literal}• {print <expression>}• {...
Soy - Commands• {template}{/template}     • {foreach}, {ifempty}, {/foreach}• {literal}{/literal}       • {for}, {/for}• {...
Soy - Commands• {template}{/template}     • {foreach}, {ifempty}, {/foreach}• {literal}{/literal}       • {for}, {/for}• {...
Soy - Commands• {template}{/template}     • {foreach}, {ifempty}, {/foreach}• {literal}{/literal}       • {for}, {/for}• {...
Soy - defining variables                          26
Soy - defining variables                          26
Soy - defining variablesNot Supported!   Keep business logic away from view!   26
Useful functions • {getText(i18n-key, ....) • {contextPath} • {$data|truncate:30}                                27
Soy Javascript Compilation      {namespace JIRA.Templates.Demo}      /**      * Simplest Hello world demo      * @param na...
28
29
// This file was automatically generated from demo.soy.// Please dont edit this file by hand.if (typeof JIRA == undefined)...
// This file was automatically generated from demo.soy.// Please dont edit this file by hand.if (typeof JIRA == undefined)...
Auto-escaping• implicit by default to HTML escaping• {namespace com.example autoescape="XXX"}  XXX may be true, false, con...
Contextual Auto-escaping                           31
Contextual Auto-escaping/** * @param name */{template .helloWorld autoescape="contextual"}<a href="/Demo?name={$name}" onc...
Contextual Auto-escaping/** * @param name */{template .helloWorld autoescape="contextual"}<a href="/Demo?name={$name}" onc...
Contextual Auto-escaping/** * @param name */{template .helloWorld autoescape="contextual"}<a href="/Demo?name={$name}" onc...
Contextual Auto-escaping    /**     * @param name     */    {template .helloWorld autoescape="contextual"}    <a href="/De...
Contextual Auto-escaping    /**     * @param name     */    {template .helloWorld autoescape="contextual"}    <a href="/De...
Contextual Auto-escaping    /**     * @param name     */    {template .helloWorld autoescape="contextual"}    <a href="/De...
Contextual Auto-escaping    /**     * @param name     */    {template .helloWorld autoescape="contextual"}    <a href="/De...
Contextual Auto-escaping    /**     * @param name     */    {template .helloWorld autoescape="contextual"}    <a href="/De...
Soy @ Atlassian• JIRA (gadgets, new project administration, mails, ...)• GreenHopper• PAC• ...                            ...
Soy and Atlassian Plugins<web-resource key="my-key">        <transformation extension="soy">            <transformer key="...
Server-side Soy• Atlassian Plugin Framework favours Velocity• SoyTemplateRenderer/SoyTemplateRendererProvider• DefaultVelo...
Soy - Coding Example                       35
Soy - Template Library • {call} in Soy • web-resource <dependency>                               36
Backbone.js              37
Backbone.js• Event-driven• Models• Views (responsible for keeping markup in sync with  model)                             ...
Our story with backbone.js                             39
Our story with backbone.js• Version/Component/People management in JIRA  (Ignite) - 2011                                  ...
Our story with backbone.js• Version/Component/People management in JIRA  (Ignite) - 2011• JIRA Importers Plugin, JIRA Mail...
Our story with backbone.js• Version/Component/People management in JIRA  (Ignite) - 2011• JIRA Importers Plugin, JIRA Mail...
Our story with backbone.js• Version/Component/People management in JIRA  (Ignite) - 2011• JIRA Importers Plugin, JIRA Mail...
Why Backbone               40
Why Backbone         backbone.js                       40
Why Backbone         backbone.js      JIRA is a backbone                           40
Why Backbone      JIRA is a backbone                backbone.js                              40
Why Backbone.js                  41
Why Backbone.js• Small                  41
Why Backbone.js• Small• Flexible                  41
Why Backbone.js• Small• Flexible• Does not impose any templating technologies                                             ...
Why Backbone.js• Small• Flexible• Does not impose any templating technologies• Well documented                            ...
Why Backbone.js• Small• Flexible• Does not impose any templating technologies• Well documented• Popular                   ...
Why Backbone.js• Small• Flexible• Does not impose any templating technologies• Well documented• Popular• Liked by us      ...
42
DOM / Markup               42
JavascriptDOM / Markup                        42
JavascriptDOM / Markup                        42
JQuery           JavascriptDOM / Markup                                 42
JQuery           JavascriptDOM / Markup                                 42
AUI                JQuery            JavascriptDOM / Markup                                  42
AUI                JQuery            JavascriptDOM / Markup                                  42
AUI                JQuery            JavascriptDOM / Markup                                  42
AUI                JQuery            JavascriptDOM / Markup                                  42
Soy (client)         AUI                JQuery                           Javascript               DOM / Markup            ...
Soy (client)         AUI                JQuery                           Javascript               DOM / Markup            ...
Soy (client)         AUI                JQuery                           Javascript               DOM / Markup            ...
Backbone.jsSoy (client)         AUI                JQuery                           Javascript               DOM / Markup ...
Backbone.jsSoy (client)         AUI                JQuery                           Javascript               DOM / Markup ...
Backbone.jsSoy (client)         AUI                JQuery                           Javascript               DOM / Markup ...
Backbone.jsSoy (client)         AUI                JQuery                           Javascript               DOM / Markup ...
Backbone.jsSoy (client)         AUI                JQuery                           Javascript               DOM / Markup ...
REST API                       Backbone.js           Soy (client)         AUI                JQuery                       ...
REST API                       Backbone.js           Soy (client)         AUI                JQuery                       ...
REST API                       Backbone.jsServicesManagers   Soy (client)         AUI                JQuery               ...
REST API                       Backbone.jsServicesManagers   Soy (client)         AUI                JQuery               ...
Possible Future• Easier, more powerful and efficient web resource  transformations• Better support for Soy on the server si...
Looking back...                  44
Looking back...2.5 years ago...                   44
Looking back...2.5 years ago...most of this stuff was not possible                                      44
“   Don’t underestimate the power of the client-side    programming. Time to learn Javascript and    related frameworks, y...
TAKE-AWAYS“   Atlassian is moving fast to client-side programming.    Technology is there. Are you ready?                 ...
Thank you!
Better Front-end Development in Atlassian Plugins
Upcoming SlideShare
Loading in...5
×

Better Front-end Development in Atlassian Plugins

2,918

Published on

Presentation showing these elements of plugin framework added in 2009 - 2011 which help us write easier much more sexier web 2.0 plugins. The talk then concentrates on Soy as the new templating mechanism which is getting very popular at Atlassian.

Published in: Technology, Business
2 Comments
1 Like
Statistics
Notes
No Downloads
Views
Total Views
2,918
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
23
Comments
2
Likes
1
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • Tell about the story - my gradual \n1 min\n
  • JIRA 1.x - 3. as a traditional Java web application (no AJAX, quite heavy MVC)\nWebWork\nNo REST support for plugins, now web-resource context\n3 min\n
  • JIRA 1.x - 3. as a traditional Java web application (no AJAX, quite heavy MVC)\nWebWork\nNo REST support for plugins, now web-resource context\n3 min\n
  • JIRA 1.x - 3. as a traditional Java web application (no AJAX, quite heavy MVC)\nWebWork\nNo REST support for plugins, now web-resource context\n3 min\n
  • JIRA 1.x - 3. as a traditional Java web application (no AJAX, quite heavy MVC)\nWebWork\nNo REST support for plugins, now web-resource context\n3 min\n
  • JIRA 1.x - 3. as a traditional Java web application (no AJAX, quite heavy MVC)\nWebWork\nNo REST support for plugins, now web-resource context\n3 min\n
  • 4 min\n
  • 4 min\n
  • 4 min\n
  • \n
  • 5\n
  • 7\ntell about servlet filter\n
  • 10\nJoke: who reads Plugin Framework Upgrade Guides or Release Notes\n
  • caching vs. locale or baseUrl = taken care of by plugin framework on application itself - class WebResourceIntegration and JiraWebResourceIntegration\n12\n
  • 14\n
  • 14\n
  • 14\n
  • 14\n
  • 14\n
  • 15\n
  • 15\n
  • \n
  • 17\n
  • 17\n
  • 17\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • 18\n
  • \n
  • \n
  • 20\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • mention that AJS.template is brain dead - just variable substitution, no loops, ifs\nscript type=&amp;#x201D;text/x-template&amp;#x201D;\n22\nask: who knows Soy\n
  • mention that AJS.template is brain dead - just variable substitution, no loops, ifs\nscript type=&amp;#x201D;text/x-template&amp;#x201D;\n22\nask: who knows Soy\n
  • mention that AJS.template is brain dead - just variable substitution, no loops, ifs\nscript type=&amp;#x201D;text/x-template&amp;#x201D;\n22\nask: who knows Soy\n
  • 24\n
  • 24\n
  • 24\n
  • 24\n
  • 24\n
  • 24\n
  • Tell what happens if @param name is missing (exception in runtime), tell about \n
  • Warning! In Java only simple types can be used like this\n26\n
  • \n
  • 28\n
  • 28\n
  • 28\n
  • 28\n
  • 28\n
  • 28\n
  • 28\n
  • 28\n
  • 28\n
  • \n
  • \n
  • \n
  • 30\n
  • \n
  • \n
  • 32\n
  • 32\n
  • \n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 34\n
  • 35\n
  • 36\n
  • 37\n
  • 37\n
  • 36\n
  • \n
  • 38\n
  • 40\n
  • 40\n
  • 40\n
  • 40\n
  • 41\n
  • 41\n
  • 41\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • 42\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Better Front-end Development in Atlassian Plugins

    1. 1. Better front-end developmentin Atlassian pluginsThe road from back-end to front-end programmingWojciech SeligaJIRA Development Team Lead, AtlassianCo-founder, Spartez 2
    2. 2. 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) 3
    3. 3. A bit of history 4
    4. 4. A bit of history• 2002 - 2006 - Awesome UI, Web 1.0 4
    5. 5. A bit of history• 2002 - 2006 - Awesome UI, Web 1.0 WebWork, XWork, JSP, Velocity, Freemarker 4
    6. 6. A bit of history• 2002 - 2006 - Awesome UI, Web 1.0 WebWork, XWork, JSP, Velocity, Freemarker• 2006 - 2009 - Features, features, features! 4
    7. 7. 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 4
    8. 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• 2009 - now - new Atlassian UI, Web 2.0+ 4
    9. 9. Evolution Step 1 - AUI• Confluence 3.0+, JIRA 3.13.5+• Forms, Controls, Tabs, Inline Dialogs, ..., AJS 5
    10. 10. Evolution Step 1 - AUI• Confluence 3.0+, JIRA 3.13.5+• Forms, Controls, Tabs, Inline Dialogs, ..., AJS 5
    11. 11. Evolution Step 1 - AUI• Confluence 3.0+, JIRA 3.13.5+• Forms, Controls, Tabs, Inline Dialogs, ..., AJS 5
    12. 12. Evolution Step 1 - AUI• Confluence 3.0+, JIRA 3.13.5+• Forms, Controls, Tabs, Inline Dialogs, ..., AJS 5
    13. 13. 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) 6
    14. 14. @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(); }} 7
    15. 15. injectable JS & CSS+ REST = WIN 8
    16. 16. 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> 9
    17. 17. Evolution Step 4 (2010)web-resource-transformer<web-resource-transformer key="my-key" class="fqcn.must.implement.WebResourceTransformer"/> 10
    18. 18. 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);} 10
    19. 19. web-resource-transformers 11
    20. 20. web-resource-transformers• I18n 11
    21. 21. web-resource-transformers• I18n• L&F 11
    22. 22. web-resource-transformers• I18n• L&F• context path 11
    23. 23. web-resource-transformers• I18n• L&F• context path• SASS, LESS 11
    24. 24. web-resource-transformers• I18n• L&F• context path• SASS, LESS• Soy 11
    25. 25. I18N 12
    26. 26. I18N i18n resource file defined in atlassian-plugin.xml hello.world=Hello World from.atlascamp=from AtlasCamp {0} 12
    27. 27. I18N - web resourcetransformation definition 13
    28. 28. 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> 13
    29. 29. I18N transformation 14
    30. 30. I18N transformationvar helloText = AJS.I18n.getText("hello.world") + " " + AJS.I18n.getText("from.atlascamp", 2012) 14
    31. 31. I18N transformationvar helloText = AJS.I18n.getText("hello.world") + " " + AJS.I18n.getText("from.atlascamp", 2012) 14
    32. 32. I18N transformationvar helloText = AJS.I18n.getText("hello.world") + " " + AJS.I18n.getText("from.atlascamp", 2012) var helloText = "Hello World" + " " + AJS.format("from AtlasCamp {0}", 2012) 14
    33. 33. Times of Hacking 15
    34. 34. Times of Hacking Javascript hacks freestyle AJAX JQuery Javascript hacks JQuery JQuery JQuery JQuery JQuery JQueryJQuery 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 15
    35. 35. “ 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 16
    36. 36. Evolution Step 5 (2011) Structure on the client side 17
    37. 37. Evolution Step 5 (2011) Structure on the client side For speed, beauty and maintainability 17
    38. 38. Evolution Step 5 (2011) Structure on the client side For speed, beauty and maintainability FTW 17
    39. 39. 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) 18
    40. 40. More structured approach in JS • Backbone.js • Soy (Google Closure Templates) 19
    41. 41. More structured approach in JS • Backbone.js • Soy (Google Closure Templates) MV C 19
    42. 42. More structured approach in JS M Backbone.js • • Soy (Google Closure Templates) VC 19
    43. 43. More structured approach in JS M Backbone.js • V • Soy (Google Closure Templates) C 19
    44. 44. More structured approach in JS M Backbone.js C • V • Soy (Google Closure Templates) 19
    45. 45. More structured approach in JS • Backbone.js • Soy (Google Closure Templates) 19
    46. 46. More structured approach in JS • Soy (Google Closure Templates) 19
    47. 47. More structured approach in JS 19
    48. 48. Our Road to Soy 20
    49. 49. Our Road to Soy• AJS.template 20
    50. 50. Our Road to Soy• AJS.template• Mustache 20
    51. 51. Our Road to Soy• AJS.template• Mustache• Soy 20
    52. 52. Soy Features 21
    53. 53. Soy Features• Simplicity 21
    54. 54. Soy Features• Simplicity• Logic and display separation 21
    55. 55. Soy Features• Simplicity• Logic and display separation• Client and server side (Javascript and Java) 21
    56. 56. Soy Features• Simplicity• Logic and display separation• Client and server side (Javascript and Java)• Client-side speed 21
    57. 57. Soy Features• Simplicity• Logic and display separation• Client and server side (Javascript and Java)• Client-side speed• Security (auto-escaping) 21
    58. 58. Soy Features• Simplicity• Logic and display separation• Client and server side (Javascript and Java)• Client-side speed• Security (auto-escaping)• Battle-tested by Google 21
    59. 59. 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} 22
    60. 60. 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] 23
    61. 61. Soy Syntax - Operators • - (unary) not • * / % • + - (binary) • < > <= >= • == != • and • or • ?: (ternary) 24
    62. 62. Soy - Commands 25
    63. 63. Soy - Commands• {template}{/template} 25
    64. 64. Soy - Commands• {template}{/template}• {literal}{/literal} 25
    65. 65. Soy - Commands• {template}{/template}• {literal}{/literal}• {print <expression>} 25
    66. 66. Soy - Commands• {template}{/template}• {literal}{/literal}• {print <expression>}• {<expression>} 25
    67. 67. Soy - Commands• {template}{/template}• {literal}{/literal}• {print <expression>}• {<expression>}• {if <expression>}, {elseif}, {else}, {/if} 25
    68. 68. Soy - Commands• {template}{/template} • {foreach}, {ifempty}, {/foreach}• {literal}{/literal}• {print <expression>}• {<expression>}• {if <expression>}, {elseif}, {else}, {/if} 25
    69. 69. Soy - Commands• {template}{/template} • {foreach}, {ifempty}, {/foreach}• {literal}{/literal} • {for}, {/for}• {print <expression>}• {<expression>}• {if <expression>}, {elseif}, {else}, {/if} 25
    70. 70. Soy - Commands• {template}{/template} • {foreach}, {ifempty}, {/foreach}• {literal}{/literal} • {for}, {/for}• {print <expression>} • {call}, {/call}, {param}, {/param}• {<expression>}• {if <expression>}, {elseif}, {else}, {/if} 25
    71. 71. 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} 25
    72. 72. Soy - defining variables 26
    73. 73. Soy - defining variables 26
    74. 74. Soy - defining variablesNot Supported! Keep business logic away from view! 26
    75. 75. Useful functions • {getText(i18n-key, ....) • {contextPath} • {$data|truncate:30} 27
    76. 76. Soy Javascript Compilation {namespace JIRA.Templates.Demo} /** * Simplest Hello world demo * @param name */ {template .helloWorld} <div>Hello World, {$name}</div> {/template} 28
    77. 77. 28
    78. 78. 29
    79. 79. // 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();}; 29
    80. 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();}; 29
    81. 81. 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 30
    82. 82. Contextual Auto-escaping 31
    83. 83. Contextual Auto-escaping/** * @param name */{template .helloWorld autoescape="contextual"}<a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a>{/template} 31
    84. 84. Contextual Auto-escaping/** * @param name */{template .helloWorld autoescape="contextual"}<a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a>{/template} 31
    85. 85. 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>"} 31
    86. 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>"}<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> 31
    87. 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> 31
    88. 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> 31
    89. 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> 31
    90. 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> 31
    91. 91. Soy @ Atlassian• JIRA (gadgets, new project administration, mails, ...)• GreenHopper• PAC• ... 32
    92. 92. 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> 33
    93. 93. Server-side Soy• Atlassian Plugin Framework favours Velocity• SoyTemplateRenderer/SoyTemplateRendererProvider• DefaultVelocityContextProvider (jira-core)• SoyData, SoyDataList, SoyDataMap, SoyData.createFromExistingData() 34
    94. 94. Soy - Coding Example 35
    95. 95. Soy - Template Library • {call} in Soy • web-resource <dependency> 36
    96. 96. Backbone.js 37
    97. 97. Backbone.js• Event-driven• Models• Views (responsible for keeping markup in sync with model) 38
    98. 98. Our story with backbone.js 39
    99. 99. Our story with backbone.js• Version/Component/People management in JIRA (Ignite) - 2011 39
    100. 100. Our story with backbone.js• Version/Component/People management in JIRA (Ignite) - 2011• JIRA Importers Plugin, JIRA Mail Plugin - 2011 39
    101. 101. Our story with backbone.js• Version/Component/People management in JIRA (Ignite) - 2011• JIRA Importers Plugin, JIRA Mail Plugin - 2011• RAB - 2011 39
    102. 102. 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 39
    103. 103. Why Backbone 40
    104. 104. Why Backbone backbone.js 40
    105. 105. Why Backbone backbone.js JIRA is a backbone 40
    106. 106. Why Backbone JIRA is a backbone backbone.js 40
    107. 107. Why Backbone.js 41
    108. 108. Why Backbone.js• Small 41
    109. 109. Why Backbone.js• Small• Flexible 41
    110. 110. Why Backbone.js• Small• Flexible• Does not impose any templating technologies 41
    111. 111. Why Backbone.js• Small• Flexible• Does not impose any templating technologies• Well documented 41
    112. 112. Why Backbone.js• Small• Flexible• Does not impose any templating technologies• Well documented• Popular 41
    113. 113. Why Backbone.js• Small• Flexible• Does not impose any templating technologies• Well documented• Popular• Liked by us 41
    114. 114. 42
    115. 115. DOM / Markup 42
    116. 116. JavascriptDOM / Markup 42
    117. 117. JavascriptDOM / Markup 42
    118. 118. JQuery JavascriptDOM / Markup 42
    119. 119. JQuery JavascriptDOM / Markup 42
    120. 120. AUI JQuery JavascriptDOM / Markup 42
    121. 121. AUI JQuery JavascriptDOM / Markup 42
    122. 122. AUI JQuery JavascriptDOM / Markup 42
    123. 123. AUI JQuery JavascriptDOM / Markup 42
    124. 124. Soy (client) AUI JQuery Javascript DOM / Markup 42
    125. 125. Soy (client) AUI JQuery Javascript DOM / Markup 42
    126. 126. Soy (client) AUI JQuery Javascript DOM / Markup 42
    127. 127. Backbone.jsSoy (client) AUI JQuery Javascript DOM / Markup 42
    128. 128. Backbone.jsSoy (client) AUI JQuery Javascript DOM / Markup 42
    129. 129. Backbone.jsSoy (client) AUI JQuery Javascript DOM / Markup 42
    130. 130. Backbone.jsSoy (client) AUI JQuery Javascript DOM / Markup 42
    131. 131. Backbone.jsSoy (client) AUI JQuery Javascript DOM / Markup 42
    132. 132. REST API Backbone.js Soy (client) AUI JQuery Javascript DOM / Markup 42
    133. 133. REST API Backbone.js Soy (client) AUI JQuery Javascript DOM / Markup 42
    134. 134. REST API Backbone.jsServicesManagers Soy (client) AUI JQuery Javascript DOM / Markup 42
    135. 135. REST API Backbone.jsServicesManagers Soy (client) AUI JQuery Javascript DOM / Markup 42
    136. 136. 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) 43
    137. 137. Looking back... 44
    138. 138. Looking back...2.5 years ago... 44
    139. 139. Looking back...2.5 years ago...most of this stuff was not possible 44
    140. 140. “ 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 45
    141. 141. TAKE-AWAYS“ Atlassian is moving fast to client-side programming. Technology is there. Are you ready? ” #atlascamp 46
    142. 142. Thank you!
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×