Remixing Confluence With Speakeasy

  • 892 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
892
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
1
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • easy to deploy // fast to deploy // social // per-user\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
  • \n
  • \n

Transcript

  • 1. Remixing Confluence withSpeakeasyNabeelah AliAtlassian 2
  • 2. Show of handsWritten a Confluence plugin? 3
  • 3. Show of handsComfortable with Javascript? 4
  • 4. Show of handsEnjoy memes? 5
  • 5. About meNabeelah AliConfluence developer on 4.0 frontend features 6
  • 6. Confluence 4• new features• diverse users 7
  • 7. “ Be the change you seek. ” Atlassian value 8
  • 8. 9
  • 9. In case you were wondering• ragefaces is really an extension BEFORE AFTER 10
  • 10. I can haz plugin?an atlassian-plugin.xml<atlassian-plugin name="Ragefaces resource" key="example.plugin.ragefaces" plugins-version="2"> <plugin-info> <description>A plugin to turn your [/awyeah]s into images</description> <vendor name="Meme Corporation" url="http://www.memecorp.us"/> <version>1.0</version> </plugin-info> <web-resource name="Resources" key="resources"> <resource name="foo.js" type="download" location="resources/foo.js"/> <context>atl.general</context> </web-resource></atlassian-plugin> 11
  • 11. Creating a Confluence plugin 12
  • 12. Creating a Confluence plugin 13
  • 13. Creating a Confluence plugin run -> debug -> run 14
  • 14. Creating a Confluence plugin run -> debug -> run 15
  • 15. Creating a Confluence plugin run -> debug -> run 16
  • 16. Creating a Confluence plugin run -> debug -> run 17
  • 17. What you will hear today• Speakeasy 101• Techniques for remixing Confluence (show & tell)• Letʼs build an extension• Cautionary Advice 18
  • 18. Speakeasy
  • 19. Speakeasy: the what• cross-product plugin• run client-side Javascript, CSS & HTML 20
  • 20. for plugin developers super fast prototyping 23
  • 21. for confluence admins try out crazy stuff on production data 24
  • 22. for confluence admins user-driven development 25
  • 23. for confluence admins democratise development 26
  • 24. Speakeasy: got Confluence?Atlassian Plugin SDK --atlas-run-standalone --product confluence --version 4.0 27
  • 25. 29
  • 26. 30
  • 27. 31
  • 28. 32
  • 29. Techniques
  • 30. Let’s build this thing1. Include the image2. Restrict the context3. Find/replace4. Twitter request5. Put it in a dialog 36
  • 31. Include the imagevar img = require(speakeasy/resources).getImageUrl(module, bird.png); 37
  • 32. Let’s do this all onready$(document).ready(function() { // we’ll put our code here} 38
  • 33. You have access to• almost everything is namespaced under AJS• AJS.$ [jQuery] 39
  • 34. You have access to• almost everything is namespaced under AJS• AJS.$ [jQuery]• AJS.Meta AJS.Meta.getAllAsMap() AJS.Meta.get(“space-key”) 40
  • 35. Restrict the context if (!!AJS.Meta.get("page-id") && !AJS.Meta.get("editor-mode")) { // do our stuff } 41
  • 36. atlassian atlassianConfluencep agesviewing a page/blog editing a page/blog dashboardbreadcrumbs breadcrumbs breadcrumbs title title Welcome to Confluence Updates content content Spaces SAVE atlassian atlassian 42
  • 37. Find & replace  var content = AJS.$("#main-content");  var twitterfiedContent = content.html().replace(/(^|s)#(w+)/g, " $1#<a href="http://search.twitter.com/search?q=%23$2">$2</a> <img src="+ img + " class=twittericon hashtag=$2/>");  content.html(twitterfiedContent); 43
  • 38. Twitter request      $.getJSON("http://search.twitter.com/search.json?callback=?", { q: "#" + id, rpp: "5", lang: "en" }, function(data) {    $.each(data.results, function() {    // Put each result’s twitter handle, tweet text and user //profile photo in nice divs and style.               }); });    44
  • 39. Twitter request      $.getJSON("http://search.twitter.com/search.json?callback=?", { q: "#" + id, rpp: "5", lang: "en" }, function(data) {    $.each(data.results, function() {    // Put each result’s twitter handle, tweet text and user //profile photo in nice divs and style.               }); });    45
  • 40. Atlassian User Interface (AUI)• a reusable set of UI components 46
  • 41. Put it in a dialog    AJS.InlineDialog($(this), 1, function(content, trigger, showPopup) {    },  {onHover:true}); 47
  • 42. Put it in a dialog    AJS.InlineDialog($(this), 1, function(content, trigger, showPopup) {      var tweets = AJS.$("<div></div>").attr("id", "tweets");      $.getJSON("http://search.twitter.com/search.json?callback=?", {q: "#" + id, rpp: "5",lang: "en"}, function(data) {        $.each(data.results, function() { // Assemble results into a tweets div.        });        $(content).html(tweets);       showPopup();       });    },  {onHover:true}); 48
  • 43. THE TWEETINATOR 49
  • 44. Cautionary advice
  • 45. Breaking things• Unsubscribe & restore URLs yourinstance/plugins/servlet/speakeasy/unsubscribe yourinstance/plugins/servlet/speakeasy/restore 51
  • 46. Breaking thingsFeedback 52
  • 47. Breaking things 53
  • 48. Should you use it?• Do you trust your users?• Does your instance allow public signup? 54
  • 49. Cross-site scripting• inserting unescaped HTML into the page • from user input • from data you fetched 55
  • 50. XSS Examplevar result = "<script>alert();</script>";var el = document.getElementById(myDiv);     56
  • 51. XSS Examplevar result = "<script>alert();</script>";var el = document.getElementById(myDiv);el.innerHTML = result; 57
  • 52. XSS Examplevar result = "<script>alert();</script>";var el = document.getElementById(myDiv);el.innerHTML = result; // BAD - Don’t do this! 58
  • 53. XSS Examplevar result = "<script>alert();</script>";var el = document.getElementById(myDiv);el.innerHTML = result; // BAD - Don’t do this!el.innerHTML = AJS.escapeHtml(result); // Do this instead. 59
  • 54. XSS Examplevar result = "<script>alert();</script>";var el = document.getElementById(myDiv);el.innerHTML = result; // BAD - Don’t do this!el.innerHTML = AJS.escapeHtml(result); // Do this instead.AJS.$(el).text(result); // Or this. 60
  • 55. Interested in learning more?Securing your Plugin - Penny Wyatt @ AtlasCamp 2010 Protip If you weren’t here last year or just enjoy nostalgia, check out the Atlascamp 2010 website for videos of every session. 61
  • 56. Where can you go from here?
  • 57. Product Compatibility• Speakeasy documentation• Extension repository• Remember: not just Confluence! 63
  • 58. ResourcesSpeakeasy Documentationhttps://developer.atlassian.com/display/SPEAK/SpeakeasySpeakeasy Source on githubhttps://github.com/mrdon/speakeasy-pluginSpeakeasy JARshttps://maven.atlassian.com/content/repositories/atlassian-public/com/atlassian/labs/speakeasy-plugin/ 64
  • 59. TAKE-AWAYS“ Got an hour to spare? That’s enough time to ” prototype a new Confluence feature with Speakeasy. #atlascamp 65
  • 60. Thank you!