tag:blogger.com,1999:blog-32205088750387567312024-03-18T17:00:29.598-05:00Notes, How Tos, Things To Remember, Things I'll soon forgetA collection of technical bits for me to remember and maybe help others find a solution before pulling out their hair.Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.comBlogger69125tag:blogger.com,1999:blog-3220508875038756731.post-85356008152083961702014-05-13T09:44:00.003-05:002014-05-13T09:44:52.085-05:00Please don't create tests like this in Perl<p>I just came across a test like:</p>
<script src="https://gist.github.com/lecar-red/62e903dd7a196a9d7326.js"></script>
<p>And of course, it was silently doing something/nothing/everything. I'd guess most experience Perl coders will notice that the <tt>eval</tt> will only run the test if the request doesn't throw an exception. Which might be kind of ok but there is no catch or check of the <tt>$@</tt> later. </p>
<p>If a check is added for <tt>$@</tt> later, it will make the test pattern pretty messy</p>
<p>Please don't write this type of test. Please.</p>
<p>
Instead use <a href="https://metacpan.org/pod/Test::Exception">Test::Exception</a> and drop into a sub. Something along the lines of:
</p>
<script src="https://gist.github.com/lecar-red/3930abcc6a49f7a073e1.js"></script>
This is better for a couple of reasons:
<ul>
<li>test will show some output in case of exception</li>
<li>test will stop instead of just pushing on with a bunch of mostly false error (unless the test wants to this to check bad input :)</li>
<li>test is simpler to understand (no response, give up)</li>
</ul>
<tt>__END__</tt>
Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com22tag:blogger.com,1999:blog-3220508875038756731.post-51449971036973487932014-03-23T15:17:00.000-05:002014-03-23T15:26:52.065-05:00Dancer Sessions using PSGI<p>A few weeks on #dancer channel, a user was having issues using <a href="http://metacpan.org/">Dancer::Session::PSGI</a>. I've never worked directly with <a href="http://plackperl.org/">Plack</a> besides reading the handbook and few play apps. (well a few weeks ago, I dug into <a href="https://metacpan.org/pod/Dancer::Debug">Dancer::Debug</a>.). Using both together was an intriguing problem stuck in my mind.</p>
<p>The person on the channel was reporting unreliable reading of session data and other odd behavior. As I started to dig into the problem, I realized that i need to create two apps, one pure <a href="http://plackperl.org">Plack</a> and one <a href="http://perldancer.org">Dancer</a> with middleware wrapper. I created a public repo on github with my test apps: <a href="https://github.com/lecar-red/Dancer-Plack-Session-Explore">Dancer and Plack session</a>. </p>
<p>Since, I didn't want to deal with html and wanted a bit of structure with return data, I made both test apps return JSON and have pretty simple routes</p>
<p> I started off using the documentation from <a href="https://metacpan.org/pod/Plack::Middleware::Session">Plack::Middleware::Session</a> to create this <a href="https://github.com/lecar-red/Dancer-Plack-Session-Explore/blob/master/pure_plack/bin/app.psgi">test app</a>:
<script src="https://gist.github.com/lecar-red/9326068.js"></script>
</p>
<p>Next I created a <a href="https://github.com/lecar-red/Dancer-Plack-Session-Explore/blob/master/pure_plack/bin/app.psgi">Test Dancer PSGI app</a>, which basically had a way to show value and update it. Here is the non-exciting Dancer app: <script src="https://gist.github.com/lecar-red/9326206.js"></script></p>
<p>I updated <a href="https://github.com/lecar-red/Dancer-Plack-Session-Explore/blob/master/dancer_plack_session/bin/app.pl"><tt>bin/app.pl</tt></a> to use Plack::Builder directly instead of creating a wrapper (which I'd like to try as well probably in a branch): <script src="https://gist.github.com/lecar-red/9326259.js"></script>
</p>
<p>With those all setup, I started both apps using <tt>plackup</tt> but each with slightly different command lines:
<pre>
magic-bus> plackup pure_plack/bin/app.psgi &
magic-bus> plackup -p 3000 dancer_plack_session/bin/app.pl &
</pre>
</p>
<p>I created a <a href="https://github.com/lecar-red/Dancer-Plack-Session-Explore/blob/master/bin/curl_cookie">curl_cookie</a> script to use and store cookies and verbose dump out request/response information. I needed to see what cookies where getting sent in and back.</p>
<p>After i fired up each app server, the first set of requests dumped the following:
<script src="https://gist.github.com/lecar-red/9326614.js"></script>
</p>
<p> Well that is odd. A couple quick bullets:
<ul>
<li>plack app did what was expected (the app increments counter in session after return response therefore on 2nd request being set to 1 is ok).
<li>dancer app didn't return '2' (since other app has write to the counter twice) plus it appears to be using both 'dancer.session' and 'plack_session'. This is wrong. </li>
</ul>
After I dug around a bit (since that session name seems wrong), I found two things.
<ul>
<li>A bug with Dancer::Session::Abstract: <a href="https://github.com/PerlDancer/Dancer/issues/1004">#1004</a></li>
<li>And in this case, Dancer::Session is only creating the session not retrieving (since it doesn't think there is one yet) which makes sense. (why retrieve when you are first generating the session.)</li>
</ul>
<p>
The initial session being created to the first request to Dancer not finding the existing plack session information. After that initial request, then it would pick up plack session data. The current behavior would lead to this confusing response the 2nd time from Dancer app:
<pre>
{
"visits" : 2
}
</pre>
<p>I fixed up <a href="">Dancer::Session::Abstract</a> to use 'plack_session' cookie and that resolved the session not getting read on initial request. </p>
<p>A bit unexpectedly, I see that Dancer is setting cookie with different session id than PSGI. PSGI includes its own session cookie. This is expected since the Plack middleware runs after Dancer (think of the onion from handbook: <img src="https://raw.github.com/miyagawa/plack-handbook/master/images/pylons_as_onion.png"></img>). </p>
<p>Here is example of response made to Dancer app:<script src="https://gist.github.com/lecar-red/9347395.js"></script></p>
<p>In the end its working now. Dancer is able to pull in session information from Plack session but its still a bit messy. I'm not sure if multiple session cookies is considered a bug or not. I think it might be best to have Dancer not do any cookie stuff and only use the session data if its available in the environment but looking over the Dancer session code, this doesn't look straightforward w/out major changes to core Dancer code. </p>
<p>Any ideas out there?</p>
<tt>__END__</tt>Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com3tag:blogger.com,1999:blog-3220508875038756731.post-6927754284106251932014-03-12T08:44:00.000-05:002014-03-23T15:18:42.351-05:00Template Toolkit Debugging inside of Perl Dancer<p>
The other day someone was asking how to enable <a href="http://www.template-toolkit.org/index.html">Template Toolkit</a> debugging inside of <a href="http://perldancer.org">Perl Dancer</a> in the <tt>#dancer</tt> IRC channel, it seemed like a good time for a write up.</p>
<p>
The template engine configuration directive supports passing through various options like <tt>start_tag</tt> and <tt>stop_tag</tt> as explained in <a href="https://metacpan.org/pod/Dancer::Template::TemplateToolkit">Dancer::Template::TemplateToolkit</a> POD. And alludes to being able to pass other options.
</p>
<h3>How</h3>
<p> To pass TT options like those found in <a href="http://www.template-toolkit.org/docs/modules/Template/Constants.html#section_EXPORTABLE_TAG_SETS">Template::Constants</a>, there must be a <tt>DEBUG</tt> section in <tt>engines -> template_toolkit</tt>, usually found in <tt>config.yml</tt>.
</p>
<h3>Example Snippet</h3>
<p> Here is an example:<script src="https://gist.github.com/lecar-red/9506977.js"></script></p>
<h3>A few notes</h3>
<ul>
<li>Remove leading <tt>DEBUG_</tt> from TT constants. The option <tt>DEBUG_PLUGINS</tt> becomes <tt>plugins</tt>.</li>
<li>Multiple options can be separated with a comma. Example:<tt>DEBUG: "provider,plugins"</tt>.
<li>Be warned, some of these options can lead to tons of information :) </li>
</ul>
<tt>__END__</tt>
Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com5tag:blogger.com,1999:blog-3220508875038756731.post-59631702431935699082013-11-04T12:57:00.003-06:002013-11-04T12:57:47.666-06:00What's installed on my ec2<h2>
What's installed on my ec2?</h2>
<div>
I swear between debian/ubuntu/mac os x/irix (well not anymore), I can never remember how to list installed packages on my ec2. </div>
<div>
<br /></div>
<div>
Here is is:<br />
<br /></div>
<div>
<pre> sudo yum list installed
</pre>
<br />
Plus or minus <tt>sudo</tt> depending on who you are. For once, the command is what i'd expect.<br />
<br /></div>
<tt>__END__</tt>
Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com12tag:blogger.com,1999:blog-3220508875038756731.post-58868213437316959202013-09-24T15:05:00.001-05:002013-09-24T15:06:00.045-05:00Toying around with backbone.js<h2>
Toying around with Backbone.js</h2>
<div>
At $work, we've been using more and more <a href="http://backbonejs.org/">backbone.js</a> to create a more responsive front end experience and help the dev team manage the code.</div>
<div>
<br /></div>
<div>
I like backbone.js and find that its it is very helpful to seperate data and code on the client. But I've found that it challenges me to think in different ways.</div>
<div>
<br /></div>
<div>
I find it helpful to create an app so I did :)</div>
<div>
<br /></div>
<h3>
Introducing Brewers Radio Finder</h3>
<div>
Over the years, i've often driven between Milwaukee and St. Paul, MN. While on the drive, there are areas of the state where finding the close Brewer's radio station is tough and figuring out which station is the closest to you is difficult when looking at the map from <a href="http://milwaukee.brewers.mlb.com/mil/schedule/radio_network.jsp">Brewers Radio network</a>. Am I currently closer to Reedsburg or Portage?</div>
<div>
<br /></div>
<div>
The app is pretty simple, you can type in or give it your current location and it will show the 3 closest Brewers radio stations to you. </div>
<div>
<br /></div>
<div>
You can check it out at <a href="http://radiofinder.leecarmichael.com/">http://radiofinder.leecarmichael.com/</a>. </div>
<div>
<br /></div>
<div>
If anyone is interested I'd be willing to make the code public on github. I didn't do it by default since I had to do some geocoding and storage of the station locations and i'm not sure if i can share that (even though its public). And i haven't dropped a license in there (not sure which one to do).</div>
<div>
<br />
The app is only a few parts:</div>
<div>
<ul>
<li>backbonejs + <a href="http://getbootstrap.com/2.3.2/">bootstrap</a> front end </li>
<li><a href="http://perldancer.org/">Perl Dancer </a>backend (serving JSON to front end and some initial templates)</li>
<li>MySQL Database</li>
<li>Use of Google's geocoding library/service (for initial coding of stations) and <a href="https://metacpan.org/module/GIS::Distance">GIS::Distance</a></li>
</ul>
<div>
Using Dancer with backbone is very slick. The Dancer json (de)serialization setup is very elegant. Basically set it in the config and you can return data structures in 'ajax' routes and it does its (de)serialization magic. Pretty nice way to hide that complexity.</div>
<div>
<br /></div>
<div>
As a full start from scratch project in backbonejs that didn't involve todo items. It was a good learning experience. I ran into some mental issues using templates w/ widgets that didn't have a model but otherwise it went pretty well. I had some trouble with routes that opened and closed widgets ('about' dialog was a bit of a fight and still isn't perfect). And I still haven't got my mind around using a view and route with something that didn't have a model (the search inputs). I felt like making it a model was a bit of extra cruft that didn't add value (but i bet it might be helpful as the app grew). There are areas, that i'll revisit when i get some time.</div>
</div>
<div>
<br /></div>
<div>
A few future things that I'm working on:</div>
<div>
<ul>
<li>Displaying current location and stations on a map (this is pretty close)</li>
<li>Fixing a few display issues with the responsive layout on smaller screens</li>
<li>More unit tests for "live" dev instance</li>
</ul>
<div>
That's all for now.</div>
<div>
<br /></div>
<div>
<span style="font-family: Courier New, Courier, monospace;">__END__</span></div>
<div>
<br /></div>
</div>
Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com5tag:blogger.com,1999:blog-3220508875038756731.post-89539372012045809662013-06-25T11:47:00.000-05:002013-06-25T11:47:14.372-05:00backbonejs' alteration of ajax handler parameters As I spend time learning <a href="http://backbonejs.org/">Backbone</a> I've found some unexpected things (to me probably not to others). Today I found that even though <a href="http://backbonejs.org/">Backbone</a> fetch allows you to pass in typical jQuery <a href="http://api.jquery.com/jQuery.ajax/">ajax</a> options (like success or error handlers), it will alter what parameters are passed back to those handlers.<br />
<br />
<h4>
In jQuery</h4>
<div>
<br /></div>
Here is an example of plain jane ajax call (in older style jQuery before renaming of events):<br />
<br />
<script src="https://gist.github.com/lecar-red/5859879.js"></script>
<br />
<br />
<h4>
In backbone handler</h4>
In backbone <a href="http://backbonejs.org/#Collection-fetch">fetch</a> changes up what you receive. It is nicely stated in that section:
<br />
<blockquote class="tr_bq">
<span style="background-color: #f4f4f4; font-family: 'Helvetica Neue', Helvetica, Arial; font-size: 14px; line-height: 22px;">The </span><b style="background-color: #f4f4f4; font-family: 'Helvetica Neue', Helvetica, Arial; font-size: 14px; line-height: 22px;">options</b><span style="background-color: #f4f4f4; font-family: 'Helvetica Neue', Helvetica, Arial; font-size: 14px; line-height: 22px;"> hash takes </span><tt style="background-color: white; border: 1px solid rgb(221, 221, 221); font-family: Monaco, Consolas, 'Lucida Console', monospace; font-size: 12px; line-height: 18px; padding: 0px 3px; zoom: 1;">success</tt><span style="background-color: #f4f4f4; font-family: 'Helvetica Neue', Helvetica, Arial; font-size: 14px; line-height: 22px;"> and </span><tt style="background-color: white; border: 1px solid rgb(221, 221, 221); font-family: Monaco, Consolas, 'Lucida Console', monospace; font-size: 12px; line-height: 18px; padding: 0px 3px; zoom: 1;">error</tt><span style="background-color: #f4f4f4; font-family: 'Helvetica Neue', Helvetica, Arial; font-size: 14px; line-height: 22px;"> callbacks which will both be passed </span><tt style="background-color: white; border: 1px solid rgb(221, 221, 221); font-family: Monaco, Consolas, 'Lucida Console', monospace; font-size: 12px; line-height: 18px; padding: 0px 3px; zoom: 1;">(collection, response, options)</tt><span style="background-color: #f4f4f4; font-family: 'Helvetica Neue', Helvetica, Arial; font-size: 14px; line-height: 22px;"> as arguments.</span></blockquote>
I only read that like 3 times before i actually saw that note :)<br />
<br />
Here is an example of backbone success handler:<br />
<script src="https://gist.github.com/lecar-red/5859954.js"></script>
<br />
The one really nice part of the different parameters is that backbone gives you objects instead of raw-ish data. This means if you need to create two different models (or collections) from the same call, you can pass it directly into the model 'set' method. (see line 13).<br />
<br />
Now the question is the best way to handle a situation where the backend server returns multiple models in a response. In this case, I chose to pull them out in a custom ajax handler and update one collection to use specific part of the return data. But I could have been persuaded to create custom ajax call to retrieve and then create each model/collection separately. This might be a good place to write out some examples, code snippets and write about what I learn. I suspect that it will vary like most things :)<br />
<br />
<tt>__END__</tt>Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com1tag:blogger.com,1999:blog-3220508875038756731.post-77531019775447271522013-03-28T16:27:00.000-05:002013-03-28T16:30:38.417-05:00Altering TT's INCLUDE_PATH in Dancer with Custom View <h2>Altering Template Toolkit's INCLUDE_PATH in Dancer</h2>
<p>This just came up on <a href="http://perldancer.org">Dancer</a>'s mailing list and I've been sitting on this code (and post) for a few months since the project I was working on didn't need it.</p>
<p>Basically Dancer's Template Toolkit view requires you completely alter it or use the default setting.
This is pain if you just want to add to it but not have to manage all the changes. </p>
<p>I created a new TT view class, to get inside the TT <tt>init</tt> and add to the <tt>INCLUDE_PATH</tt> instead of replace it. The code was a bit involved and I extended it a bit by adding a <tt>customization</tt> flag in each environment (if needed).</p>
<h2>On to the code</h2>
<p>Here is the code and config that i used to do this
<script src="https://gist.github.com/lecar-red/5266904.js"></script>
<h3>Disclaimer</h3>
<p> I don't recall all the other issues that i ran into while doing this. It was over 6 months ago but post questions if you have them</p>
<tt>__END__</tt>Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com3tag:blogger.com,1999:blog-3220508875038756731.post-54351847660304198522013-01-25T08:40:00.000-06:002013-05-24T15:54:41.083-05:00Dancer + Nginx + FastCGI<h3>Bring together the parts</h3>
<p>
I was able to find complete documentation on running <a href="http://perldancer.org/">dancer</a> with <a href="http://www.nginx.org">nginx</a> using FastCGI. In the dancer <a href="https://metacpan.org/module/XSAWYERX/Dancer-1.3110/lib/Dancer/Deployment.pod">deployment</a> it discusses using Apache and fastcgi or <a href="http://www.nginx.org">nginx</a> with proxy. Often, using <a href="http://www.nginx.org">nginx</a> as proxy to starman(or some other plack webserver) is probably the right thing. But sometimes using fastcgi is good idea too :) I'm running some benchmarks but it seems like memory usage is a bit smaller with FCGI but I still need to do more digging on this.</p>
<h3>Make it so</h3>
<p>Lets get all the parts install and then configure them</p>
<h4>Install the Parts</h4>
<p><strong>Note:</strong> These parts will be very dependent on your system. I'm assuming a debian/ubuntu system below.</p>
<p>
First you need to have nginx and dancer installed. For <a href="http://www.nginx.org">nginx</a> i would recommend doing something like:</p>
<pre>apt-get install nginx</pre>
<p>or building and install from source. </p>
<p>
Next, install need Perl modules:</p>
<p><strong>cpanm + Dancer's Makefile.PL</strong></p>
<p> I like to install using Dancer's app generated <tt>Makefile.PL</tt> along with <tt><a href="https://metacpan.org/module/cpanm">cpanm</a></tt> to manage Perl dependencies.</p>
<p>Setup your <tt>Makefile.PL</tt>:
<pre>
use strict;
use warnings;
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'AppName',
AUTHOR => q{your name<email>},
VERSION_FROM => 'lib/ExApp.pm',
ABSTRACT => 'example dancer app',
($ExtUtils::MakeMaker::VERSION >= 6.3002
? ('LICENSE'=> 'perl')
: ()),
PL_FILES => {},
PREREQ_PM => {
'Test::More' => 0,
'YAML' => 0,
'Dancer' => 1.3095,
# required to run in fcgi mode
'Plack' => 0,
'FCGI' => 0,
'FCGI::ProcManager' => 0,
# application specific
'Template' => 0,
'Dancer::Plugin::Database' => 0,
'DateTime' => 0,
'DateTime::Format::MySQL' => 0,
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'example-app-name-*' },
);
</pre>
</p>
<p>You can do: <tt>cpanm --installdeps .</tt></p>
<p><strong>Other options....</strong></p>
<pre>cpanm Dancer Plack FCGI FCGI::ProcManager</pre>
Or<br />
<pre>cpan install Dancer Plack FCGI FCGI::ProcManager</pre>
<h4>Configure nginx</h4>
<p>Now, lets configure <a href="http://www.nginx.org">nginx</a> nginx.conf. It isn't a large change from <a href="http://wiki.nginx.org/NginxFcgiExample">http://wiki.nginx.org/NginxFcgiExample</a>. There are three main changes below.
<ol>
<li>Configure nginx to serve the static content (in dev this isn't a huge deal but in production you will save some major time and resources).</li>
<li>Plack's FCGI handler requires <tt>SCRIPT_NAME</tt> to be empty. I'm not sure why but i'm sure its a very smart security thing or due the fact that it isn't using a dispatch script.</li>
<li>Plack's FCGI handler uses <tt>PATH_INFO</tt> and needs it to be configured. See:<tt>set $path_info $uri;</tt> line</li>
</ol>
</p>
<p><strong>Example Configuration</strong>:
<pre>
server {
listen 80;
server_name fastcgi-example.leecarmichael.com;
root /home/user/dancer_app/public;
access_log logs/fcgi-example.access.log main;
# serve static content from nginx not dancer
location = /favicon.ico {
}
location /images {
}
location /js {
}
location /css {
}
# serve all other stuff from appserver
location / {
set $script "";
set $path_info $uri;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $request_filename;
# plack FCGI handler requires these changes
fastcgi_param SCRIPT_NAME $script;
fastcgi_param PATH_INFO $path_info;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
# can use port as well
fastcgi_pass unix:/tmp/myapp-fcgi.sock;
}
}
</pre>
<h4>Start, Restart and Go</h4>
<p>Start or restart nginx.</p>
<p>On debian: <tt>/etc/init.d/nginx restart</tt></p>
Startup your app server (make sure you'ave changed to /home/user/dancer_app):
<pre>
plackup -E development -s FCGI -a bin/app.pl -S /tmp/myapp-fcgi.sock -D
</pre>
<p>See <a href="https://metacpan.org/module/plackup">plackup</a> for all the options. I added <tt>-D</tt> and usually add <tt>--error-log</tt> but a start up script is probably a better long term choice</p>
<p>After writing all this, i stumbled across a pretty helpful reference in the <a href="http://plackperl.org">Plack</a> docs on <a href="https://metacpan.org/module/Plack::Handler::FCGI">Plack::Handler::FCGI</a> which replicates the fast-cgi nginx.conf above.
<p><tt>__END__</tt></p>Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com0tag:blogger.com,1999:blog-3220508875038756731.post-17722221496960431912012-10-07T10:53:00.001-05:002012-10-17T14:53:01.558-05:00Changing Dancer::Plugin::Ajax's content type<p>
Dancer does lots of great things. It has a nice clean way to define routes to handle AJAX routes using the plugin <a href="https://metacpan.org/module/Dancer::Plugin::Ajax">Dancer::Plugin::Ajax</a>.
</p>
<p>
ajax routes are defined in a clear way:
<pre class="brush: perl;">
ajax '/stuff' => sub {
# do work and return
};
</pre>
</p>
<p>This plugin technique allows for clear way to separate between ajax and other types of actions for the same route.
<pre class="brush: perl;">
ajax '/stuff' => sub {
# do ajax-y stuff here
};
get '/stuff' => sub {
# handle html response
};
</pre></p>
<p>
Unfortunately, the one negative with <a href="https://metacpan.org/module/Dancer::Plugin::Ajax">Dancer::Plugin::Ajax</a> is that is assumes all responses will be XML.
</p>
<p> A quick fix is to manually set the <a href="https://metacpan.org/module/Dancer#content_type">content type</a> in each ajax handler.
<pre class="brush: perl;">
ajax '/stuff' => sub {
content_type('application/json');
# do work
};
</pre>
or add set it as a general option in your main before hook or in each prefix route handler like:<pre class="brush: perl;">
package WebApp;
hook before => sub {
if ( request->is_ajax ) {
content_type('application/json');
}
};
</pre>
</p>
<p>Both of these solutions feel kind of clunky due to the level of duplication. Our app returns JSON or HTML snippets and never uses XML. This redundancy in code led me to creating a patch for <a href="https://github.com/sukria/Dancer">Dancer</a> that allows default Ajax content_type to be set in the config file. (see <a href="https://github.com/sukria/Dancer/issues/840">issue 840</a>).
</p>
<p>
Config Example: <pre>
plugins:
ajax:
content_type: 'application/json'
</pre>
</p>
<tt>__END__</tt>
Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com0tag:blogger.com,1999:blog-3220508875038756731.post-67084782231144366912012-09-25T15:27:00.001-05:002012-10-17T15:01:46.856-05:00Blueberry (Image slider) and YouTube video working in harmony<h3>
Do what needs to be done</h3>
We recently launched a new home page and the designed used a responsive image slider called <a href="http://marktyrrell.com/labs/blueberry/">Blueberry</a>. Well there were a few issues with navigation and I needed to be able to make sure to have the slider start to slide automatically and then stop while playing a YouTube video.<br />
<br />
I need to fix the problem with navigation causing a speed up and unreliable timing while showing slides. I extended it to support being stopped and started. Since the project appears to be on hiatus (no changes in a year even though it has a few <a href="https://github.com/marktuk/Blueberry/issues?state=open">github issues</a>), I forked it on <a href="https://github.com/lecar-red/Blueberry">github</a> to fix the event issue and add the ability to stop/start slider.<br />
<h3>
Blueberry + YouTube sitting in a tree</h3>
I found it to be a bit of challenge to update the site to support pausing the image slider when the YouTube video that is linked in through iframe started and stop being played. I found to get the correct permissions and callback into the player I needed to use the <a href="https://developers.google.com/youtube/iframe_api_reference">YouTube iFrame Player API</a>. (thank you Google)<br />
<br />
To setup the Blueberry slider, there is some basic html<br />
(and css see: <a href="https://github.com/lecar-red/Blueberry/blob/master/index.html">https://github.com/lecar-red/Blueberry/blob/master/index.html</a>).<br />
<br />
Here is a blurb of html<br />
<br />
<iframe src="http://pastebin.com/embed_iframe.php?i=ZnJckZFe" style="border:none;width:100%; height: 480px;"></iframe>
<br />
<div>
Next is the Javascript code to setup the slider:</div>
<div>
<br /></div>
<div>
<pre class="brush: js;">$(function() {
$('.blueberry').blueberry({hoverpause: true});
});
</pre>
<div>
<span style="font-family: inherit;"><br /></span>
<span style="font-family: inherit;">Now the image slider will start up showing images (and YouTube video).</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">Next comes dropping in the YouTube API, plus adding in the callback controls. The following snippet of JS code contains all of the code needed to start and stop slider when video is played and stopped by user. I'll explain it in the following sections.</span></div>
<br />
<iframe src="http://pastebin.com/embed_iframe.php?i=GEM4p9kf" style="border:none;width:100%; height: 700px;"></iframe>
<br />
<div>
1. The first closure is to load the youtube js API script. </div>
<div>
<br /></div>
<div>
2. <span style="font-family: Courier New, Courier, monospace;">onPlayerStateChange</span><span style="font-family: inherit;"> is a function that is called each time the player changes state, it is passed an event object with what type of change occurred see the details in the <a href="https://developers.google.com/youtube/iframe_api_reference#Events">YouTube API Docs</a>. </span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">2a. This code will pause the slider when the video is playing (when event type is PLAYING). </span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">2b. When data event is type is PAUSED or ENDED restart slider. </span><span style="font-family: inherit;">The Blueberry slider's code will restart the timeout interval at start and stop so it won't necessarily change right away. I could see expanding this code to only start when the video was ended in our case it wasn't required.</span></div>
<div>
<span style="font-family: inherit;"><br /></span></div>
<div>
<span style="font-family: inherit;">3. Create new API object and save player to global object (this could be done a bit cleaner by storing in a global object or something else - </span>exercise<span style="font-family: inherit;"> for the reader :)</span></div>
<div>
<br />
Once I waded through the various APIs, browser cross domain restrictions and code patches. The end solution wasn't too bad. The above YouTube API code could be used with any slider or <a href="http://twitter.github.com/bootstrap/javascript.html#carousel">carousel</a>.<br />
<br /></div>
<tt>__END__</tt>
</div>
Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com1tag:blogger.com,1999:blog-3220508875038756731.post-10280775008108924222012-08-25T08:39:00.000-05:002012-08-25T08:39:03.778-05:00Template Tooltip Tip #1<b><span style="font-size: large;"> A bit of background</span></b><br />
<br />
<a href="http://www.template-toolkit.org/">Template toolkit</a> is a powerful and mature <a href="http://www.perl.org/">Perl</a> based templating engine. It is designed to be output format agnostic and used (or able to be used) with most of the Perl based Web application frameworks like <a href="http://perldancer.org/">Dancer</a>, <a href="https://metacpan.org/module/Catalyst::View::TT">Catalyst</a> and <a href="https://metacpan.org/module/CGI::Application::Plugin::TT">CGI::Application</a>. <br />
<br />
<span style="font-size: large;"><b>TT Tip #1 - Simple html attribute macro</b></span><br />
<br />
In this tip, i'll combine using a TT <a href="http://www.template-toolkit.org/docs/manual/Directives.html#section_MACRO">macro</a> with <a href="http://www.template-toolkit.org/docs/manual/Plugins.html#section_HTML">HTML plugin</a> to create a simple macro to add <tt>active</tt> class to html element.
<br />
<br />
<b>code</b><br />
<br />
TT code: (put in top of template or shared TT file pulled in with PROCESS or INCLUDE)<br />
<pre>[% USE HTML %]
</pre>
<pre>[% MACRO active GET HTML.attributes( 'class' => 'active' ) %]</pre>
<br />
Usage in a template:<br />
<pre></pre>
<pre><ul id="navBar">
<li [% active IF page.name == 'home' %]>Home</li>
<li [% active IF page.name == 'about' %]>about</li>
<li [% active IF page.name == 'contact' %]>contact</li>
</ul>
</pre>
<br />
In this case, when <tt>page.name</tt> matches then macro will drop in <tt>class="active"</tt>. Simple but much more readable then a bunch of statements like:<br />
<pre>[% IF page.name == 'home' %]class="active"[% END %]
</pre>
<br />
I'm sure there are more elegant ways to create menu bar or breadcrumbs but this is intended to give you a feel of using a TT <a href="http://www.template-toolkit.org/docs/manual/Directives.html#section_MACRO">macro</a>.<br />
<br />
A <a href="http://www.template-toolkit.org/docs/manual/Directives.html#section_BLOCK">block</a> with a process or include could be used but that ends up with template code like <tt>[% PROCESS active IF page.name == 'home' %]</tt> but i think the macro call is clearer with less directive line noise.<br />
<br />
<tt>__END__</tt>Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com0tag:blogger.com,1999:blog-3220508875038756731.post-25912022474607211412012-07-12T17:21:00.000-05:002012-07-12T17:23:50.467-05:005 minute guide to using JS PubSub and Noty<h3>5 minute guide to using PubSubJS and Noty</h3>
<p>
A little background, Publish/Subscribe is a design pattern for decoupling components in software (or i guess anywhere in the world). The basic idea is that one thing publishes information to a well known place and another subscribes to it. There is lots of good writing about it out there, check it out on <a href="http://en.wikipedia.org/wiki/Publish/subscribe">Wikipedia</a>.</p>
<p> In my situation we wanted to display page level notifications. I would consider these to be messages that aren't tied to a web widget or element (like a message in a form). Page level notifications can increase the usability of your application (too many or badly placed one can reduce it :)</p>
<div>
This tutorial will show you a simple way to create a subscriber that publishes messages to the browser using <a href="http://needim.github.com/noty/">noty</a>. And uses <a href="https://github.com/mroderick/PubSubJS">PubSubJS</a> to handle the Publish/Subscribe work.
</div>
<h4>The tools</h4>
<div>You will need a few things for this tutorial.</div>
<ul>
<li><a href="http://www.jquery.com/">jQuery</a></li>
<li><a href="https://github.com/mroderick/PubSubJS">PubSubJS</a></li>
<li><a href="http://needim.github.com/noty/">noty - jquery plugin</a></li>
</ul>
<div>Grab them and download, or you can try this shell snippet:</div>
<div>
<pre class="brushes: bash;"> mkdir js
wget https://raw.github.com/needim/noty/master/js/jquery.noty.js
wget https://raw.github.com/mroderick/PubSubJS/master/src/pubsub.js
cd ..
mkdir css
wget https://raw.github.com/needim/noty/master/css/jquery.noty.css
wget https://raw.github.com/needim/noty/master/css/noty_theme_twitter.css</pre>
</div>
<h4>The whys</h4>
<div>
In our application, we needed to publish messages in the top of the application page. We use bootstrap and the <a href="http://needim.github.com/noty/">noty</a> plugin provided a perfect fit since it supports top (or anywhere else) notifications plus it matched the style of bootstrap alerts. It has an active developer as well.</div>
<div>
There are many (many, many, many) Javascript PubSub implementations but <a href="https://github.com/mroderick/PubSubJS">PubSubJS</a> seems the most lively and felt the most mature. In reality there are many good ones.</div>
<h3>Getting Started</h3>
<p>You will need to include PubSub and noty in your page with standard script and style html tags. </p>
<p>Also, all the code I"m including below should be put in a jQuery on load page closure. Example:
<pre class="brush: js;">
$(function() {
// code goes here
});
</pre>
<h4>Setup of noty options</h4>
<p> First lets setup our noty library to display messages. After including the libraries in your page (using standard css and js html tags), In a page load closure set the following:
<div>
noty allows setup of most options when making the explicity call to the library:</div>
<div>
<br /></div>
<pre class="brush: js;">
$.noty({
text: 'noty - a jquery notification library!',
theme: 'noty_theme_twitter'
});
</pre>
<br />
But this will become a pain, esp since we want all the notifications to use the same theme anyway. Nicely noty gives a way to setup all the options before creating individual notfications.<br />
<br />
In the end, we only really need to set two default options:<br />
<ul>
<li>theme - set everything to use the twitter option</li>
<li>closeButton - show button to close notification</li>
</ul>
Global Setup:<pre class="brush: js;">
$.noty.defaultOptions.theme = 'noty_theme_twitter';
$.noty.defaultOptions.closeButton = true;
</pre>
<p> You can see all the options at <a href="http://needim.github.com/noty/#options">noty docs</a>.</p>
<h5> Using noty</h5>
<p> Creating a noty is pretty quick and simple but before I drop the code in later in a subscriber, it seems best show and example an example now.</p>
Example:<pre class="brush: js;">
$.noty({ type: 'error', text: 'Arghhh getting eaten by zombie!' });
</pre>
<p> This will create a nice little alert at the top of your page. <tt>type</tt> parameter is used to figure what type of notification (and formatting to show) to show. <tt>text</tt> is what is shown to the user. </p>
<h4>Setup of PubSubJS and message queues</h4>
<p> Using pubsub requires two functions. A subscriber (that listens and acts on messages in a queue) and a publisher which sends a message (really just a data structure) to a queue. I guess there is a third item to setup but its more or less implicit that is the queue. In this situation the queue is created when either a publisher or subscriber specifics a queue. </p>
<p> The PubSubJS docs recommend using a variable name for a given queue name. I think that is often a good idea but in this case I don't plan on doing it :)</p>
<h5>Subscriber</h5>
<p> Since we have a pretty good idea of what the subscriber needs to do. I think creating the subscriber first makes sense.</p>
<p> The subscriber will need to listen on a queue and display each message coming in. In this situation, we want to be able to pass an array of messages. </p>
Data format: <pre class="brush: js;">
[
{ 'type': msgtype, 'text': msgtext },
... more if needed ...
]
</pre>
Example:
<pre class="brush: js;">
PubSub.subscribe( 'site.messages', function( topic, msgs ) {
var msgs = $.isArray(msgs) ? msgs : [ msgs ];
$.each( msgs, function() { $.noty( this ) } );
});
</pre>
<p> that is it. That will listen to subscriber and show each message coming in. As I look at the code (after a few weeks), I added an auto convert <tt>msgs</tt> to an array. </p>
<h5>Publisher</h5>
<p>The publisher will be embedded in some other globber of code. I've used this type of call in ajax form handlers, click events and even some code that runs at page load time to show messages generated when the pages are produced from the server. </p>
Example:<pre class="brush: js;">
PubSub.publish( 'site.messages',
{ 'type': "success", 'text': 'Successfully updated thingy' });
</pre>
<h5>Use inside of events</h5>
<p>I find it helpful to see an example of this in use i real-ish code. Here is a boring click handler for a button (or anything really) that will show a message</p>
<pre class="brush: js;">
$('body').on('click', '.show-message', function(e) {
PubSub.publish( 'site.message',
{ type: 'warning', "Watch for falling rocks!' });
return false;
});
</pre>
<p>I hope you found some use in this guide, please let me know if you have any comments or questions</p>
<p>__END__</p>Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com1tag:blogger.com,1999:blog-3220508875038756731.post-62304638185170973802012-07-03T14:26:00.000-05:002012-07-03T14:28:16.577-05:00Using (Test::?)WWW::Mechanize to test AJAX calls<h3>
Test::WWW::Mechanize + AJAX = Love?</h3>
<div>
As we use more and more client side driven forms, testing in a standard way for unit/expanded unit tests becomes more and more difficult.</div>
<div>
<br /></div>
<div>
I've been in the process of creating more use case tests so as underlying components in our system changes those non-web people can verify that their changes don't break the webapp. </div>
<div>
<br /></div>
<div>
This is often our REST API but can apply to DB changes or modules updates.</div>
<div>
<br /></div>
<div>
I've found this basic code block to work pretty well at using <a href="https://metacpan.org/module/Test::WWW::Mechanize">Test::WWW::Mechanize</a> to simulate the situations where there are elements that use client side forms. (AJAX! But really AJAJ since we use JSON instead of XML).</div>
<div>
<br /></div>
<div>
<br /></div>
<pre class="brush: perl;">BEGIN {
use Test::More;
use Test::Exception;
use Test::WWW::Mechanize;
use JSON;
}
#
# setup test data or load it from db
#
#
# in this test, i login w/ many page, jump to account page
# then run ajax form and check json results
#
{
diag "Running login and create user test";
my $mech = Test::WWW::Mechanize->new;
# base is defined above :)
$mech->get_ok(sprintf('%s%s', $base, '/user/login'));
# login
$mech->submit_form_ok({
#might be best to add name to enroll form
form_number => 1,
fields => {
email => $test_email,
password => $test_password,
}
}, '/user/login');
# goto next page
$mech->get_ok( sprintf( '%s%s', $base, '/users' ));
# in my case the form doesn't exist on the page until js
# code is run so we have to pretend to know it
# pretend to be ajax client
$mech->add_header( 'X-Requested-With' => 'XMLHttpRequest' );
# form url
my $create_url = sprintf '%s%s', $base, '/user/create';
#
# this is a failure case
#
my $resp = $mech->post( $create_url, $bad_user_params );
lives_ok { $jresp = from_json( $mech->content ) }
'invalid user - json returned';
# check response for errors and specific fields, YMMV
is scalar @{$jresp->{errors}}, 5, 'missing fields';
ok grep { qr/confirm_email/ } @{ $jresp->{errors} },
'errors - confirm_email';
}
</pre>
<br />
Its a bit of a long example but the real magic happens with adding the header to the request with <tt>$mech->add_header</tt> line, you will probably need to go back to standard requests by removing that header with <tt>$mech->delete_header('X-Requested-With').</tt><br />
<br />
Next series of my tests will be doing this with forms that exist in the page. I suspect that it may take a bit of fiddle with WWW::Mech.<br />
<br />
__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com3tag:blogger.com,1999:blog-3220508875038756731.post-77417019573229568512012-05-30T15:06:00.000-05:002012-05-30T15:09:26.316-05:00bootstrap popover responsive layoutAs i was working on solving some problems with <a href="http://twitter.github.com/bootstrap/">Bootstrap's</a> popovers and our responsive webapp design, I came up w/ this simple snippet to change the location of the popover using <tt>placement</tt> option using the current window's width.<br />
<br />
Example of how to set placement using function:<br />
<br />
<pre class="brush: js;">$('.show-details').popover({
placement: function(tip, ele) {
var width = $(window).width();
return width >= 975 ? 'left' : ( width < 600 ? 'top' : 'right' );
}
});
</pre>
<br />
In the long run i think it would make more sense to setup those location options in a map or site wide setting object along the lines of:
<br />
<br />
<pre class="brush: js;">var superapp = {};
superapp.popover_layouts = {
full: { width: 975, pos: 'left'},
mid: { width: 600: pos: 'right'},
micro: { width: 320: pos: 'top' }
};
function determine_placement(tip, ele) {
var width = $(window).width();
var map = superapp.popover_layouts;
.... TBD .... :)
}
</pre>
<br />
I'm not sure I'm crazy about that. I wonder if using media queries is a better option. In our situation we will need to adjust the class on each popover.<br />
<br />
Probably need a bit more thought on it all.<br />
<br />
__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com1tag:blogger.com,1999:blog-3220508875038756731.post-90589943086912594682012-05-21T07:05:00.002-05:002012-05-21T07:05:59.490-05:00Bootstrap popover with function driven contentIn another <a href="http://blog.leecarmichael.com/2012/03/bootstrap-by-twitter-loading-in-page.html">post</a>, I wrote about a technique that allowed loading content into a popover using a function.
<p>Its a great feature but I found one gotcha. If you set anything in the <tt>data-content</tt> attribute on the trigger element, the content will not be loaded with the function.
</p>
<p>Maybe I should say that again for myself, If you want to use <tt>content: function() {...} </tt> your element must not include <tt>data-content</tt></p>
Don't use:
<pre class="brush: html;"><a id="mypopover" href="#"
data-content="will not run function"> Label </a>
</pre>
Use:
<pre class="brush: html;"><a id="mypopover" href="#" > Label </a>
</pre>
<tt>__END__</tt>Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com0tag:blogger.com,1999:blog-3220508875038756731.post-43552294935703514662012-04-05T10:58:00.000-05:002012-04-05T10:58:23.488-05:00BootstrapX clickover<h2>Birth</h2><br />
The last few weeks, i've been pushing <a href="http://twitter.github.com/bootstrap">Bootstrap</a> in various directions. Most of the time, its being hacking around Popovers. Our current design uses Popovers with forms. It provides a very nice balance between in page action and more subtle interruption to viewing the page than a modal.<br />
<br />
Over the last few weeks, I've found a few quirks with using <a href="http://twitter.github.com/bootstrap/javascript.html#popovers">Popover's</a> trigger action of 'focus'. This works fine with forms but on Chrome and Safari 'focus' events are supported <a href="http://www.quirksmode.org/dom/events/blurfocus.html">incompletely</a>. In addition to that varied support we have a few other needs that inspired a new <a href="http://twitter.github.com/bootstrap">Bootstrap</a> extension. <b>BootstrapX - Clickover</b>.<br />
<br />
Our requirements are:<br />
<ul> <li>Click button/link/icon to toggle display of popover content</li>
<li>Option to click 'away' from popover to close</li>
<li>Ability to have 'popover' autoclose after some amount of time</li>
<li>Option to have element inside of popover hide it</li>
</ul><br />
I suspect, in the future, it will need to only auto close when user's mouse leaves the clickover. <br />
<br />
Out of these needs spawed the library: <a href="https://github.com/lecar-red/bootstrapx-clickover">bootstrapx-clickover</a>.<br />
<br />
<h2>Usage Examples</h2><br />
<h3>Basic</h3><br />
html:<pre class="brush: html;"><button rel="clickover"
data-content="Show something here.
<button data-dismiss='clickover'
>Close Clickover</button>"
>Show clickover</button>
</pre><br />
javascript:<br />
<pre class="brush:js;">// load click overs using 'rel' attribute
$('[rel="clickover"]').clickover();
</pre><br />
For more complex details and examples check out:<br />
<ul> <li><a href="http://www.leecarmichael.com/bootstrapx-clickover/examples.html">Examples</a></li>
<li><a href="https://github.com/lecar-red/bootstrapx-clickover">Github - clickover</a> docs</li>
</ul>__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com354tag:blogger.com,1999:blog-3220508875038756731.post-44699368527210759762012-03-08T09:05:00.001-06:002012-03-08T09:06:53.343-06:00Bootstrap (by Twitter) loading in page content for Popovers<a href="http://twitter.github.com/bootstrap">Bootstrap</a> is a nice get started HTML/CSS/JS interface toolkit. At $work our newest design has been based on it and many of its components.<br />
<br />
One of the challenges I've run into with the <a href="http://twitter.github.com/bootstrap/javascript.html#popovers">Popover</a> element is generating in attribute content for complex elements. <br />
<br />
The basic context is: <br />
<pre class="brush: html;"><a id="mypopover" href="#" data-content="stuff to display"> Label </a>
</pre><br />
The popover gets the body from the <tt>data-content</tt> attribute. The other option that doesn't appear to be documented is using a function set in the options.<br />
<br />
<pre class="brush: js">$('#mypopover').popover({
// other options here
content: function(ele) { return $('#popover-content').html(); }
});
</pre><br />
This will load the html content from element '#popover-content' when calling 'show' on popover.<br />
<br />
<b>Note</b>: If trigger element still has a <tt>data-content</tt> element, even if its empty, the content function will <b>not</b> be called by method.<br />
<br />
My biggest issue still with <a href="http://twitter.github.com/bootstrap">Bootstrap</a> tools is that they are not generally designed to be used with externally loaded content. Therefore to load this type of content I still need to setup lots of manually event handlers. It seems like <a href="http://flowplayer.org/tools/index.html">jQuery Tools</a> has a bit more complete event model today. But Bootstrap is still very young.<br />
<br />
__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com13tag:blogger.com,1999:blog-3220508875038756731.post-17564176007449603312012-02-21T10:10:00.000-06:002012-02-21T10:10:59.551-06:00Sticky floating headers inside of overflowing divsIn our latest project, we have some pretty sweet designs that have headers that drift down in the page as the user scrolls. But at some point the header will hit the end of the containing div and need to stop. (We have a date header for each transaction. The header stops floating once the next day's header is met in the scroll).<br />
<br />
We had some luck using <a href="http://archive.plugins.jquery.com/project/stickyfloat">jquery plugin</a> based on a good tutorial at <a href="http://designwoop.com/2011/01/how-to-create-a-jquery-sticky-sidebar/">Design Woop</a> mixed with this updated <a href=" https://gist.github.com/728487">Gist</a><br />
<br />
But this fell apart when trying to use it with a div that had overflow set to 'auto' or 'scroll'. Since the plugin was calculating location based on document not the div element. Plus the plugin operated on single elements not on jquery objects.<br />
<br />
CSS Looks like:<br />
<pre class="brush: css;" >div.scroll {
background-color: #eee;
width: 600px;
height: 200px;
overflow:scroll;
}
.header {
float: left;
height: 30px;
width: 600px;
background-color: black;
color: white;
font-family: 'Times New Roman', serif;
font-size: 20px;
}
</pre><br />
And html markup looks like (i've removed the extra text so it many not flow based on screen size and such).<br />
<br />
html:<br />
<pre class="brush: html;"><div class="scroll">
<div class="header" id="nowrapper">This is a header</div>
<br class="clear">
text here
<div class="inside">
<div class="header" id="lower">Lower Header</div>
<br class="clear">
more text here
</div>
</div>
</pre><br />
I couldn't find the plugin anywhere so I dumped it up in: <a href="https://github.com/lecar-red/jquery-stickyfloat">https://github.com/lecar-red/jquery-stickyfloat</a> and added support for floating inside a overflowed div.<br />
<br />
To make that page work, after downloading updated stickfloat then add this javascript:<br />
<pre class="brush: js;"><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.stickyfloat.js"></script>
<script type="text/javascript">
$(function() { $(.header).stickyfloat({}) } );
</script>
</pre><br />
I'm hoping to put a tutorial but that will need to wait until another day. You can see how to use it in: <a href="https://github.com/lecar-red/jquery-stickyfloat/blob/master/overflow.html">https://github.com/lecar-red/jquery-stickyfloat/blob/master/overflow.html</a><br />
<br />
__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com0tag:blogger.com,1999:blog-3220508875038756731.post-81131432735634064332012-01-23T14:05:00.000-06:002012-01-23T14:05:29.828-06:00New CPAN Module: WWW::DirectAdmin::APINew module for interacting with <a href="http://directadmin.com/">DirectAdmin</a>'s API: <a href="https://metacpan.org/module/WWW::DirectAdmin::API">WWW::DirectAdmin::API</a><br />
<br />
It currently supports User level functions only. More to come later<br />
<br />
__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com3tag:blogger.com,1999:blog-3220508875038756731.post-45259909011240043282012-01-16T14:25:00.000-06:002012-01-16T14:25:25.423-06:00Accessing Dancer config settings inside of a templateAs I continue to work more and more with <a href="http://perldancer.org/">Perl Dancer</a>, I run into situations where I need to pull in application configuration data inside of the template system.<br />
<br />
<a href="http://perldancer.org/">Dancer</a> provides access to this config in your template system with the template token <tt><a href="https://metacpan.org/module/Dancer::Template::Abstract">settings</a></tt>. What caught me the other day was my desire to use it in the same way as the in the app's DSL: <tt><a href="https://metacpan.org/module/Dancer#setting">setting</a></tt>. This was my misreading of the documentation. To access <tt>settings</tt> in <a href="http://template-toolkit.org/">Template Toolkit</a>, you must grab sub areas as hash keys. <br />
<br />
Example: (you can see this in the generated new app code) <pre>App name: [% settings.appname %]
</pre>I did have a case where I wanted to pull in a value that was located in the plugin section. The plugin (like some of them) are named with double colons (::) and I couldn't get the hash key lookup to work so I used <a href="http://template-toolkit.org/">TT</a>'s <tt><a href="http://template-toolkit.org/docs/manual/VMethods.html#section_item">item</a></tt> virtual method.<br />
<br />
This example dumps out RSS version:<br />
<pre>Using RSS Output Version:
[% settings.plugins.item('XML::RSS').output %]
</pre><br />
Disclaimer: Of course in the case of some configuration values it might make more sense to update the plugin code to share the value or add a before template hook to pass it out. <br />
<br />
__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com1tag:blogger.com,1999:blog-3220508875038756731.post-57553298041275547952011-12-28T14:10:00.001-06:002011-12-30T16:04:08.156-06:00mac os x xattr and "protected" files (post download)Mac OS X (10.6 maybe older or new) sets 'quarantine' bit on files and directories downloaded and unarchived (or just downloaded).<br />
<br />
Its a good idea to warn users what they are opening but this is a pain if the an archive is opened but then you want to move it somewhere else that isn't using typical OS X apps that understand and can clear this perm. (like unix dev location under webserver).<br />
<br />
I've found this <tt>xattr</tt> command to work to clear out that problem:<pre>xattr -d -r com.apple.quarantine directory
</pre><br />
It will verbose blurb out stuff but at least it gets rid of it and allows reading of those files by various unix programs (like apache).<br />
<br />
__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com0tag:blogger.com,1999:blog-3220508875038756731.post-5928805844758439792011-10-28T13:03:00.001-05:002012-01-10T19:10:20.825-06:00jQuery - "getting" chainsI've been using <a href="http://jquery.com">jQuery</a> for quite a while now. I really like its interface, often it feels very Perlish to me. <br />
<br />
But in the past I've struggle when trying to process or access parts of a single element returned by a selector. Most of the time, I really want to grab it with an array index, e.g. <pre class="brush: js" >$('.special-sauce')[0].href</pre>(just some rough example). <br />
<br />
But that always felt wrong, against the jQuery way, like i was an outsider. Esp when its so natural do things like: <pre class="brush: js">$('a.special-sauce').click( function() { // do something } );
</pre><br />
I've tried to use the <tt><a href="http://api.jquery.com/first/">first()</a></tt> method to get a single element but that returns an array too. But I finally got how to use it today...<br />
<br />
We are using <a href="http://flowplayer.org/tools">jQuery Tools</a> for overlays and some other actions. I wanted to retrieve the <tt>href</tt> attribute for the trigger object (the one that was clicked to open the overlay (aka lightbox). I tried the wrong feeling: <pre class="brush: js">this.getTrigger()[0].href</pre>and had the moment of clarity that said "that really means: <pre class="brush: js">this.getTrigger().first().attr('href')</pre>And now i get it (for now) :)<br />
<br />
Since I want some part of the element like an attribute or value I can use the <tt>first</tt> method with either <tt>attr</tt> or <tt>val</tt> methods (or whatever part of the element I really want).<br />
<br />
__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com0tag:blogger.com,1999:blog-3220508875038756731.post-85406127691636470702011-10-26T12:17:00.000-05:002011-10-26T12:17:47.789-05:00jQuery placeholder pluginWe have moved to using the <a href="http://jquery.com">jQuery</a> plugin <a href="https://github.com/dciccale/placeholder-enhanced">placeholder-enhanced</a> for adding placeholders to browsers that don't support them (i'm looking at you IE9).<br />
<br />
It seems to work better than the other plugins and libraries out there (we tried <a href="https://github.com/appsinyourpants/jquery-plugins">placify</a> which had some trouble when pages resized or if forms were hidden in lightboxes).<br />
<br />
It looks like placify creates a div with text (and class) positioned above the input element but placeholder-enhanced adds a class to input and then sets value to placeholder text. Both have positives and negatives. I can see why there are less positioning issues with placeholder-enhanced since it doesn't have to figure out the current location of the element to position a new div on top of it.<br />
<br />
But the one thing i found interesting was that for password fields, placeholder-enhanced creates an input on top of the password input. Its a clever idea but i found a bug with IE9 (go figure) that by default password inputs w/out size have a set width. I need to patch the placeholder library to check for size of the input that it covers up. I've forked and submitted pull request on <a href="http://github.com">github</a>.<br />
<br />
The only other thing i'd like with placeholder-enhanced is way to disable adding 'placeholder' class to input elements when browser supports placeholder styling since we don't need that. It should be too tough to create new parameter. Someday :)<br />
<br />
__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com0tag:blogger.com,1999:blog-3220508875038756731.post-8404817441083197072011-10-04T17:20:00.005-05:002011-12-01T09:20:59.524-06:00Dancer::Plugin internal sharingI've been creating quite a few <a href="http://perldancer.org/">Dancer</a> plugins recently. The nice part of a Dancer plugin is that it gives a small new set of keywords.<br />
<br />
In some cases, I've want to provide a generic keyword interface to an object but then provide smarter business level keywords. I've found a quirk in the Dancer::Plugin interface. I couldn't find it documented anywhere but I'm sure it is.<br />
<br />
If you want to access keywords from the same space that they are registered you need to use a different format than the: <br />
<pre class="brush: perl;">register keyword => sub {};
</pre><br />
You need to use the pattern: <br />
<pre class="brush: perl;">sub keyword {
# do stuff
}
register keyword => \&keyword;
</pre><br />
<tt>register_plugin</tt> actually stuffs the symbols into the namespace therefore you need to share the sub names before that happens to use them.Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com0tag:blogger.com,1999:blog-3220508875038756731.post-18995060315069727812011-07-13T14:58:00.001-05:002011-12-01T09:23:27.143-06:00Perl Module Versions in dotcloudI just realized that I was running an older version in my <a href="http://dotcloud.com/">dotcloud</a> service. There was an update due to a security issue so it was kind of important. <br />
<br />
I found that I needed to update (or put) a version number in the <tt>Makefile.PL</tt>. Here is an example of mine.<br />
<br />
Before:<br />
<pre class="brush:perl;">use strict;
use warnings;
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'leecarmichael',
AUTHOR => q{Lee Carmichael <lee@leecarmichael.com>},
VERSION_FROM => 'lib/leecarmichael.pm',
ABSTRACT => 'Home Site',
($ExtUtils::MakeMaker::VERSION >= 6.3002
? ('LICENSE'=> 'perl')
: ()),
PL_FILES => {},
PREREQ_PM => {
'Test::More' => 0,
'YAML' => 0,
'XML::RSS' => 0,
'URI' => 0,
'Date::Parse' => 0,
'Digest::MD5' => 0,
'Plack' => 0,
'Plack::Request' => 0,
'Template' => 0,
'Dancer' => 1.3040,
'Dancer::Plugin::MobileDevice' => 0,
'Dancer::Plugin::Email' => 0,
'Dancer::Plugin::FlashMessage' => 0,
'Dancer::Plugin::Database' => 0,
'Dancer::Plugin::XML::RSS' => 0,
'Dancer::Session::Storable' => 0,
'DBI' => 0,
'DBD::mysql' => 0
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'leecarmichael-*' },
);
</lee@leecarmichael.com></pre><br />
My updated one has version of Dancer changed to: <br />
<tt>'Dancer' => 1.3060,</tt><br />
<br />
I like this approach to module version management. If you want to force the system to move to everything new you'd need to delete your service and recreate then push. If you want to force just a single CPAN module up to the most recent you update the version number.<br />
<br />
It probably will require me to create a script to compare versions between the service and local dev/qa machines. Better put that on the TODO list :)<br />
<br />
__END__Lee Carmichaelhttp://www.blogger.com/profile/12196361943882608758noreply@blogger.com0