SlideShare a Scribd company logo
1 of 143
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
                                                  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
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




                                                4
A bit of history
• 2002 - 2006 - Awesome UI, Web 1.0
     WebWork, XWork, JSP, Velocity, Freemarker
• 2006 - 2009 - Features, features, features!




                                                 4
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
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
Evolution Step 1 - AUI
• Confluence 3.0+, JIRA 3.13.5+
• Forms, Controls, Tabs, Inline Dialogs, ..., AJS




                                                    5
Evolution Step 1 - AUI
• Confluence 3.0+, JIRA 3.13.5+
• Forms, Controls, Tabs, Inline Dialogs, ..., AJS




                                                    5
Evolution Step 1 - AUI
• Confluence 3.0+, JIRA 3.13.5+
• Forms, Controls, Tabs, Inline Dialogs, ..., AJS




                                                    5
Evolution Step 1 - AUI
• Confluence 3.0+, JIRA 3.13.5+
• Forms, Controls, Tabs, Inline Dialogs, ..., AJS




                                                    5
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
@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
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
• 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
Evolution Step 4 (2010)
web-resource-transformer
<web-resource-transformer key="my-key"
      class="fqcn.must.implement.WebResourceTransformer"/>




                                                             10
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
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 AtlasCamp {0}




                                                        12
I18N - web resource
transformation definition




                           13
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
I18N transformation




                      14
I18N transformation

var helloText = AJS.I18n.getText("hello.world") + " "
     + AJS.I18n.getText("from.atlascamp", 2012)




                                                        14
I18N transformation

var helloText = AJS.I18n.getText("hello.world") + " "
     + AJS.I18n.getText("from.atlascamp", 2012)




                                                        14
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)


                                                        14
Times of Hacking




                   15
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                                                                                                 15
“
    It's 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
Evolution Step 5 (2011)


      Structure on the client side




                                     17
Evolution Step 5 (2011)


      Structure on the client side

 For speed, beauty and maintainability


                                         17
Evolution Step 5 (2011)


      Structure on the client side

 For speed, beauty and maintainability

                 FTW
                                         17
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
More structured approach in JS

         • Backbone.js
         • Soy (Google Closure Templates)




                                            19
More structured approach in JS

         • Backbone.js
         • Soy (Google Closure Templates)


                 MV C
                                            19
More structured approach in JS

        M Backbone.js
         •
         • Soy (Google Closure Templates)


                    VC
                                            19
More structured approach in JS

        M Backbone.js
         •
                 V
         • Soy (Google Closure Templates)


                        C
                                            19
More structured approach in JS

        M Backbone.js C
         •
                 V
         • Soy (Google Closure Templates)




                                            19
More structured approach in JS

         • Backbone.js
         • Soy (Google Closure Templates)




                                            19
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)




                                                 21
Soy Features
• Simplicity
• Logic and display separation
• Client and server side (Javascript and Java)
• Client-side speed




                                                 21
Soy Features
• Simplicity
• Logic and display separation
• Client and server side (Javascript and Java)
• Client-side speed
• Security (auto-escaping)


                                                 21
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
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
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
Soy Syntax - Operators
          •   - (unary) not
          •   * / %
          •   + - (binary)
          •   < > <= >=
          •   == !=
          •   and
          •   or
          •   ?: (ternary)

                              24
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>},
  {elseif}, {else}, {/if}

                            25
Soy - Commands
• {template}{/template}     • {foreach}, {ifempty}, {/foreach}
• {literal}{/literal}
• {print <expression>}
• {<expression>}
• {if <expression>},
  {elseif}, {else}, {/if}

                                                                 25
Soy - Commands
• {template}{/template}     • {foreach}, {ifempty}, {/foreach}
• {literal}{/literal}       • {for}, {/for}
• {print <expression>}
• {<expression>}
• {if <expression>},
  {elseif}, {else}, {/if}

                                                                 25
Soy - Commands
• {template}{/template}     • {foreach}, {ifempty}, {/foreach}
• {literal}{/literal}       • {for}, {/for}
• {print <expression>}      • {call}, {/call}, {param}, {/param}
• {<expression>}
• {if <expression>},
  {elseif}, {else}, {/if}

                                                                   25
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
Soy - defining variables




                          26
Soy - defining variables




                          26
Soy - defining variables




Not 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 name
      */
      {template .helloWorld}
      <div>Hello World, {$name}</div>
      {/template}



                                        28
28
29
// This file was automatically generated from demo.soy.
// Please don't 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
// This file was automatically generated from demo.soy.
// Please don't 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
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
Contextual Auto-escaping




                           31
Contextual Auto-escaping
/**
 * @param name
 */
{template .helloWorld autoescape="contextual"}
<a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a>
{/template}




                                                                     31
Contextual Auto-escaping
/**
 * @param name
 */
{template .helloWorld autoescape="contextual"}
<a href="/Demo?name={$name}" onclick="var x = {$name}">{$name}</a>
{/template}




                                                                     31
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
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
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
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
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
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
Soy @ Atlassian
• JIRA (gadgets, new project administration, mails, ...)
• GreenHopper
• PAC
• ...




                                                           32
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
Server-side Soy
• Atlassian Plugin Framework favours Velocity
• SoyTemplateRenderer/SoyTemplateRendererProvider
• DefaultVelocityContextProvider (jira-core)
• SoyData, SoyDataList, SoyDataMap,
  SoyData.createFromExistingData()



                                                    34
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)




                                                       38
Our story with backbone.js




                             39
Our story with backbone.js
• Version/Component/People management in JIRA
  (Ignite) - 2011




                                                39
Our story with backbone.js
• Version/Component/People management in JIRA
  (Ignite) - 2011
• JIRA Importers Plugin, JIRA Mail Plugin - 2011




                                                   39
Our story with backbone.js
• Version/Component/People management in JIRA
  (Ignite) - 2011
• JIRA Importers Plugin, JIRA Mail Plugin - 2011
• RAB - 2011




                                                   39
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
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




                                                41
Why Backbone.js
• Small
• Flexible
• Does not impose any templating technologies
• Well documented




                                                41
Why Backbone.js
• Small
• Flexible
• Does not impose any templating technologies
• Well documented
• Popular


                                                41
Why Backbone.js
• Small
• Flexible
• Does not impose any templating technologies
• Well documented
• Popular
• Liked by us
                                                41
42
DOM / Markup

               42
Javascript


DOM / Markup

                        42
Javascript


DOM / Markup

                        42
JQuery


           Javascript


DOM / Markup

                                 42
JQuery


           Javascript


DOM / Markup

                                 42
AUI                JQuery


            Javascript


DOM / Markup

                                  42
AUI                JQuery


            Javascript


DOM / Markup

                                  42
AUI                JQuery


            Javascript


DOM / Markup

                                  42
AUI                JQuery


            Javascript


DOM / Markup

                                  42
Soy (client)         AUI                JQuery


                           Javascript


               DOM / Markup

                                                 42
Soy (client)         AUI                JQuery


                           Javascript


               DOM / Markup

                                                 42
Soy (client)         AUI                JQuery


                           Javascript


               DOM / Markup

                                                 42
Backbone.js




Soy (client)         AUI                JQuery


                           Javascript


               DOM / Markup

                                                 42
Backbone.js




Soy (client)         AUI                JQuery


                           Javascript


               DOM / Markup

                                                 42
Backbone.js




Soy (client)         AUI                JQuery


                           Javascript


               DOM / Markup

                                                 42
Backbone.js




Soy (client)         AUI                JQuery


                           Javascript


               DOM / Markup

                                                 42
Backbone.js




Soy (client)         AUI                JQuery


                           Javascript


               DOM / Markup

                                                 42
REST API                       Backbone.js




           Soy (client)         AUI                JQuery


                                      Javascript


                          DOM / Markup

                                                            42
REST API                       Backbone.js




           Soy (client)         AUI                JQuery


                                      Javascript


                          DOM / Markup

                                                            42
REST API                       Backbone.js


Services
Managers   Soy (client)         AUI                JQuery


                                      Javascript


                          DOM / Markup

                                                            42
REST API                       Backbone.js


Services
Managers   Soy (client)         AUI                JQuery


                                      Javascript


                          DOM / Markup

                                                            42
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
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, you old Java fellow
                                              ”
                                        Master Joda, Javascript convert




                                                                          45
TAKE-AWAYS




“   Atlassian is moving fast to client-side programming.
    Technology is there. Are you ready?
                                          ”
     #atlascamp


                                                           46
Thank you!

More Related Content

What's hot

Advanced #6 clean architecture
Advanced #6  clean architectureAdvanced #6  clean architecture
Advanced #6 clean architectureVitali Pekelis
 
Node.js Development with Apache NetBeans
Node.js Development with Apache NetBeansNode.js Development with Apache NetBeans
Node.js Development with Apache NetBeansRyan Cuprak
 
Developing Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJSDeveloping Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJSShekhar Gulati
 
Web application development using Play Framework (with Java)
Web application development using Play Framework (with Java)Web application development using Play Framework (with Java)
Web application development using Play Framework (with Java)Saeed Zarinfam
 
JavaOne 2011: Migrating Spring Applications to Java EE 6
JavaOne 2011: Migrating Spring Applications to Java EE 6JavaOne 2011: Migrating Spring Applications to Java EE 6
JavaOne 2011: Migrating Spring Applications to Java EE 6Bert Ertman
 
JavaOne 2017 - Choosing a NoSQL API and Database to Avoid Tombstones and Drag...
JavaOne 2017 - Choosing a NoSQL API and Database to Avoid Tombstones and Drag...JavaOne 2017 - Choosing a NoSQL API and Database to Avoid Tombstones and Drag...
JavaOne 2017 - Choosing a NoSQL API and Database to Avoid Tombstones and Drag...Leonardo De Moura Rocha Lima
 
Top 50 java ee 7 best practices [con5669]
Top 50 java ee 7 best practices [con5669]Top 50 java ee 7 best practices [con5669]
Top 50 java ee 7 best practices [con5669]Ryan Cuprak
 
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...Leonardo De Moura Rocha Lima
 
[English version] JavaFX and Web Integration
[English version] JavaFX and Web Integration[English version] JavaFX and Web Integration
[English version] JavaFX and Web IntegrationKazuchika Sekiya
 
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.WO Community
 
Wicket Introduction
Wicket IntroductionWicket Introduction
Wicket IntroductionEyal Golan
 
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...Matt Raible
 
Apache Wicket: 10 jaar en verder - Martijn Dashorst
Apache Wicket: 10 jaar en verder - Martijn DashorstApache Wicket: 10 jaar en verder - Martijn Dashorst
Apache Wicket: 10 jaar en verder - Martijn DashorstNLJUG
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot IntroductionJeevesh Pandey
 
What's New in Spring 3.1
What's New in Spring 3.1What's New in Spring 3.1
What's New in Spring 3.1Matt Raible
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Matt Raible
 
JMP402 Master Class: Managed beans and XPages: Your Time Is Now
JMP402 Master Class: Managed beans and XPages: Your Time Is NowJMP402 Master Class: Managed beans and XPages: Your Time Is Now
JMP402 Master Class: Managed beans and XPages: Your Time Is NowRussell Maher
 

What's hot (20)

Advanced #6 clean architecture
Advanced #6  clean architectureAdvanced #6  clean architecture
Advanced #6 clean architecture
 
Migrating Beyond Java 8
Migrating Beyond Java 8Migrating Beyond Java 8
Migrating Beyond Java 8
 
DataFX - JavaOne 2013
DataFX - JavaOne 2013DataFX - JavaOne 2013
DataFX - JavaOne 2013
 
Node.js Development with Apache NetBeans
Node.js Development with Apache NetBeansNode.js Development with Apache NetBeans
Node.js Development with Apache NetBeans
 
Developing Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJSDeveloping Modern Java Web Applications with Java EE 7 and AngularJS
Developing Modern Java Web Applications with Java EE 7 and AngularJS
 
Web application development using Play Framework (with Java)
Web application development using Play Framework (with Java)Web application development using Play Framework (with Java)
Web application development using Play Framework (with Java)
 
JavaOne 2011: Migrating Spring Applications to Java EE 6
JavaOne 2011: Migrating Spring Applications to Java EE 6JavaOne 2011: Migrating Spring Applications to Java EE 6
JavaOne 2011: Migrating Spring Applications to Java EE 6
 
JavaOne 2017 - Choosing a NoSQL API and Database to Avoid Tombstones and Drag...
JavaOne 2017 - Choosing a NoSQL API and Database to Avoid Tombstones and Drag...JavaOne 2017 - Choosing a NoSQL API and Database to Avoid Tombstones and Drag...
JavaOne 2017 - Choosing a NoSQL API and Database to Avoid Tombstones and Drag...
 
Top 50 java ee 7 best practices [con5669]
Top 50 java ee 7 best practices [con5669]Top 50 java ee 7 best practices [con5669]
Top 50 java ee 7 best practices [con5669]
 
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
 
[English version] JavaFX and Web Integration
[English version] JavaFX and Web Integration[English version] JavaFX and Web Integration
[English version] JavaFX and Web Integration
 
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
 
Wicket Introduction
Wicket IntroductionWicket Introduction
Wicket Introduction
 
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
Java Web Application Security with Java EE, Spring Security and Apache Shiro ...
 
JavaCro'15 - Java EE 8 - An instant snapshot - David Delabassee
JavaCro'15 - Java EE 8 - An instant snapshot - David DelabasseeJavaCro'15 - Java EE 8 - An instant snapshot - David Delabassee
JavaCro'15 - Java EE 8 - An instant snapshot - David Delabassee
 
Apache Wicket: 10 jaar en verder - Martijn Dashorst
Apache Wicket: 10 jaar en verder - Martijn DashorstApache Wicket: 10 jaar en verder - Martijn Dashorst
Apache Wicket: 10 jaar en verder - Martijn Dashorst
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot Introduction
 
What's New in Spring 3.1
What's New in Spring 3.1What's New in Spring 3.1
What's New in Spring 3.1
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
 
JMP402 Master Class: Managed beans and XPages: Your Time Is Now
JMP402 Master Class: Managed beans and XPages: Your Time Is NowJMP402 Master Class: Managed beans and XPages: Your Time Is Now
JMP402 Master Class: Managed beans and XPages: Your Time Is Now
 

Similar to Better Front-end Development in Atlassian Plugins

Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Stephen Chin
 
WSO2Con Asia 2014 - WSO2 AppDev Platform for the Connected Business
WSO2Con Asia 2014 - WSO2 AppDev Platform for the Connected BusinessWSO2Con Asia 2014 - WSO2 AppDev Platform for the Connected Business
WSO2Con Asia 2014 - WSO2 AppDev Platform for the Connected BusinessWSO2
 
Making The Move To Java 17 (JConf 2022)
Making The Move To Java 17 (JConf 2022)Making The Move To Java 17 (JConf 2022)
Making The Move To Java 17 (JConf 2022)Alex Motley
 
What’s new in Java SE, EE, ME, Embedded world & new Strategy
What’s new in Java SE, EE, ME, Embedded world & new StrategyWhat’s new in Java SE, EE, ME, Embedded world & new Strategy
What’s new in Java SE, EE, ME, Embedded world & new StrategyMohamed Taman
 
How to make Ajax Libraries work for you
How to make Ajax Libraries work for youHow to make Ajax Libraries work for you
How to make Ajax Libraries work for youSimon Willison
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overviewjeresig
 
Java EE 7, what's in it for me?
Java EE 7, what's in it for me?Java EE 7, what's in it for me?
Java EE 7, what's in it for me?Alex Soto
 
Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Stephen Chin
 
What's this jQuery? Where it came from, and how it will drive innovation
What's this jQuery? Where it came from, and how it will drive innovationWhat's this jQuery? Where it came from, and how it will drive innovation
What's this jQuery? Where it came from, and how it will drive innovationMarakana Inc.
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)Doris Chen
 
JavaScript Libraries (@Media)
JavaScript Libraries (@Media)JavaScript Libraries (@Media)
JavaScript Libraries (@Media)jeresig
 
JavaScript Libraries (Kings of Code)
JavaScript Libraries (Kings of Code)JavaScript Libraries (Kings of Code)
JavaScript Libraries (Kings of Code)jeresig
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016Matt Raible
 
Java EE 7 (Hamed Hatami)
Java EE 7 (Hamed Hatami)Java EE 7 (Hamed Hatami)
Java EE 7 (Hamed Hatami)Hamed Hatami
 
Mume JQueryMobile Intro
Mume JQueryMobile IntroMume JQueryMobile Intro
Mume JQueryMobile IntroGonzalo Parra
 
JavaScript for ASP.NET programmers (webcast) upload
JavaScript for ASP.NET programmers (webcast) uploadJavaScript for ASP.NET programmers (webcast) upload
JavaScript for ASP.NET programmers (webcast) uploadRuss Fustino
 
jQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPagesjQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPagesMark Roden
 

Similar to Better Front-end Development in Atlassian Plugins (20)

Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5
 
WSO2Con Asia 2014 - WSO2 AppDev Platform for the Connected Business
WSO2Con Asia 2014 - WSO2 AppDev Platform for the Connected BusinessWSO2Con Asia 2014 - WSO2 AppDev Platform for the Connected Business
WSO2Con Asia 2014 - WSO2 AppDev Platform for the Connected Business
 
WSO2 AppDev platform
WSO2 AppDev platformWSO2 AppDev platform
WSO2 AppDev platform
 
Making The Move To Java 17 (JConf 2022)
Making The Move To Java 17 (JConf 2022)Making The Move To Java 17 (JConf 2022)
Making The Move To Java 17 (JConf 2022)
 
What’s new in Java SE, EE, ME, Embedded world & new Strategy
What’s new in Java SE, EE, ME, Embedded world & new StrategyWhat’s new in Java SE, EE, ME, Embedded world & new Strategy
What’s new in Java SE, EE, ME, Embedded world & new Strategy
 
How to make Ajax Libraries work for you
How to make Ajax Libraries work for youHow to make Ajax Libraries work for you
How to make Ajax Libraries work for you
 
JavaScript Library Overview
JavaScript Library OverviewJavaScript Library Overview
JavaScript Library Overview
 
Java EE 7, what's in it for me?
Java EE 7, what's in it for me?Java EE 7, what's in it for me?
Java EE 7, what's in it for me?
 
Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5Moving to the Client - JavaFX and HTML5
Moving to the Client - JavaFX and HTML5
 
JQuery introduction
JQuery introductionJQuery introduction
JQuery introduction
 
What's this jQuery? Where it came from, and how it will drive innovation
What's this jQuery? Where it came from, and how it will drive innovationWhat's this jQuery? Where it came from, and how it will drive innovation
What's this jQuery? Where it came from, and how it will drive innovation
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
 
JavaScript Libraries (@Media)
JavaScript Libraries (@Media)JavaScript Libraries (@Media)
JavaScript Libraries (@Media)
 
JavaScript Libraries (Kings of Code)
JavaScript Libraries (Kings of Code)JavaScript Libraries (Kings of Code)
JavaScript Libraries (Kings of Code)
 
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016
Get Hip with JHipster: Spring Boot + AngularJS + Bootstrap - Devoxx France 2016
 
Java EE 7 (Hamed Hatami)
Java EE 7 (Hamed Hatami)Java EE 7 (Hamed Hatami)
Java EE 7 (Hamed Hatami)
 
Mume JQueryMobile Intro
Mume JQueryMobile IntroMume JQueryMobile Intro
Mume JQueryMobile Intro
 
JSF2
JSF2JSF2
JSF2
 
JavaScript for ASP.NET programmers (webcast) upload
JavaScript for ASP.NET programmers (webcast) uploadJavaScript for ASP.NET programmers (webcast) upload
JavaScript for ASP.NET programmers (webcast) upload
 
jQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPagesjQuery - the world's most popular java script library comes to XPages
jQuery - the world's most popular java script library comes to XPages
 

More from Wojciech Seliga

Sprzedawanie własnego biznesu IT - Confitura 2023.pdf
Sprzedawanie własnego biznesu IT - Confitura 2023.pdfSprzedawanie własnego biznesu IT - Confitura 2023.pdf
Sprzedawanie własnego biznesu IT - Confitura 2023.pdfWojciech Seliga
 
Jak być zarąbistym developerem w oczach szefa i ... klienta
Jak być zarąbistym developerem w oczach szefa i ... klientaJak być zarąbistym developerem w oczach szefa i ... klienta
Jak być zarąbistym developerem w oczach szefa i ... klientaWojciech Seliga
 
How to impress your boss and your customer in a modern software development c...
How to impress your boss and your customer in a modern software development c...How to impress your boss and your customer in a modern software development c...
How to impress your boss and your customer in a modern software development c...Wojciech Seliga
 
Developer plantations - colonialism of XXI century (GeeCON 2017)
Developer plantations - colonialism of XXI century (GeeCON 2017)Developer plantations - colonialism of XXI century (GeeCON 2017)
Developer plantations - colonialism of XXI century (GeeCON 2017)Wojciech Seliga
 
SFI 2017 Plantacje Programistów (Developers Plantations) - Colonialism in XXI...
SFI 2017 Plantacje Programistów (Developers Plantations) - Colonialism in XXI...SFI 2017 Plantacje Programistów (Developers Plantations) - Colonialism in XXI...
SFI 2017 Plantacje Programistów (Developers Plantations) - Colonialism in XXI...Wojciech Seliga
 
Ten lessons I painfully learnt while moving from software developer
to entrep...
Ten lessons I painfully learnt while moving from software developer
to entrep...Ten lessons I painfully learnt while moving from software developer
to entrep...
Ten lessons I painfully learnt while moving from software developer
to entrep...Wojciech Seliga
 
Ten lessons I painfully learnt while moving from software developer to entrep...
Ten lessons I painfully learnt while moving from software developer to entrep...Ten lessons I painfully learnt while moving from software developer to entrep...
Ten lessons I painfully learnt while moving from software developer to entrep...Wojciech Seliga
 
10 bezcennych lekcji dla software developera stającego się szefem firmy
10 bezcennych lekcji dla software developera stającego się szefem firmy10 bezcennych lekcji dla software developera stającego się szefem firmy
10 bezcennych lekcji dla software developera stającego się szefem firmyWojciech Seliga
 
5-10-15 years of Java developer career - Warszawa JUG 2015
5-10-15 years of Java developer career - Warszawa JUG 20155-10-15 years of Java developer career - Warszawa JUG 2015
5-10-15 years of Java developer career - Warszawa JUG 2015Wojciech Seliga
 
Devoxx Poland 2015: 5-10-15 years with Java
Devoxx Poland 2015: 5-10-15 years with Java Devoxx Poland 2015: 5-10-15 years with Java
Devoxx Poland 2015: 5-10-15 years with Java Wojciech Seliga
 
Spartez Open Day March 13th 2015
Spartez Open Day March 13th 2015Spartez Open Day March 13th 2015
Spartez Open Day March 13th 2015Wojciech Seliga
 
Software Development Innovation in Practice - 33rd Degree 2014
Software Development Innovation in Practice - 33rd Degree 2014Software Development Innovation in Practice - 33rd Degree 2014
Software Development Innovation in Practice - 33rd Degree 2014Wojciech Seliga
 
Innowacja w praktyce - Infoshare 2014
Innowacja w praktyce - Infoshare 2014Innowacja w praktyce - Infoshare 2014
Innowacja w praktyce - Infoshare 2014Wojciech Seliga
 
Escaping Test Hell - ACCU 2014
Escaping Test Hell - ACCU 2014Escaping Test Hell - ACCU 2014
Escaping Test Hell - ACCU 2014Wojciech Seliga
 
Escaping Test Hell - Our Journey - XPDays Ukraine 2013
Escaping Test Hell - Our Journey - XPDays Ukraine 2013Escaping Test Hell - Our Journey - XPDays Ukraine 2013
Escaping Test Hell - Our Journey - XPDays Ukraine 2013Wojciech Seliga
 
Confitura 2013 Software Developer Career Unplugged
Confitura 2013 Software Developer Career UnpluggedConfitura 2013 Software Developer Career Unplugged
Confitura 2013 Software Developer Career UnpluggedWojciech Seliga
 
Software Developer Career Unplugged - GeeCon 2013
Software Developer Career Unplugged - GeeCon 2013Software Developer Career Unplugged - GeeCon 2013
Software Developer Career Unplugged - GeeCon 2013Wojciech Seliga
 
Escaping Automated Test Hell - One Year Later
Escaping Automated Test Hell - One Year LaterEscaping Automated Test Hell - One Year Later
Escaping Automated Test Hell - One Year LaterWojciech Seliga
 
How to be Awesome at a Java Developer Job Interview (Confitura 2012, Polish)
How to be Awesome at a Java Developer Job Interview (Confitura 2012, Polish)How to be Awesome at a Java Developer Job Interview (Confitura 2012, Polish)
How to be Awesome at a Java Developer Job Interview (Confitura 2012, Polish)Wojciech Seliga
 
InfoShare 2012 efektywne przeglądy kodu w zespołach agile [Polish]
InfoShare 2012 efektywne przeglądy kodu w zespołach agile [Polish]InfoShare 2012 efektywne przeglądy kodu w zespołach agile [Polish]
InfoShare 2012 efektywne przeglądy kodu w zespołach agile [Polish]Wojciech Seliga
 

More from Wojciech Seliga (20)

Sprzedawanie własnego biznesu IT - Confitura 2023.pdf
Sprzedawanie własnego biznesu IT - Confitura 2023.pdfSprzedawanie własnego biznesu IT - Confitura 2023.pdf
Sprzedawanie własnego biznesu IT - Confitura 2023.pdf
 
Jak być zarąbistym developerem w oczach szefa i ... klienta
Jak być zarąbistym developerem w oczach szefa i ... klientaJak być zarąbistym developerem w oczach szefa i ... klienta
Jak być zarąbistym developerem w oczach szefa i ... klienta
 
How to impress your boss and your customer in a modern software development c...
How to impress your boss and your customer in a modern software development c...How to impress your boss and your customer in a modern software development c...
How to impress your boss and your customer in a modern software development c...
 
Developer plantations - colonialism of XXI century (GeeCON 2017)
Developer plantations - colonialism of XXI century (GeeCON 2017)Developer plantations - colonialism of XXI century (GeeCON 2017)
Developer plantations - colonialism of XXI century (GeeCON 2017)
 
SFI 2017 Plantacje Programistów (Developers Plantations) - Colonialism in XXI...
SFI 2017 Plantacje Programistów (Developers Plantations) - Colonialism in XXI...SFI 2017 Plantacje Programistów (Developers Plantations) - Colonialism in XXI...
SFI 2017 Plantacje Programistów (Developers Plantations) - Colonialism in XXI...
 
Ten lessons I painfully learnt while moving from software developer
to entrep...
Ten lessons I painfully learnt while moving from software developer
to entrep...Ten lessons I painfully learnt while moving from software developer
to entrep...
Ten lessons I painfully learnt while moving from software developer
to entrep...
 
Ten lessons I painfully learnt while moving from software developer to entrep...
Ten lessons I painfully learnt while moving from software developer to entrep...Ten lessons I painfully learnt while moving from software developer to entrep...
Ten lessons I painfully learnt while moving from software developer to entrep...
 
10 bezcennych lekcji dla software developera stającego się szefem firmy
10 bezcennych lekcji dla software developera stającego się szefem firmy10 bezcennych lekcji dla software developera stającego się szefem firmy
10 bezcennych lekcji dla software developera stającego się szefem firmy
 
5-10-15 years of Java developer career - Warszawa JUG 2015
5-10-15 years of Java developer career - Warszawa JUG 20155-10-15 years of Java developer career - Warszawa JUG 2015
5-10-15 years of Java developer career - Warszawa JUG 2015
 
Devoxx Poland 2015: 5-10-15 years with Java
Devoxx Poland 2015: 5-10-15 years with Java Devoxx Poland 2015: 5-10-15 years with Java
Devoxx Poland 2015: 5-10-15 years with Java
 
Spartez Open Day March 13th 2015
Spartez Open Day March 13th 2015Spartez Open Day March 13th 2015
Spartez Open Day March 13th 2015
 
Software Development Innovation in Practice - 33rd Degree 2014
Software Development Innovation in Practice - 33rd Degree 2014Software Development Innovation in Practice - 33rd Degree 2014
Software Development Innovation in Practice - 33rd Degree 2014
 
Innowacja w praktyce - Infoshare 2014
Innowacja w praktyce - Infoshare 2014Innowacja w praktyce - Infoshare 2014
Innowacja w praktyce - Infoshare 2014
 
Escaping Test Hell - ACCU 2014
Escaping Test Hell - ACCU 2014Escaping Test Hell - ACCU 2014
Escaping Test Hell - ACCU 2014
 
Escaping Test Hell - Our Journey - XPDays Ukraine 2013
Escaping Test Hell - Our Journey - XPDays Ukraine 2013Escaping Test Hell - Our Journey - XPDays Ukraine 2013
Escaping Test Hell - Our Journey - XPDays Ukraine 2013
 
Confitura 2013 Software Developer Career Unplugged
Confitura 2013 Software Developer Career UnpluggedConfitura 2013 Software Developer Career Unplugged
Confitura 2013 Software Developer Career Unplugged
 
Software Developer Career Unplugged - GeeCon 2013
Software Developer Career Unplugged - GeeCon 2013Software Developer Career Unplugged - GeeCon 2013
Software Developer Career Unplugged - GeeCon 2013
 
Escaping Automated Test Hell - One Year Later
Escaping Automated Test Hell - One Year LaterEscaping Automated Test Hell - One Year Later
Escaping Automated Test Hell - One Year Later
 
How to be Awesome at a Java Developer Job Interview (Confitura 2012, Polish)
How to be Awesome at a Java Developer Job Interview (Confitura 2012, Polish)How to be Awesome at a Java Developer Job Interview (Confitura 2012, Polish)
How to be Awesome at a Java Developer Job Interview (Confitura 2012, Polish)
 
InfoShare 2012 efektywne przeglądy kodu w zespołach agile [Polish]
InfoShare 2012 efektywne przeglądy kodu w zespołach agile [Polish]InfoShare 2012 efektywne przeglądy kodu w zespołach agile [Polish]
InfoShare 2012 efektywne przeglądy kodu w zespołach agile [Polish]
 

Recently uploaded

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 

Recently uploaded (20)

DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 

Better Front-end Development in Atlassian Plugins

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

Editor's Notes

  1. \n
  2. \n
  3. Tell about the story - my gradual \n1 min\n
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. 4 min\n
  10. 4 min\n
  11. 4 min\n
  12. \n
  13. 5\n
  14. 7\ntell about servlet filter\n
  15. 10\nJoke: who reads Plugin Framework Upgrade Guides or Release Notes\n
  16. caching vs. locale or baseUrl = taken care of by plugin framework on application itself - class WebResourceIntegration and JiraWebResourceIntegration\n12\n
  17. 14\n
  18. 14\n
  19. 14\n
  20. 14\n
  21. 14\n
  22. 15\n
  23. 15\n
  24. \n
  25. 17\n
  26. 17\n
  27. 17\n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. \n
  36. \n
  37. \n
  38. \n
  39. \n
  40. \n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n
  46. \n
  47. \n
  48. \n
  49. \n
  50. \n
  51. \n
  52. \n
  53. \n
  54. \n
  55. \n
  56. \n
  57. \n
  58. \n
  59. \n
  60. \n
  61. \n
  62. \n
  63. \n
  64. \n
  65. \n
  66. \n
  67. \n
  68. \n
  69. \n
  70. \n
  71. \n
  72. \n
  73. \n
  74. \n
  75. \n
  76. \n
  77. \n
  78. \n
  79. 18\n
  80. \n
  81. \n
  82. 20\n
  83. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. 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
  95. 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
  96. 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
  97. 24\n
  98. 24\n
  99. 24\n
  100. 24\n
  101. 24\n
  102. 24\n
  103. Tell what happens if @param name is missing (exception in runtime), tell about \n
  104. Warning! In Java only simple types can be used like this\n26\n
  105. \n
  106. 28\n
  107. 28\n
  108. 28\n
  109. 28\n
  110. 28\n
  111. 28\n
  112. 28\n
  113. 28\n
  114. 28\n
  115. \n
  116. \n
  117. \n
  118. 30\n
  119. \n
  120. \n
  121. 32\n
  122. 32\n
  123. \n
  124. 34\n
  125. 34\n
  126. 34\n
  127. 34\n
  128. 34\n
  129. 34\n
  130. 34\n
  131. 34\n
  132. 34\n
  133. 34\n
  134. 34\n
  135. 34\n
  136. 34\n
  137. 34\n
  138. 34\n
  139. 34\n
  140. 35\n
  141. 36\n
  142. 37\n
  143. 37\n
  144. 36\n
  145. \n
  146. 38\n
  147. 40\n
  148. 40\n
  149. 40\n
  150. 40\n
  151. 41\n
  152. 41\n
  153. 41\n
  154. 42\n
  155. 42\n
  156. 42\n
  157. 42\n
  158. 42\n
  159. 42\n
  160. 42\n
  161. 42\n
  162. 42\n
  163. 42\n
  164. 42\n
  165. 42\n
  166. 42\n
  167. 42\n
  168. 42\n
  169. 42\n
  170. 42\n
  171. 42\n
  172. 42\n
  173. 42\n
  174. 42\n
  175. 42\n
  176. 42\n
  177. 42\n
  178. 42\n
  179. 42\n
  180. 42\n
  181. \n
  182. \n
  183. \n
  184. \n
  185. \n
  186. \n