{"id":5810,"date":"2020-10-08T18:44:24","date_gmt":"2020-10-08T22:44:24","guid":{"rendered":"https:\/\/www.dr-chuck.com\/csev-blog\/?p=5810"},"modified":"2020-10-07T18:44:42","modified_gmt":"2020-10-07T22:44:42","slug":"how-to-build-a-jsr-168-portlet-in-sakai","status":"publish","type":"post","link":"https:\/\/www.dr-chuck.com\/csev-blog\/2020\/10\/how-to-build-a-jsr-168-portlet-in-sakai\/","title":{"rendered":"How to build a JSR-168 Portlet in Sakai"},"content":{"rendered":"<p>Using JSR-168 portlets is the only way to have a page (like Overview) with multiple tools on the page rendered without iframes. \u00a0The portal only removes iframes when a page has one tool. \u00a0If there are &gt; 1 tools &#8211; it uses iframes. \u00a0 But JSR-168 tools never use iframes no matter how many there are on the page.<\/p>\n<p>It is pretty easy to convert a servlet-style tool to portlet-style &#8211; in particular if the tool uses either JSP or Velocity templates, t is pretty simple.<\/p>\n<p>Here is an example of a tool that uses Velocity:<\/p>\n<p><a class=\"\" href=\"https:\/\/github.com\/sakaiproject\/sakai\/tree\/master\/web\/web-portlet\">https:\/\/github.com\/sakaiproject\/sakai\/tree\/master\/web\/web-portlet<\/a><\/p>\n<p><a class=\"\" href=\"https:\/\/github.com\/sakaiproject\/sakai\/blob\/master\/web\/web-portlet\/src\/java\/org\/sakaiproject\/portlets\/PortletIFrame.java\">https:\/\/github.com\/sakaiproject\/sakai\/blob\/master\/web\/web-portlet\/src\/java\/org\/sakaiproject\/portlets\/PortletIFrame.java<\/a><\/p>\n<p>This was a direct conversion from an old iframe+servlet style tool used in earlier versions of Sakai:<\/p>\n<p><a class=\"\" href=\"https:\/\/github.com\/sakaiproject\/sakai\/tree\/master\/web\/web-tool\">https:\/\/github.com\/sakaiproject\/sakai\/tree\/master\/web\/web-tool<\/a><\/p>\n<p>If you want to use JSP as your templating language, the following is a sample JSR-168 portlet:<\/p>\n<p><a class=\"\" href=\"https:\/\/github.com\/sakaiproject\/sakai\/tree\/master\/basiclti\/basiclti-portlet\">https:\/\/github.com\/sakaiproject\/sakai\/tree\/master\/basiclti\/basiclti-portlet<\/a><\/p>\n<p><a class=\"\" href=\"https:\/\/github.com\/sakaiproject\/sakai\/blob\/master\/basiclti\/basiclti-portlet\/src\/java\/org\/sakaiproject\/portlets\/IMSBLTIPortlet.java\">https:\/\/github.com\/sakaiproject\/sakai\/blob\/master\/basiclti\/basiclti-portlet\/src\/java\/org\/sakaiproject\/portlets\/IMSBLTIPortlet.java<\/a><\/p>\n<p>The portlet model sends GETs go to \u201cview&#8221; methods and POSTs to \u201caction\u201d methods. \u00a0Our Velocity tools have the same concept of action and view &#8211; but they are hand-layered on top of a servlet using convention and classes like VelocityPortletPaneledAction so the pattern will be familiar for those who wander through old Sakai code.<\/p>\n<p>Another interesting bit of Portlets is that they have view \u201cmodes\u201d like \u201cHelp\u201d and \u201cEdit\u201d that are part of the spec. \u00a0Velocity \u201cportlets\u201d have panels but they are not as formally defined.<\/p>\n<p>For example if you see a JSR-168 \u00a0portlet in Sakai (<a href=\"https:\/\/www.dr-chuck.com\/csev-blog\/wp-content\/uploads\/2020\/10\/portlet-awesome.png\" target=\"_blank\" rel=\"noopener\">image<\/a>)\u00a0 (Home Information is a portlet) , there is a \u201cEdit\u201d button that comes from the *portal* in the portal title line. \u00a0That edit is not part of the portlet\u2019s markup &#8211; the portlet simply declares one of its views as \u201cthe edit view\u201d and Sakai puts up the button and wires it up.<\/p>\n<p>For an old-school Velocity servlet pretending to be a portlet in an iframe (like Message of the in the image) the \u201cedit mode\u201d is just another panel in the tool and the tool puts out markup with a link to its \u201cedit view\u201d in \u201cOptions\u201d below.<\/p>\n<p>It is surprisingly easy to convert from the old to the new because the view\/panel and action patterns already are pretty parallel &#8211; the velocity servlet that is a fake portlet was one of the inspirations for \u00a0JSR-168 so the similarity is not random. \u00a0Both were \u201ccool&#8221; MVC approaches in 2001-2003.<\/p>\n<p>I love the JSR-168 pattern for multiple independent rectangles on a page. \u00a0There is a clever pattern that allows all of the rectangles to handle the back button and refresh in a consistent manner for all three rectangles simultaneously. \u00a0I would love it if all the Sakai tools were rewritten as portlets &#8211; but with the magic iframe inlining since Sakai 11 &#8211; it is only really beneficial for synoptic tools.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using JSR-168 portlets is the only way to have a page (like Overview) with multiple tools on the page rendered without iframes. \u00a0The portal only removes iframes when a page has one tool. \u00a0If there are &gt; 1 tools &#8211; it uses iframes. \u00a0 But JSR-168 tools never use iframes no matter how many there [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-5810","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts\/5810","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/comments?post=5810"}],"version-history":[{"count":4,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts\/5810\/revisions"}],"predecessor-version":[{"id":5815,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/posts\/5810\/revisions\/5815"}],"wp:attachment":[{"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/media?parent=5810"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/categories?post=5810"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dr-chuck.com\/csev-blog\/wp-json\/wp\/v2\/tags?post=5810"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}