<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DkUDRXs_eip7ImA9WhRaE0Q.&quot;"><id>tag:blogger.com,1999:blog-5349471866547418688</id><updated>2012-02-16T12:11:14.542Z</updated><category term="apache" /><category term="communique" /><category term="day" /><category term="performance" /><category term="cq" /><category term="components" /><category term="templates components" /><category term="caching" /><category term="analytics" /><category term="cq qrcode programming java osgi googlecharts sling apache day cq5 mobile" /><category term="google" /><title>CQStuff</title><subtitle type="html">Somewhere to squirrel my Day CQ Experiences</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.diffa.co.uk/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.diffa.co.uk/" /><author><name>Chris Pilsworth</name><uri>http://www.blogger.com/profile/03221639608396248493</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Cqstuff" /><feedburner:info uri="cqstuff" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0YNQnk5eCp7ImA9WxFSFkU.&quot;"><id>tag:blogger.com,1999:blog-5349471866547418688.post-5069353003824968339</id><published>2010-04-19T14:47:00.002+01:00</published><updated>2010-04-19T14:53:13.720+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-19T14:53:13.720+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="cq qrcode programming java osgi googlecharts sling apache day cq5 mobile" /><title>Creating QR Codes for Apache Sling URLs</title><content type="html">Matt Cutts &lt;a href="http://twitter.com/mattcutts/status/11780579336"&gt;mentioned recently&lt;/a&gt; that the goo.gl URL shortening service had a trick where if a ".qr" extension is added to the shortened URL then a &lt;a href="http://en.wikipedia.org/wiki/QRcode"&gt;QR Code&lt;/a&gt; image is generated for that URL. &lt;br /&gt;
&lt;br /&gt;
After a quick look at the &lt;a href="http://sling.apache.org/site/servlets.html"&gt;Apache Sling documentation&lt;/a&gt; it seemed that adding such a feature to Sling/ Day CQ would be pretty easy, especially as goo.gl uses the &lt;a href="http://code.google.com/apis/chart/docs/gallery/qr_codes.html"&gt;Google Chart API&lt;/a&gt; to create the images.&lt;br /&gt;
&lt;br /&gt;
To deal with requests within Sling based on the url extension, a Servlet Service must be added via an OSGi bundle and use service reference properties to detail which extensions/paths/selectors/methods/prefix are handled by this servlet. &amp;nbsp;Thanks to the maven-bundle-plugin and maven-scr-plugins, packaging this bundle for deployment using Maven is a piece of cake.&lt;br /&gt;
&lt;br /&gt;
The Servlet is quite simple.  Here are the SCR annotations from the Servlet class javadoc that tell the Sling what type of requests this Servlet will service:&lt;br /&gt;
&lt;pre&gt;/**
 * @scr.service interface="javax.servlet.Servlet"
 * @scr.property name="sling.servlet.resourceTypes"
 *               value="sling/servlet/default"
 *
 * @scr.property name="sling.servlet.extensions" value = "qr"
 */
&lt;/pre&gt;&lt;br /&gt;
and here are the couple of lines that create the redirect URL for the QR Code image and send that in the response.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;private static final String baseUrl = "http://chart.apis.google.com/chart?cht=qr&amp;amp;chs=150x150&amp;amp;choe=UTF-8&amp;amp;chld=H&amp;amp;chl=";
 
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ... { 
 resp.sendRedirect(baseUrl + removeQRExtension(req));
} 

protected String removeQRExtension(HttpServletRequest req) {
 StringBuffer url = req.getRequestURL();
 return url.substring(0, url.length() -3);  
} 
&lt;/pre&gt;&lt;a href="http://chart.apis.google.com/chart?cht=qr&amp;amp;chs=150x150&amp;amp;choe=UTF-8&amp;amp;chld=H&amp;amp;chl=http://localhost:4502/libs/cq/core/content/welcome.html" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" src="http://chart.apis.google.com/chart?cht=qr&amp;amp;chs=150x150&amp;amp;choe=UTF-8&amp;amp;chld=H&amp;amp;chl=http://localhost:4502/libs/cq/core/content/welcome.html" /&gt;&lt;/a&gt;&lt;br /&gt;
Once the OSGi bundle is installed, you can add the .qr extension to any url on your Sling/CQ5 server and get back a QR code for that URL. For example the CQ5 URL&lt;br /&gt;
&lt;a href="http://localhost:4502/libs/cq/core/content/welcome.html.qr"&gt;http://localhost:4502/libs/cq/core/content/welcome.html.qr&lt;/a&gt;&lt;br /&gt;
will give you this QR Code.&lt;br /&gt;
&lt;br /&gt;
Although QR codes not yet made it mainstream, they provide a great way for mobile users to grab information quickly and there seem to be plenty of QR code readers out there. &amp;nbsp;I have been using &lt;a href="http://www.quickmark.com.tw/default.asp"&gt;QuickMark&lt;/a&gt;&amp;nbsp;on the iPhone and that works great for me.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;The full code can be found here&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;a href="http://github.com/cpilsworth/urlqrcode"&gt;http://github.com/cpilsworth/urlqrcode&lt;/a&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;and the compiled OSGi bundle can be found here&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;a href="http://github.com/downloads/cpilsworth/urlqrcode/qrcodes-0.0.2-SNAPSHOT.jar"&gt;http://github.com/downloads/cpilsworth/urlqrcode/qrcodes-0.0.2-SNAPSHOT.jar&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5349471866547418688-5069353003824968339?l=blog.diffa.co.uk' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Cqstuff/~4/TNlHtVKo_zI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.diffa.co.uk/feeds/5069353003824968339/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.diffa.co.uk/2010/04/creating-qr-codes-for-apache-sling-urls.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5349471866547418688/posts/default/5069353003824968339?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5349471866547418688/posts/default/5069353003824968339?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Cqstuff/~3/TNlHtVKo_zI/creating-qr-codes-for-apache-sling-urls.html" title="Creating QR Codes for Apache Sling URLs" /><author><name>Chris Pilsworth</name><uri>http://www.blogger.com/profile/03221639608396248493</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.diffa.co.uk/2010/04/creating-qr-codes-for-apache-sling-urls.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QFRHw8eyp7ImA9WxNaF0g.&quot;"><id>tag:blogger.com,1999:blog-5349471866547418688.post-4028566680570606388</id><published>2009-12-02T10:50:00.003Z</published><updated>2009-12-02T10:55:15.273Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-02T10:55:15.273Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="communique" /><category scheme="http://www.blogger.com/atom/ns#" term="cq" /><category scheme="http://www.blogger.com/atom/ns#" term="templates components" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="day" /><category scheme="http://www.blogger.com/atom/ns#" term="analytics" /><category scheme="http://www.blogger.com/atom/ns#" term="components" /><title>New Google Analytics Tracking Code for CQ 5.x</title><content type="html">Today's &lt;a href="http://googlecode.blogspot.com/2009/12/google-analytics-launches-asynchronous.html"&gt;announcement from Google Analytics&lt;/a&gt; that they are providing an alternative page tracking snippet to make tracking asynchronous looks good. &amp;nbsp;Steve Souders provides a &lt;a href="http://www.stevesouders.com/blog/2009/12/01/google-analytics-goes-async/"&gt;good write up of the benefits&lt;/a&gt; of their revised approach. &lt;br /&gt;
&lt;br /&gt;
Fortunately, its very easy to upgrade any Day CQ5.x sites that use the previous incarnation of the Google tracking code from &amp;nbsp;base page component. &lt;br /&gt;
&lt;br /&gt;
There are 3 steps to updating &amp;nbsp;the existing Google analytics implementation to an asynchronous one&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Overlay the analytics.google.jsp in /apps/foundation/components/page/ with&amp;nbsp;an &lt;a href="http://gist.github.com/247092#file_analytics.google.jsp"&gt;async version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Create a &lt;a href="http://gist.github.com/247115#file_analytics.google.queue.jsp"&gt;script block&lt;/a&gt; to queue Google Analytics commands (trackPageView)&lt;/li&gt;
&lt;li&gt;Add that script block to the  section of the base template by &lt;a href="http://gist.github.com/247101#file_head.jsp"&gt;overriding head.jsp&lt;/a&gt; in the overlayed component&lt;/li&gt;
&lt;/ol&gt;More simply; that is the following 3 files added to the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;/apps/foundation/components/page/ &lt;/span&gt;folder on your CQ instance:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://gist.github.com/247092#file_analytics.google.jsp"&gt;google.analytics.jsp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gist.github.com/247115#file_analytics.google.queue.jsp"&gt;google.analytics.queue.jsp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://gist.github.com/247101#file_head.jsp"&gt;head.jsp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;This will override the one built into CQ. &amp;nbsp;If you find that it is not working out for you, then remove these files and you will go back to the original tracking code (make sure you flush any caches here too).&lt;br /&gt;
&lt;br /&gt;
You could always add as an alternative provider for analytics by setting it up as&lt;br /&gt;
&lt;span style="font-family: tahoma, verdana, Arial, sans-serif; font-size: 11px; white-space: pre;"&gt;/libs/foundation/components/page/dialog/items/items/analytics/items/provider/options/google-async&lt;/span&gt;&lt;br /&gt;
and renaming the files accordingly. &amp;nbsp;It probably wouldn't hurt to use the provider selection logic in the queue jsp also. &amp;nbsp;However, it is great to see how easy it is to override out of the box CQ functionality.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5349471866547418688-4028566680570606388?l=blog.diffa.co.uk' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Cqstuff/~4/dlF7zqbemIU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.diffa.co.uk/feeds/4028566680570606388/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.diffa.co.uk/2009/12/new-google-analytics-tracking-code-for.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5349471866547418688/posts/default/4028566680570606388?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5349471866547418688/posts/default/4028566680570606388?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Cqstuff/~3/dlF7zqbemIU/new-google-analytics-tracking-code-for.html" title="New Google Analytics Tracking Code for CQ 5.x" /><author><name>Chris Pilsworth</name><uri>http://www.blogger.com/profile/03221639608396248493</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://blog.diffa.co.uk/2009/12/new-google-analytics-tracking-code-for.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UERHYyeSp7ImA9WxNaF0g.&quot;"><id>tag:blogger.com,1999:blog-5349471866547418688.post-7388697377351529811</id><published>2009-11-17T17:40:00.006Z</published><updated>2009-12-02T10:53:25.891Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-02T10:53:25.891Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="communique" /><category scheme="http://www.blogger.com/atom/ns#" term="caching" /><category scheme="http://www.blogger.com/atom/ns#" term="cq" /><category scheme="http://www.blogger.com/atom/ns#" term="day" /><category scheme="http://www.blogger.com/atom/ns#" term="apache" /><title>Improving Day CQ Performance Using Caching</title><content type="html">Recently, we looked at how best to improve performance on one of our CQ4 extranet sites and found that although the page content was being served very fast, a lot of time was being spent by the client downloading various associated resources for that page.&amp;nbsp; In fact for every page, there were about 40 &lt;i&gt;static&lt;/i&gt; resources (png, css, js, etc) that simply didn't change between application releases, yet for every page request the browser would request each of these 40 resources and a &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;304 Not Modified&lt;/span&gt; response returned for each.&amp;nbsp; Given the fact that each of these requests was laden with SSO, load balancer &amp;amp; CQ session cookies (another problem); the overhead for this was quite great.&lt;br /&gt;
&lt;br /&gt;
In keeping with &lt;a href="http://developer.yahoo.com/performance/rules.html"&gt;good practices for speeding up websites&lt;/a&gt;, we wanted to set &lt;a href="http://developer.yahoo.com/performance/rules.html#expires"&gt;far future Expires headers&lt;/a&gt; on these static resources so that once the client populated their cache, there would no more requests for these resources.&lt;br /&gt;
The first step towards this was to add some directives to our apache httpd.conf that set the expires headers for us.&lt;br /&gt;
&lt;br /&gt;
This would add an &lt;a href="http://www.mnot.net/cache_docs/#EXPIRES"&gt;Expires header&lt;/a&gt; to each static resource&lt;b&gt; &lt;/b&gt;that was requested with a date that was 1 year in the future.&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&amp;lt;Location "cq/myapp/static"&amp;gt;&lt;br /&gt;
ExpiresDefault "access plus 1 year"&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
However, from time to time we make application releases which do change these "static" resources.&amp;nbsp; For example, any change to the site's CSS design or javascript functionality would need to be represented immediately for users of the site.&lt;br /&gt;
&lt;br /&gt;
To get around this we used the CQ4 mapper functionality to rewrite the resource URLs within the system to include the version number.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;
&lt;/div&gt;This meant changing the &lt;span style="color: #333399;"&gt;&lt;b&gt;/config/delivery/mapper_live_publish.xml&lt;/b&gt;&lt;/span&gt; file to contain the following mapping:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_4jbBMJC6xXc/SwLdHPWgAAI/AAAAAAAAAWI/3OYHwkVOY7w/s1600/mapper.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://1.bp.blogspot.com/_4jbBMJC6xXc/SwLdHPWgAAI/AAAAAAAAAWI/3OYHwkVOY7w/s400/mapper.png" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: #003366;"&gt;&lt;b&gt;&lt;map from="/apps/myapp/docroot/myapp/static" to="/myapp/static/v1.0.2/"&gt;&lt;/map&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
This adapted the URLs output from CQ templates from&lt;br /&gt;
/&lt;span style="color: #333399;"&gt;&lt;b&gt;myapp/static/js/logo.png &lt;span style="color: #38761d; font-size: small;"&gt;&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt; &lt;span style="color: #333399;"&gt;&lt;b&gt;/myapp/static/&lt;span style="color: green;"&gt;v.1.0.2&lt;/span&gt;/js/logo.png&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
All this means that a client with a populated cache will rarely request any of the static resources of the site &lt;i&gt;unless &lt;/i&gt;they change, in which case they are requested immediately.&amp;nbsp; This saves a tremendous amount of effort for the client browser, and the user experience of the site performance is greatly improved.&amp;nbsp; These simple steps gave us great performance boost for very little effort.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5349471866547418688-7388697377351529811?l=blog.diffa.co.uk' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/Cqstuff/~4/LVagdzW8ers" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.diffa.co.uk/feeds/7388697377351529811/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://blog.diffa.co.uk/2009/11/improving-day-cq-performance-using.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5349471866547418688/posts/default/7388697377351529811?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5349471866547418688/posts/default/7388697377351529811?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/Cqstuff/~3/LVagdzW8ers/improving-day-cq-performance-using.html" title="Improving Day CQ Performance Using Caching" /><author><name>Chris Pilsworth</name><uri>http://www.blogger.com/profile/03221639608396248493</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_4jbBMJC6xXc/SwLdHPWgAAI/AAAAAAAAAWI/3OYHwkVOY7w/s72-c/mapper.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://blog.diffa.co.uk/2009/11/improving-day-cq-performance-using.html</feedburner:origLink></entry></feed>

