<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="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" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-4835543129581941165</atom:id><lastBuildDate>Tue, 21 Feb 2012 13:16:17 +0000</lastBuildDate><category>web application</category><category>flash</category><category>content sink</category><category>parsing errors</category><category>ecmascript</category><category>bug</category><category>css attribute selectors</category><category>modena</category><category>algorithms</category><category>RIA</category><category>wcag 2.0</category><category>cocoa</category><category>xampp</category><category>google sitemap</category><category>lightbox</category><category>classes</category><category>procedural programming</category><category>xpath</category><category>silvia dini</category><category>jaws</category><category>semantics</category><category>prototypes</category><category>xhtml</category><category>nodelist</category><category>c++</category><category>closures</category><category>fbml</category><category>opera</category><category>roberto ellero</category><category>jss</category><category>google apis</category><category>facebook</category><category>scripting</category><category>attack</category><category>daily life</category><category>jast</category><category>java</category><category>olpc</category><category>reset css</category><category>property</category><category>best practices</category><category>django</category><category>experiment</category><category>c</category><category>mvc</category><category>background images</category><category>browser statistics</category><category>css comments</category><category>richard stallman</category><category>interview</category><category>desktop</category><category>web fonts</category><category>object oriented</category><category>flickr</category><category>obtrusive</category><category>google prettify</category><category>design</category><category>specifications</category><category>simon daniels</category><category>json</category><category>compiler</category><category>svn</category><category>google</category><category>jsanim</category><category>radio buttons</category><category>css urls</category><category>W3C</category><category>search engine</category><category>application</category><category>eric seidel</category><category>site</category><category>lastModified</category><category>typography</category><category>text-indent</category><category>plugin</category><category>font sizer</category><category>overriding styles</category><category>id selectors</category><category>dxr</category><category>embed</category><category>web toolkit</category><category>social network</category><category>xlink</category><category>user experience</category><category>daniele florio</category><category>navigation</category><category>layout engine</category><category>extensions</category><category>matilde</category><category>screen readers</category><category>engine</category><category>xslt</category><category>scriptaculous</category><category>lynx</category><category>widgets</category><category>simplexml</category><category>private</category><category>properties</category><category>jquery</category><category>boris zbarsky</category><category>wikipedia</category><category>print</category><category>web typography</category><category>sabayon</category><category>sql</category><category>twitter</category><category>web forms</category><category>source code</category><category>standards</category><category>media queries</category><category>social media</category><category>acid test 3</category><category>includes</category><category>gmail</category><category>andy budd</category><category>mobile</category><category>clear</category><category>overuse</category><category>wai-aria</category><category>html5</category><category>web</category><category>firebug</category><category>tails</category><category>library</category><category>application/xhtml+xml</category><category>wordpress theme</category><category>web slices</category><category>applications</category><category>queries</category><category>standard</category><category>css</category><category>javascript engine</category><category>web 2.0</category><category>jquery ui</category><category>essentials</category><category>appunti sui css</category><category>file inputs</category><category>performance</category><category>v8</category><category>local hosts</category><category>dummy text</category><category>ims</category><category>christopher schmitt</category><category>safari</category><category>asp</category><category>xml</category><category>unobtrusive javascript</category><category>urls</category><category>mysql</category><category>google maps</category><category>inline styles</category><category>dom level 2</category><category>input background images</category><category>experiments</category><category>google adsense</category><category>web standards</category><category>cameron moll</category><category>automation server can't create object</category><category>POSIX</category><category>android</category><category>accessibility guidelines</category><category>domdocument</category><category>svg</category><category>david baron</category><category>o'reilly</category><category>simon collison</category><category>javascript effects</category><category>regular expressions</category><category>slide</category><category>syntax highlighter</category><category>zend</category><category>web accessibility</category><category>itunes</category><category>prototype</category><category>bugzilla</category><category>css anomalies</category><category>floats</category><category>selectors</category><category>design patterns</category><category>wireframe</category><category>javascript</category><category>documents</category><category>web development</category><category>gnu</category><category>youtube</category><category>var keyword</category><category>dave raggett</category><category>iwa</category><category>browsers</category><category>effects</category><category>get glue</category><category>yahoo user interface</category><category>developers</category><category>portfolio</category><category>css tables</category><category>analysis</category><category>amazon</category><category>browser</category><category>forms</category><category>windows</category><category>layouts</category><category>filling text</category><category>image element</category><category>css breadcrumbs</category><category>progressive enhancement</category><category>csv</category><category>textpattern</category><category>email validation</category><category>feed</category><category>tabs</category><category>sass</category><category>internet explorer</category><category>php</category><category>2010</category><category>lucene</category><category>oop</category><category>website</category><category>gecko</category><category>wamboo</category><category>jquery 1.4.2</category><category>eric meyer</category><category>free software</category><category>libxml</category><category>singleton pattern</category><category>tests</category><category>captcha</category><category>formatrssdate</category><category>blogger</category><category>type hinting</category><category>pseudo-elements</category><category>css tests</category><category>poetry</category><category>pattern</category><category>polyglot inc</category><category>namespace selectors</category><category>modular</category><category>keywords</category><category>images</category><category>dom navigation</category><category>icons</category><category>dtd</category><category>development</category><category>border-opacity</category><category>events</category><category>parsing</category><category>api</category><category>white-space</category><category>yql</category><category>tokenizer</category><category>chrome</category><category>inheritance</category><category>git</category><category>spam</category><category>rss</category><category>apps</category><category>code compressions</category><category>video</category><category>redirect</category><category>mashup</category><category>hcard</category><category>basics</category><category>directory listing</category><category>extending</category><category>stoyan stefanov</category><category>demos</category><category>sitepoint</category><category>mxr</category><category>301</category><category>faq</category><category>social icons</category><category>zend studio</category><category>themes</category><category>wordpress</category><category>pdf</category><category>rest</category><category>javascript libraries</category><category>form validation</category><category>smarty</category><category>optimization</category><category>rich internet applications</category><category>magento</category><category>framework</category><category>feedburner</category><category>yahoo query language</category><category>scott meyers</category><category>feeds</category><category>objects literals</category><category>nomenclature</category><category>information architecture</category><category>dom</category><category>page refresh</category><category>XMLHttpRequest</category><category>perl</category><category>github</category><category>accordion</category><category>css positioning</category><category>generated content</category><category>tech talks</category><category>steve souders</category><category>excel</category><category>prototyping</category><category>webkit</category><category>steve jobs</category><category>uml</category><category>prince</category><category>textarea</category><category>bleach</category><category>css parser</category><category>usability</category><category>dreamweaver</category><category>mark pilgrim</category><category>css generated content</category><category>table model</category><category>css classes</category><category>mac os x</category><category>interoperability</category><category>web services</category><category>aaron gustafson</category><category>anne van kesteren</category><category>publishing</category><category>haslayout</category><category>seo</category><category>default style sheet</category><category>douglas crockford</category><category>permanent links</category><category>squirrelfish extreme</category><category>reusable</category><category>css table values</category><category>web site</category><category>javascript animations</category><category>ie6fix</category><category>michele diodati</category><category>templates</category><category>css bugs</category><category>html forms</category><category>gwt</category><category>john resig</category><category>bug tracking</category><category>functions</category><category>syntax</category><category>date</category><category>validation</category><category>css 3 selectors</category><category>firefox</category><category>navigation menu</category><category>iphone</category><category>accessibility</category><category>css sprites</category><category>nicholas c. zakas</category><category>bjarne stroustrup</category><category>css 2.1</category><category>matt mullenweg</category><category>eclipse</category><category>supporting</category><category>user testing</category><category>cascade</category><category>css 3</category><category>lorem ipsum</category><category>page rank</category><category>security</category><category>semantic web</category><category>object</category><category>css3</category><category>form validator</category><category>aural css</category><category>rootkit</category><category>headings</category><category>minidom</category><category>theming</category><category>microformats</category><category>box model</category><category>gears</category><category>geolocation</category><category>tutorials</category><category>zend framework</category><category>html</category><category>hakon wium lie</category><category>testing</category><category>russ weakley</category><category>ide</category><category>web design</category><category>yui</category><category>javascript dates</category><category>image optimization</category><category>debugging</category><category>pcre</category><category>marco olivetti</category><category>validation icons</category><category>url rewriting</category><category>conference</category><category>overflow</category><category>validator</category><category>css absolute positioning</category><category>tables</category><category>compression</category><category>tim berners-lee</category><category>jquery plugin</category><category>namespaces</category><category>ibm</category><category>python</category><category>cms</category><category>internet</category><category>rounded corners</category><category>html 5</category><category>css floats</category><category>database</category><category>molly holzschlag</category><category>simon willison</category><category>apache</category><category>linux</category><category>fancybox</category><category>rendering</category><category>template blocks</category><category>calendars</category><category>ajax</category><category>programming</category><category>tutorial</category><category>objects</category><category>facebook api</category><category>ian hickson</category><category>jsp</category><category>blog</category><category>data urls</category><category>roberto scano</category><category>object oriented programming</category><category>form elements</category><category>drupal</category><category>jquery novice to ninja</category><category>microsoft</category><category>colors</category><category>legacy browsers</category><category>smau</category><category>visited links</category><category>mercurial</category><category>client-side code</category><category>high performance websites</category><title>onwebdev</title><description>Web development by Gabriele Romanato</description><link>http://onwebdev.blogspot.com/</link><managingEditor>noreply@blogger.com (Gabriele Romanato)</managingEditor><generator>Blogger</generator><openSearch:totalResults>1686</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/rss+xml" href="http://feeds.feedburner.com/blogspot/onwebdev" /><feedburner:info uri="blogspot/onwebdev" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:emailServiceId>blogspot/onwebdev</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/blogspot/onwebdev" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2Fblogspot%2Fonwebdev" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-113118963941303577</guid><pubDate>Mon, 20 Feb 2012 09:41:00 +0000</pubDate><atom:updated>2012-02-20T01:41:49.819-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: curtain effect on slideshows</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/curtain.jpg" alt="" class="wide spaced" /&gt;&lt;cite&gt;jQuery Easing&lt;/cite&gt; is a fantastic plugin, surely one of my favorites. Today I've created a nice curtain effect on a jQuery slideshow that I'd like to share with you. Let's see the details.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;The markup&lt;/h2&gt;

&lt;p&gt;Our slideshow only requires the addition of an element with two empty elements inside:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;div id=&amp;quot;slider&amp;quot;&amp;gt;
 &amp;lt;div id=&amp;quot;slider-wrapper&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;h2&amp;gt;Slide 1&amp;lt;/h2&amp;gt;
   &amp;lt;p&amp;gt;Lorem ipsum dolor.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;h2&amp;gt;Slide 2&amp;lt;/h2&amp;gt;
   &amp;lt;p&amp;gt;Lorem ipsum dolor.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;h2&amp;gt;Slide 3&amp;lt;/h2&amp;gt;
   &amp;lt;p&amp;gt;Lorem ipsum dolor.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;h2&amp;gt;Slide 4&amp;lt;/h2&amp;gt;
   &amp;lt;p&amp;gt;Lorem ipsum dolor.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;
   &amp;lt;h2&amp;gt;Slide 5&amp;lt;/h2&amp;gt;
   &amp;lt;p&amp;gt;Lorem ipsum dolor.&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;


 &amp;lt;/div&amp;gt;
 &amp;lt;div id=&amp;quot;slider-panels&amp;quot;&amp;gt;
  &amp;lt;div id=&amp;quot;slider-panel-left&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div id=&amp;quot;slider-panel-right&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
 &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&lt;/pre&gt;

&lt;p&gt;These panels will be our curtains.&lt;/p&gt;

&lt;h2&gt;The CSS&lt;/h2&gt;

&lt;p&gt;The additional empty element must be absolutely positioned on the top of all other slideshow elements:&lt;/p&gt;

&lt;pre&gt;
#slider {
 width: 500px;
 height: 300px;
 margin: 4em auto;
 font: 90% Arial, sans-serif;
 position: relative;
 overflow: hidden;
 border: 5px solid #666;
}

#slider-wrapper {
 width: 2500px;
 height: 300px;
 position: relative;
}

div.slide {
 width: 500px;
 height: 300px;
 background: #ccc;
 text-align: center;
 float: left;
}

div.slide h2 {
 font-weight: normal;
 padding: 2em 0 0 0;
 margin: 0;
}

div.slide p {
 margin-top: 0.3em;
}

#slider-panels {
 width: 500px;
 height: 300px;
 position: absolute;
 top: 0;
 left: 0;
}

#slider-panel-left {
 width: 250px;
 height: 300px;
 position: absolute;
 top: 0;
 left: 0;
 background: #222;
}

#slider-panel-right {
 width: 250px;
 height: 300px;
 position: absolute;
 top: 0;
 right: 0;
 background: #222;
}
&lt;/pre&gt;

&lt;p&gt;Our panels are exactly 250 pixels wide, that is, the half of their container.&lt;/p&gt;

&lt;h2&gt;The jQuery code&lt;/h2&gt;

&lt;p&gt;We'll use an object to properly wrap all the logic behind our slideshow. First, we need to declare all the required properties:&lt;/p&gt;

&lt;pre&gt;
var Slider = new function() {

 var slider = document.getElementById('slider'),
  slides = $('div.slide', slider),
  wrapper = $('#slider-wrapper', slider),
  leftPanel = $('#slider-panel-left', slider),
  rightPanel = $('#slider-panel-right', slider),
  index = -1,
  timer = null;
        
        // continues
}();
&lt;/pre&gt;

&lt;p&gt;Since we're going to zero the widths of the panels, we need a method to reset their widths:&lt;/p&gt;

&lt;pre&gt;
var reset = function() {
 
  leftPanel.width(250);
  rightPanel.width(250);
 
 
};
&lt;/pre&gt;

&lt;p&gt;Now we can create our sliding effect on panels:&lt;/p&gt;

&lt;pre&gt;
var slidePanels = function() {
 
  leftPanel.animate({
   width: 0
  }, 1000, 'easeOutBounce');
  
  rightPanel.animate({
   width: 0
  }, 1000, 'easeOutBounce');
 
 
 
};
&lt;/pre&gt;

&lt;p&gt;Then we need to create an automatic and cyclic effect on all slides, so we basically need to initiate our timer:&lt;/p&gt;

&lt;pre&gt;
var autoSlide = function() {
 
  timer = setInterval(function() {
  
   index++;
   
   reset();
   
   if(index == (slides.length -1)) {
   
    index = -1;
   
   
   }
  
   var slide = slides.eq(index);
   
   wrapper.animate({
    left: - slide.position().left
   }, 0, function() {
   
    slidePanels();
   
   
   });
  
  
  }, 2000);
 
 
 
};
&lt;/pre&gt;

&lt;p&gt;Finally, a public method to kick things off:&lt;/p&gt;

&lt;pre&gt;
this.init = function() {
 
  autoSlide();
 
 
};
&lt;/pre&gt;

&lt;p&gt;We can use our object as follows:&lt;/p&gt;

&lt;pre&gt;
$(function() {

 Slider.init();


});
&lt;/pre&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;

&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-effetto-sipario/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-effetto-sipario/jquery-slideshow-effetto-sipario.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-113118963941303577?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/GAvaOB_Ni4Q" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/GAvaOB_Ni4Q/jquery-curtain-effect-on-slideshows.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/jquery-curtain-effect-on-slideshows.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-3522059941170028180</guid><pubDate>Sat, 18 Feb 2012 11:37:00 +0000</pubDate><atom:updated>2012-02-18T03:38:16.745-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><title>WordPress is for blogging: any other use is a costly mistake</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/09/wordpress-logo.png" alt="" class="aligncenter spaced" /&gt;I don't understand why most web agencies tend to use WordPress as a catch-all for every project they work on. In short, WordPress is a CMS designed to manage blogs or blog-like web sites. WordPress was not designed to manage e-commerce sites, communities or even newsletter or file downloads. The more the task diverges from the original design, the more it's likely that your project will fail or, if you're lucky and patient, need continuous assistance for bug fixing, maintenance and plugin customization. You'll probably end up with a disappointed and angry client and a significant increase of your budget costs. You don't deserve this.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;Let's speak honestly: we use WordPress because it's easy to set up, not because is the best tool we can use. We should use more robust frameworks, such as Zend, when the required tasks are actually complex. The point is that WordPress is a full-box where you can code only in the way WordPress allows you to do, not in the way you really want to.&lt;/p&gt;

&lt;p&gt;We need more control over our actions so that when the sky falls down we're sure that it's only our fault and we can start finding a solution instead of testing and exhausting all the possible causes without having a clue.&lt;/p&gt;

&lt;p&gt;Because when WordPress fails it's hard to track down the case zero where everything started. It might be a wrong rewrite rule, an incorrect permission, an SQL error or what? Further, we can find help only on forums, mailing lists, blogs or simply reading carefully the documentation. Are we sure that we'll find a good solution? No.&lt;/p&gt;

&lt;p&gt;When you force WordPress to do something it was not designed for, you're actually raising the percentage of a possible failure of the whole CMS. And don't be tempted to rely on plugins to accomplish the tasks your site needs: plugins are not a good solution, because you don't actually know what your client will ask in the future. Is it possible to find the right plugin for every feature your client wants now, tomorrow, the next month and so on? How many plugins will you have to install? And how WordPress will handle tons of plugins?&lt;/p&gt;

&lt;p&gt;The point is simple: WordPress is designed to handle blogs. All other possible uses are actually an unknown scenario.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-3522059941170028180?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/fasK46K33KE" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/fasK46K33KE/wordpress-is-for-blogging-any-other-use.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/wordpress-is-for-blogging-any-other-use.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-2099123335421250036</guid><pubDate>Thu, 16 Feb 2012 19:24:00 +0000</pubDate><atom:updated>2012-02-16T11:24:55.226-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><title>WordPress: Timthumb vulnerability fix</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/timthumb-malware.jpg" alt="" class="wide spaced" /&gt;If you're viewing the above screenshot on your site with Chrome, your site has been compromised by the Timthumb vulnerability. The best thing you can do is to follow the instructions provided below.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;What's happened?&lt;/h2&gt;

&lt;p&gt;Your WordPress theme uses an outdated version of the Timthumb library. By exploiting this vulnerability, most of the JavaScript files of your theme (and also some core JavaScript files used by WordPress) have been tainted with malicious code (appended at the end of each file). Also, the cache of your theme might contain malicious code in some PHP files.&lt;/p&gt;

&lt;h2&gt;What can I do?&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;To fix the Timthumb vulnerability, download and use the &lt;a href="http://wordpress.org/extend/plugins/timthumb-vulnerability-scanner/"&gt;Timthumb Vulnerability Scanner&lt;/a&gt; plugin.&lt;/li&gt;
&lt;li&gt;Replace your compromised theme files with a clean copy.&lt;/li&gt;
&lt;li&gt;Upgrade or restore your WordPress installation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Finally, you have to notify Google that now your site is safe again. Use the &lt;cite&gt;Reconsider site&lt;/cite&gt; functionality provided by Google.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-2099123335421250036?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/IuFGbsoSlZc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/IuFGbsoSlZc/wordpress-timthumb-vulnerability-fix.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/wordpress-timthumb-vulnerability-fix.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-8005225473055421843</guid><pubDate>Thu, 16 Feb 2012 06:50:00 +0000</pubDate><atom:updated>2012-02-15T22:50:17.821-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: Observer Pattern on slideshows</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/observer.jpg" alt="" class="aligncenter spaced" /&gt;I've just finished to work on an interesting jQuery/WordPress project (you can find it &lt;a href="http://www.valburger.com/?page_id=74&amp;lang=it"&gt;here&lt;/a&gt;) where I had to build an interactive slideshow very similar to a classic jQuery slot machine in its inner functioning. The only problem was to keep track of the visibility of the slides, that is, being sure that the current slide was visible. This is a fantastic use case for the Observer Pattern.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;Let's take a sample slideshow:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;
    &amp;lt;div id=&amp;quot;slideshow-wrapper&amp;quot;&amp;gt;
        &amp;lt;div class=&amp;quot;slide one&amp;quot;&amp;gt;One&amp;lt;/div&amp;gt;
        &amp;lt;div class=&amp;quot;slide two&amp;quot;&amp;gt;Two&amp;lt;/div&amp;gt;
        &amp;lt;div class=&amp;quot;slide three&amp;quot;&amp;gt;Three&amp;lt;/div&amp;gt;
        &amp;lt;div class=&amp;quot;slide four&amp;quot;&amp;gt;Four&amp;lt;/div&amp;gt;
        &amp;lt;div class=&amp;quot;slide five&amp;quot;&amp;gt;Five&amp;lt;/div&amp;gt;
 &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;div id=&amp;quot;watch&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;with a couple of CSS styles used to make it work:&lt;/p&gt;

&lt;pre&gt;
#slideshow {
    width: 500px;
    height: 300px;
    margin: 2em auto;
    position: relative;
    overflow: hidden;
    border: 0.5em double #aaa;
}

#slideshow-wrapper {
    width: 2500px;
    height: 300px;
    position: relative;
    background: #222;
}

div.slide {
    float: left;
    width: 500px;
    height: 300px;
    background: #ccc;
    text-align: center;
    font-size: 1.5em;
    line-height: 300px;
}

div.two, div.four {background: #ffc;}

div[rel="visible"] {
    font-size: 5em;
}
​&lt;/pre&gt;

&lt;p&gt;When the slideshow moves from right to left, obviously the current slide is visible. We can attach a custom attribute to the current slide so that we're sure that it's visible:&lt;/p&gt;

&lt;pre&gt;
var watch = function(element) {
    
   element.attr('rel', 'visible').siblings().removeAttr('rel');
  
   $('#watch').text(element.text() + ' is ' + element.attr('rel'));    
    
};
&lt;/pre&gt;

&lt;p&gt;Then we have to call this method only when the slideshow change its position:&lt;/p&gt;

&lt;pre&gt;
var slideTo = function(element) {
    
    wrapper.animate({
        left: - element.position().left
    }, 2000);
    
};

var watch = function(element) {
    
   element.attr('rel', 'visible').siblings().removeAttr('rel');
  
   $('#watch').text(element.text() + ' is ' + element.attr('rel'));    
    
};


var autoSlide = function() {
    
    timer = setInterval(function() {

        index++;
        
        if(index == slides.length) {
         
              index = 0;            
            
        }
        
        var slide = slides.eq(index);
        
        slideTo(slide);
        watch(slide);

    }, 2000);        
    
};
&lt;/pre&gt;

&lt;p&gt;Since we've set the following styles on a particular slide whose &lt;code&gt;rel&lt;/code&gt; attribute is set to &lt;code&gt;visible&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
div[rel="visible"] {
    font-size: 5em;
}
&lt;/pre&gt;

&lt;p&gt;the font size of the current slide is increased as well. You can see the demo below.&lt;/p&gt;


&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://jsfiddle.net/gabrieleromanato/3chyE/"&gt;Live demo&lt;/a&gt; (with code on jsFiddle)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-8005225473055421843?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/DiSxpRl1_Ms" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/DiSxpRl1_Ms/jquery-observer-pattern-on-slideshows.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/jquery-observer-pattern-on-slideshows.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-1366644587487912929</guid><pubDate>Fri, 10 Feb 2012 11:18:00 +0000</pubDate><atom:updated>2012-02-10T03:18:14.603-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>CSS generated content tutorial</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/css-code.jpg" alt="" class="aligncenter spaced" /&gt;In this article I'll discuss some possible uses of &lt;a href="http://www.w3.org/TR/CSS21/generate.html"&gt;generated content&lt;/a&gt;.
Generated content is a powerful feature of &lt;acronym title="Cascading Style Sheets"&gt;CSS&lt;/acronym&gt;. Before going on, I'd like to explain
what generated content is &lt;em&gt;not&lt;/em&gt;.&lt;/p&gt; 

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;Let's take a look at the following picture.&lt;/p&gt;


&lt;p&gt;&lt;img src="http://www.css-zibaldone.com/articles/generated-content/img/dog.jpg" alt="A puppy dog puppet" /&gt;&lt;/p&gt;

&lt;p&gt;The picture depicts a puppy dog puppet. Of course this is not a real puppy, but only an abstraction.
By the same token, generated content is not real content but only an abstraction.
More precisely, generated content doesn't exist in the document tree nor is parsed with the rest of the document.
We can say, in other words, that generated content is only pseudo-content.
For example, when we insert a string through generated content, the text inserted is not selectable.
That's why generated content lives only in the style rules.&lt;/p&gt;

&lt;h2&gt;Inserting generated content&lt;/h2&gt;
&lt;p&gt;Generated content can be inserted before and after the real content of an element through the
&lt;code&gt;:before&lt;/code&gt; and &lt;code&gt;:after&lt;/code&gt; pseudo-elements, respectively. To represent them, we can use
the following fictional markup.&lt;/p&gt;

&lt;pre&gt;
&amp;lt;p&amp;gt;
&amp;lt;before&amp;gt;Start&amp;lt;/before&amp;gt;
Real content
&amp;lt;after&amp;gt;End&amp;lt;/after&amp;gt;
&amp;lt;/p&amp;gt;
&lt;/pre&gt;

&lt;p&gt;And our CSS will be:&lt;/p&gt;

&lt;pre&gt;
p:before {
 content: "Start";
}
p:after {
 content: "End";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/generated-content/examples/1/1.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, the property that actually inserts the two strings is &lt;code&gt;content&lt;/code&gt;. This
property accepts the following values:&lt;/p&gt;

&lt;dl&gt;
&lt;dt&gt;&lt;strong&gt;none&lt;/strong&gt;, &lt;strong&gt;normal&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;The pseudo-content is not generated.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;&amp;lt;string&amp;gt;&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;A textual string enclosed in matching quotes.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;url()&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;This function allow us to insert an external resource (usually an image), as in the 
&lt;code&gt;background-image&lt;/code&gt; property.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;counter()&lt;/strong&gt;, &lt;strong&gt;counters()&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;These functions insert counters. See below for more details.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;attr(attribute)&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;This function allow us to insert the value of the attribute &lt;code&gt;attribute&lt;/code&gt; of the given
element.&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;Keep in mind that generated content takes up its own space on the page and its presence
affects the space's computation of the element that hosts it.&lt;/p&gt;

&lt;h2&gt;Inserting strings and special characters&lt;/h2&gt;
&lt;p&gt;In the previous example, we've inserted two simple strings before and after the real content
of an element. Generated content allows us to insert also more complex symbols through escaping.&lt;/p&gt;

&lt;pre&gt;
p:before {
 content: "\00A7";
 padding-right: 0.2em;
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/generated-content/examples/2/2.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The escaped sequence inside the double quotes is an hexadecimal Unicode value that refers to a
paragraph symbol. We can also combine simple strings with Unicode symbols, as shown below.&lt;/p&gt;

&lt;pre&gt;
p:before {
 content: "( " "\00A7" " )";
 padding-right: 0.2em;
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/generated-content/examples/3/3.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep in mind that all the textual content inside the &lt;code&gt;content&lt;/code&gt; property is treated literally, that is, spaces and tabulations inserted via the keyboard will be inserted in the page
as well.&lt;/p&gt;

&lt;h2&gt;Inserting images&lt;/h2&gt;

&lt;p&gt;We can insert images through the &lt;code&gt;url()&lt;/code&gt; function.&lt;/p&gt;

&lt;pre&gt;
a:before {
 content: url("../img/link.gif");
 padding-right: 0.2em;
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/generated-content/examples/4/4.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see, this function works exactly as in the &lt;code&gt;background-image&lt;/code&gt; property.&lt;/p&gt;


&lt;h2&gt;Inserting attribute values&lt;/h2&gt;

&lt;p&gt;An attribute value of an element can be inserted through the &lt;code&gt;attr()&lt;/code&gt; function.&lt;/p&gt;

&lt;pre&gt;
a[href]:after {
 content: "( " attr(href) " )";
 padding-left: 0.2em;
 color: #000;
 font: small "Courier New", Courier, monospace;
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/generated-content/examples/5/5.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've just inserted the value of the &lt;code&gt;href&lt;/code&gt; attribute that, as you can see, is a simple
textual string.&lt;/p&gt;

&lt;h2&gt;Inserting counters&lt;/h2&gt;

&lt;p&gt;Through counters we can add an automatic numbering to the elements of a web document. Thanks to the &lt;code&gt;:before&lt;/code&gt; and
&lt;code&gt;:after&lt;/code&gt; pseudo-elements, the numbering will appear before or after the actual content of an element, respectively.&lt;/p&gt;

&lt;h3&gt;Adding counters to elements&lt;/h3&gt;
&lt;p&gt;The automatic numbering of &lt;acronym title="Cascading Style Sheets"&gt;CSS&lt;/acronym&gt; is controlled by two properties, 
&lt;code&gt;counter-reset&lt;/code&gt; and &lt;code&gt;counter-increment&lt;/code&gt;. Counters defined by these properties are then used with
the &lt;code&gt;counter()&lt;/code&gt; and &lt;code&gt;counters()&lt;/code&gt; functions of the &lt;code&gt;content&lt;/code&gt; property.&lt;/p&gt;


&lt;p&gt;The &lt;code&gt;counter-reset&lt;/code&gt; property can contain one or more names of counters (identifiers), optionally followed by an integer.
The integer sets the value that will be incremented by the &lt;code&gt;counter-increment&lt;/code&gt; property for any occurence of the
given element. The default value is 0. Negative values are allowed.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;counter-increment&lt;/code&gt; property is similar to the previous property. The basic difference here is that this
property actually increments a counter. Its default increment is 1. Negative values are allowed.&lt;/p&gt;

&lt;p&gt;Now we are ready to create a practical example. Given the following markup:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;dl&amp;gt;
 &amp;lt;dt&amp;gt;term&amp;lt;/dt&amp;gt;
 &amp;lt;dd&amp;gt;definition&amp;lt;/dd&amp;gt;
 &amp;lt;dt&amp;gt;term&amp;lt;/dt&amp;gt;
 &amp;lt;dd&amp;gt;definition&amp;lt;/dd&amp;gt;
 &amp;lt;dt&amp;gt;term&amp;lt;/dt&amp;gt;
 &amp;lt;dd&amp;gt;definition&amp;lt;/dd&amp;gt;
&amp;lt;/dl&amp;gt;
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing1.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;we want to add a progressive numbering (1, 2, 3) to each definition term (&lt;code&gt;dt&lt;/code&gt;) in the list. The relevant CSS is the
following:&lt;/p&gt;

&lt;pre&gt;
dl {
 counter-reset: term;
}
dt:before {
 counter-increment: term;
 content: counter(term);
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing2.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first rule in the previous listing sets a counter for the definition list. This is called a scope.
The name (an identifier) of the counter is &lt;code&gt;term&lt;/code&gt;. Keep in mind that once we've chosen a name
for our counter this must be the same also in the &lt;code&gt;counter-increment&lt;/code&gt; property (of course se should
use a meaningful name).&lt;/p&gt;

&lt;p&gt;In the second rule we attach the &lt;code&gt;:before&lt;/code&gt; pseudo-element to the &lt;code&gt;dt&lt;/code&gt; element, since we want to insert
the counter exactly before the actual content of the element. Now let's take a closer look at the second declaration of the
second rule. The &lt;code&gt;counter()&lt;/code&gt; function accepts our identifier (&lt;code&gt;term&lt;/code&gt;) as its argument and the 
&lt;code&gt;content&lt;/code&gt; property actually generates the counter.&lt;/p&gt;

&lt;p&gt;As you can see, there's no space between the number and the content of the element. If we want to add more space and, say,
a period (.) after the number, we could insert the following string in the &lt;code&gt;content&lt;/code&gt; property:&lt;/p&gt;

&lt;pre&gt;
dt:before {
 content: counter(term) ". ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing3.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that the string inside the double quotes is treated literally, that is, the space after the period is inserted
as we've typed it on the keyboard. In fact, the &lt;code&gt;content&lt;/code&gt; property can be regarded as the CSS counterpart of the
JavaScript &lt;code&gt;document.write()&lt;/code&gt; method except that this property doesn't add real content to the document. Simply put,
the &lt;code&gt;content&lt;/code&gt; property creates a mere abstraction on the document tree but it doesn't modify it.&lt;/p&gt;

&lt;p&gt;In case you're wondering, we can add more styles to counters by applying other properties to the attached pseudo-element.
For example:&lt;/p&gt;

&lt;pre&gt;
dt:before {
 content: counter(term);
 padding: 1px 2px;
 margin-right: 0.2em;
 background: #ffc;
 color: #000;
 border: 1px solid #999;
 font-weight: bold;
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing4.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've just set a background color, added some padding and a right margin, made the font bold and outlined
the counters with a thin solid border. Now our counters are a little more attractive.&lt;/p&gt;

&lt;p&gt;Furthermore, counters can be negative. When dealing with negative counters, we should only keep in mind a little maths, namely
the part concerning addition and subtraction of negative and positive numbers. For example, if we need a progressive numbering
starting from 0, we could write the following:&lt;/p&gt;

&lt;pre&gt;
dl {
 counter-reset: term -1;
}

dt:before {
 counter-increment: term;
 content: counter(term) ". ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing5.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By setting the &lt;code&gt;counter-reset&lt;/code&gt; property to -1 and incrementing it by 1, the resulting value is 0 and the numbering
will actually start from that value. Negative counters can combine with positive counters to create interesting results. Consider
the following example:&lt;/p&gt;

&lt;pre&gt;
dl {
 counter-reset: term -1;
}

dt:before {
 counter-increment: term 3;
 content: counter(term) ". ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing6.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, addition and substraction of negative and positive numbers yield a wide range of combination between counters.
With just a simple set of calculations we can get a complete control over this automatic numbering.&lt;/p&gt;

&lt;h3&gt;Nested counters&lt;/h3&gt;
&lt;p&gt;Another interesting feature of CSS counters lies in their capability of being nested. In fact, numbering may proceed also
by using progressive sublevels, such as 1.1, 1.1.1, 2.1 and so on. For example, if we want to add a sublevel to the elements of our
list, we could write the following:&lt;/p&gt;

&lt;pre&gt;
dl {
 counter-reset: term definition;
}

dt:before {
 counter-increment: term;
 content: counter(term) ". ";
}

dd:before {
 counter-increment: definition;
 content: counter(term) "." counter(definition) " ";
}

&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing7.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This example is similar to the first one, but in this case we have two counters, &lt;code&gt;term&lt;/code&gt; and &lt;code&gt;definition&lt;/code&gt;.
The scope of both counters is set by the first rule and &amp;quot;lives&amp;quot; in the &lt;code&gt;dl&lt;/code&gt; element.
The second rule inserts the first counter before each definition term of the list. This rule is not particularly interesting, since
its effect is already known. Instead, the last rule is the core of our code because it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;increments the second counter (&lt;code&gt;definition&lt;/code&gt;) on &lt;code&gt;dd&lt;/code&gt; elements&lt;/li&gt;
&lt;li&gt;inserts the first counter (&lt;code&gt;term&lt;/code&gt;), followed by a period&lt;/li&gt;
&lt;li&gt;inserts the second counter (&lt;code&gt;definition&lt;/code&gt;), followed by a space.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that steps #2 and #3 are both performed by the &lt;code&gt;content&lt;/code&gt; property used on the &lt;code&gt;:before&lt;/code&gt; pseudo-element
attached to the definition term.&lt;/p&gt;

&lt;p&gt;Another interesting thing to remember is that counters are &amp;quot;self-nesting&amp;quot; in the sense that resetting a counter
on a descendant element (or pseudo-element) automatically creates a new instance of the counter. This is useful in the case of
(X)HTML lists, where elements may be nested with arbitrary depth. However, it's not always possible to specify a different
counter for each list, since this approach might produce a really redundant code. In that vein, it's useful to mention the
&lt;code&gt;counters()&lt;/code&gt; function. This function creates a string containing all the counters having the same name of the
given counter in the scope. Counters are then separated by a string. For example, given the following markup:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;ol&amp;gt;
 &amp;lt;li&amp;gt;item&amp;lt;/li&amp;gt;
 &amp;lt;li&amp;gt;item
  &amp;lt;ol&amp;gt;
   &amp;lt;li&amp;gt;item&amp;lt;/li&amp;gt;
   &amp;lt;li&amp;gt;item&amp;lt;/li&amp;gt;
   &amp;lt;li&amp;gt;item
    &amp;lt;ol&amp;gt;
     &amp;lt;li&amp;gt;item&amp;lt;/li&amp;gt;
     &amp;lt;li&amp;gt;item&amp;lt;/li&amp;gt;
    &amp;lt;/ol&amp;gt;
   &amp;lt;/li&amp;gt;
  &amp;lt;/ol&amp;gt;
 &amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing8.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following CSS numbers the nested list items as 1, 1.1, 1.1.1, etc.&lt;/p&gt;

&lt;pre&gt;
ol {
 counter-reset: item;
}

li {
 display: block;
}

li:before {
 counter-increment: item;
 content: counters(item, ".") " ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing9.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example we have only the &lt;code&gt;item&lt;/code&gt; counter for each nesting level. Instead of writing three different counters
(e.g. &lt;code&gt;item1&lt;/code&gt;, &lt;code&gt;item2&lt;/code&gt;, &lt;code&gt;item3&lt;/code&gt;) and thus creating three different scopes for each nested &lt;code&gt;ol&lt;/code&gt; element, we can rely on the &lt;code&gt;counters()&lt;/code&gt; function to achieve this goal. The second rule is really important and
deserves a further explanation. Since ordered lists have a default marker (a number), we get rid of these marker by turning the list
items into block-level elements. Keep in mind that only elements with &lt;code&gt;display: list-items&lt;/code&gt; have markers. Now we can
look carefully at the third rule that actually does the work. The first declaration increments the counter previously set on the
outermost list. Then, in the second declaration, the &lt;code&gt;counters()&lt;/code&gt; function creates all the counter's instances for
the innermost lists. The structure of this function is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;its first argument is the name of the given counter, immediately followed by a comma&lt;/li&gt;
&lt;li&gt;its second argument is a period inserted in double quotes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that we've inserted a space after the &lt;code&gt;counters()&lt;/code&gt; function in order to keep the numbers separate from the
actual content of the list items.&lt;/p&gt;

&lt;h3&gt;Styles of counters&lt;/h3&gt;
&lt;p&gt;Counters are formatted with decimal numbers by default. However, the styles of the &lt;code&gt;list-style-type&lt;/code&gt; property
are also available for counters. The default notation is &lt;code&gt;counter(name)&lt;/code&gt; (no style) or 
&lt;code&gt;counter(name, 'list-style-type')&lt;/code&gt; if we want to change the default formatting. In practice, the recommended styles are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;decimal&lt;/code&gt;&lt;/li&gt; 
&lt;li&gt;&lt;code&gt;decimal-leading-zero&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lower-roman&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;upper-roman&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lower-greek&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lower-latin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;upper-latin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lower-alpha&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;upper-alpha&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;because we should always bear in mind that we're working with numeric systems. Furthermore, we should also be aware of the fact
that the specifications don't define the rendering of alphabetical systems at the end of the alphabet. For example, after 26 list
items the rendering of &lt;code&gt;lower-latin&lt;/code&gt; is undefined. Real numbers are thus recommended for long lists. Here's an
example:&lt;/p&gt;

&lt;pre&gt;
dl {
 counter-reset: term definition;
}

dt:before {
 counter-increment: term;
 content: counter(term, upper-latin) ". ";
}

dd:before {
 counter-increment: definition;
 content: counter(definition, lower-latin) ". ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing10.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also add styles to the &lt;code&gt;counters()&lt;/code&gt; function, as shown in the following example.&lt;/p&gt;

&lt;pre&gt;
li:before {
 counter-increment: item;
 content: counters(item, ".", lower-roman) " ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing11.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that the &lt;code&gt;counters()&lt;/code&gt; function can also accept a third argument (&lt;code&gt;lower-roman&lt;/code&gt;) as the last member of its arguments list, separated by a second
comma from the preceding period. However, the &lt;code&gt;counters()&lt;/code&gt; function doesn't allow us to specify different styles for each level of nesting.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-1366644587487912929?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/sJ3-gmfeYjI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/sJ3-gmfeYjI/css-generated-content-tutorial.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>2</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/css-generated-content-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-6517213254632371263</guid><pubDate>Thu, 09 Feb 2012 18:42:00 +0000</pubDate><atom:updated>2012-02-09T10:42:55.877-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><category domain="http://www.blogger.com/atom/ns#">jquery ui</category><title>Image slideshow with jQuery UI effects</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/jquery-slideshow.jpg" alt="" class="aligncenter spaced" /&gt;jQuery UI come bundled with an outstanding set of visual effects. In this article I'll show you how to apply such effects to a jQuery image slideshow. As you will see, results won't disappoint you.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;The markup&lt;/h2&gt;

&lt;p&gt;First, our base markup structure:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;

 &amp;lt;div id=&amp;quot;slideshow-wrapper&amp;quot;&amp;gt;
 
  &amp;lt;img src=&amp;quot;img/1.jpg&amp;quot; alt=&amp;quot;Lorem ipsum sit&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/2.jpg&amp;quot; alt=&amp;quot;Etiam autem et dolor lorem ipsum sit&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/3.jpg&amp;quot; alt=&amp;quot;Iban forte sicut meus est mos&amp;quot; /&amp;gt;
  &amp;lt;img src=&amp;quot;img/4.jpg&amp;quot; alt=&amp;quot;Nescio quid meditans&amp;quot; /&amp;gt;
  
  &amp;lt;div id=&amp;quot;caption&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
  
 &amp;lt;/div&amp;gt;

&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;After this, we need to include all the required JavaScript files in our page:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/jquery.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/jquery.effects.core.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/jquery.effects.blind.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/jquery.effects.clip.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/jquery.effects.drop.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;js/jquery.effects.explode.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;slideshow.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/pre&gt;

&lt;p&gt;We'll use the &lt;code&gt;blind&lt;/code&gt;, &lt;code&gt;clip&lt;/code&gt;, &lt;code&gt;drop&lt;/code&gt; and &lt;code&gt;explode&lt;/code&gt; jQuery UI effects. Since we have four images, we're going to use a different effect on each image.&lt;/p&gt;

&lt;h2&gt;The CSS styles&lt;/h2&gt;

&lt;p&gt;Our CSS styles are really simple:&lt;/p&gt;

&lt;pre&gt;
#slideshow {
 width: 900px;
 height: 558px;
 margin: 3em auto;
 position: relative;
 background: url(img/bg.jpg) no-repeat;
}

#slideshow-wrapper {
 width: 400px;
 height: 360px;
 position: absolute;
 top: 50%;
 left: 50%;
 margin: -180px 0 0 -200px;
}

#slideshow-wrapper img {
 display: none;
}

#slideshow-wrapper #caption {
 text-align: center;
 padding: 5px 0;
 font: 1.4em serif;
 display: none;
}
&lt;/pre&gt;

&lt;h2&gt;The jQuery code&lt;/h2&gt;

&lt;p&gt;In our file called &lt;code&gt;slideshow.js&lt;/code&gt; we have to associate a different effect to each image. For that reason, we'll use a cyclic timer which increments (and resets) a counter that will be used to select the current image.&lt;/p&gt;

&lt;p&gt;We also need to change the text of our caption using the &lt;code&gt;alt&lt;/code&gt; attribute of the current image. Here's the code:&lt;/p&gt;

&lt;pre&gt;
var Slideshow = new function() {

 var wrapper = $('#slideshow-wrapper', document.getElementById('slideshow')),
  images = $('img', wrapper),
  caption = $('#caption', wrapper),
  index = -1,
  timer = null;
  
 var showImage = function(i) {
 
  var image = images.eq(i);
  var text = image.attr('alt');
  
  images.hide();
  caption.hide();
  
  switch(i) {
  
   case 0:
   
   
   
   image.effect('explode',
        {
          mode: 'show',
          pieces: 4
        }, 1000, function() {
   caption.text(text).fadeIn(1000);
   
   
   });
   
   break;
   
   case 1:
   
   
   
   image.effect('drop',
        {
          mode: 'show',
          direction: 'bottom'
        }, 1000, function() {
   caption.text(text).fadeIn(1000);
   
   });
   
   break;
   
   
   case 2:
   
   
   
   image.effect('clip',
        {
          mode: 'show',
          direction: 'vertical'
        }, 1000, function() {
       caption.text(text).fadeIn(1000);
       });
   
   break;
   
   
   case 3:
   
   
   
   image.effect('blind',
        {
          mode: 'show',
          direction: 'vertical'
        }, 1000, function() {
   caption.text(text).fadeIn(1000);
   
   });
   
   break;

      
  
  
  }
 
 
 };
 
 var slide = function() {
 
 
  timer = setInterval(function() {
  
   index++;
   
   if(index == images.length) {
   
    index = -1;
   
   }
   
   showImage(index);
  
  }, 2000);
 
 
 };
 
 this.init = function() {
 
  slide();
 
 };


}();

$(function() {

 Slideshow.init();

});
&lt;/pre&gt;

&lt;p&gt;You can see the results below.&lt;/p&gt;

&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-immagini-effetti-jquery-ui/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-immagini-effetti-jquery-ui/jquery-slideshow-immagini-effetti-jquery-ui.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-6517213254632371263?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/dbQ4u3LO8NQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/dbQ4u3LO8NQ/image-slideshow-with-jquery-ui-effects.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/image-slideshow-with-jquery-ui-effects.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-1290994194058550463</guid><pubDate>Thu, 09 Feb 2012 06:52:00 +0000</pubDate><atom:updated>2012-02-08T22:52:12.969-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><title>WordPress: the_post() in depth</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/wordpress-folder.png" alt="" class="aligncenter spaced" /&gt;&lt;code&gt;the_post()&lt;/code&gt;, as a matter of fact, is the most used WordPress function in any theme but also almost unknown to the masses. We all know that this function initializes The Loop, but we actually don't know what kind of internal routines it uses. Let's see them together.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;This function is defined within the core &lt;code&gt;wp-includes/query.php&lt;/code&gt; file. This file, in turn, contains the definition of the famous &lt;code&gt;WP_Query&lt;/code&gt; class, namely the main engine of the WordPress Loop.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;the_post()&lt;/code&gt; is both defined as an external function and as a method of the aforementioned class. &lt;code&gt;the_post()&lt;/code&gt; relies on the following code:&lt;/p&gt;

&lt;pre&gt;
/**
  * Sets up the current post.
  *
  * Retrieves the next post, sets up the post, sets the 'in the loop'
  * property to true.
  *
  * @since 1.5.0
  * @access public
  * @uses $post
  * @uses do_action_ref_array() Calls 'loop_start' if loop has just started
  */
 function the_post() {
  global $post;
  $this-&amp;gt;in_the_loop = true;

  if ( $this-&amp;gt;current_post == -1 ) // loop has just started
   do_action_ref_array('loop_start', array(&amp;$this));

  $post = $this-&amp;gt;next_post();
  setup_postdata($post);
 }
&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;WP_Query::the_post()&lt;/code&gt; sets a Boolean flag to notify other class members that we're in the Loop, Then it checks whether The Loop has started and sets the current post by moving each time to the next post in the queue, until the post queue ends.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;the_post()&lt;/code&gt; itself, instead, is defined as follows:&lt;/p&gt;

&lt;pre&gt;
/**
 * Iterate the post index in the loop.
 *
 * @see WP_Query::the_post()
 * @since 1.5.0
 * @uses $wp_query
 */
function the_post() {
 global $wp_query;

 $wp_query-&amp;gt;the_post();
}
&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;$wp_query&lt;/code&gt; is an instance of the &lt;code&gt;WP_Query&lt;/code&gt; class. Bear in mind, however, that this class uses a backward-compatible object-oriented notation (as of PHP 4), not the latest OO features available in PHP 5.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-1290994194058550463?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/1qgjHhCglXs" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/1qgjHhCglXs/wordpress-thepost-in-depth.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/wordpress-thepost-in-depth.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-4467046384840637297</guid><pubDate>Wed, 08 Feb 2012 16:15:00 +0000</pubDate><atom:updated>2012-02-08T08:15:20.461-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>CSS reset considered evil</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/css-code.jpg" alt="" class="aligncenter spaced" /&gt;CSS resets are wrongly considered as a necessary part of any CSS template. After fixing a long series of WordPress themes that relied massively on this feature, I have to say that CSS resets are evil. More precisely, they're overused even when they're not necessary. Let me put it in this way: are we absolutely sure that all HTML elements must be reset? Are we absolutely sure that, in any circumstances and templates, we have to normalize the default rendering of all elements? Are we absolutely sure that all the default styles used by browsers on all elements need to be reduced to a lowest common denominator? Or, more properly, should we start rethinking the whole process behind normalization and realize that perhaps some default styles might be useful in some cases?&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;Consider the example of a navigation menu. After normalizing all the lists, we can simply write:&lt;/p&gt;

&lt;pre&gt;
ul#nav {
 height: 2em;
}
&lt;/pre&gt;

&lt;p&gt;instead of:&lt;/p&gt;

&lt;pre&gt;
ul#nav {
 margin: 0;
 padding: 0;
 list-style: none;
 height: 2em;
}
&lt;/pre&gt;

&lt;p&gt;That's a good point for the CSS reset approach. But there's a drawback: since you've reset all the lists, you have to specify again their base styles when you actually want a list to be displayed as usual:&lt;/p&gt;

&lt;pre&gt;
#content div.post ul {
 margin: 1em 0 1em 2.5em;
 list-style: disc;
}
&lt;/pre&gt;

&lt;p&gt;Is it really a good point for using a global reset? I don't think so. Moreover, if you reset some particular HTML elements used by a couple of popular CMS (including WordPress), you'll probably get into trouble when your clients copy and paste a formatted text document into the CMS editor.&lt;/p&gt;

&lt;p&gt;If you write this:&lt;/p&gt;

&lt;pre&gt;
b,i {
 font-weight: normal;
 font-style: normal;
}
&lt;/pre&gt;

&lt;p&gt;you can say goodbye to the basic bold and italic styles of such elements. Are you sure that you actually love trying to figure out what's wrong with your theme only to find out that it's all caused by two simple CSS rules? I guess your clients will love it too.&lt;/p&gt;

&lt;p&gt;Another interesting thing happens when you reset the base font size of the headings to 100%. The following declaration is global:&lt;/p&gt;

&lt;pre&gt;
h1, h2, h3, h4, h5, h6 {
 font-size: 100%;
}
&lt;/pre&gt;

&lt;p&gt;But there's no actual need to do this because the following standard reset:&lt;/p&gt;

&lt;pre&gt;
body {
 font-size: 62.5%;
}
&lt;/pre&gt;

&lt;p&gt;automatically normalizes your base font size so that browsers can actually calculate the following rule correctly:&lt;/p&gt;

&lt;pre&gt;
h1 {
 font-size: 2em;
}
&lt;/pre&gt;

&lt;p&gt;In other words, CSS resets are not necessary. More surprisingly, CSS resets don't take into account the effective normalization of form elements:&lt;/p&gt;

&lt;pre&gt;
input, select {
 font: 1em Arial, sans-serif; /* normalizes height */
 vertical-align: middle; /* inline elements */
}

textarea {
 display: block;
 overflow: auto;
 font: 1em Arial, sans-serif; /* default font is monospaced */
}

input:focus {
 outline-style: none;
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-4467046384840637297?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/0WdLAIXvn3g" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/0WdLAIXvn3g/css-reset-considered-evil.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/css-reset-considered-evil.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-6773807082454539949</guid><pubDate>Mon, 06 Feb 2012 15:55:00 +0000</pubDate><atom:updated>2012-02-06T07:55:01.078-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>Alternatives to CSS hacks</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/css-hacks.jpg" alt="" class="aligncenter spaced" /&gt;The so-called &amp;quot;CSS hacks&amp;quot; are particular patterns used by authors to deliver style rules only to one
browser or to prevent a browser from reading certain rules that might cause rendering problems.
These patterns may rely on parsing bugs, wrong &lt;acronym title="Document Object Model"&gt;DOM&lt;/acronym&gt; implementations or
syntactical constructs supported only by the targeted browser. Hacks may validate or not.
In this article I'll review the most popular hacks used by authors, explaining why such patterns
should be avoided and how one can actually target a browser by deploying other techniques.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;The Box Model hack&lt;/h2&gt;

&lt;p&gt;This hack is used in order to hide style rules from Internet Explorer 5 Windows. It relies on a parsing bug
related to the correct handling of escaped sequences inside strings. The pattern is the following:&lt;/p&gt;

&lt;pre&gt;
body {
 font-size: x-small;
 voice-family: "\"}\"";
 voice-family: inherit;
 font-size: small;
}
&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;voice-family&lt;/code&gt; property is used only as a container of the escaped sequence,
since this is an aural property that has no effect on the visual rendering of a document
(note, however, that its first value is then overridden by the &lt;code&gt;inherit&lt;/code&gt; value).
Internet Explorer 5 reads first the '{' token (interpreted as the end of the declaration block) and then
an escape ('\') that hides the following declarations. In other words, Explorer 5 can only read the first
declaration of the block.&lt;/p&gt;

&lt;h2&gt;The Tan hack&lt;/h2&gt;

&lt;p&gt;This hack is used in order to hide style rules from Internet Explorer 5 Windows. It relies on a parsing bug
related to the correct handling of escapes inside property names. The pattern is the following:&lt;/p&gt;

&lt;pre&gt;
#box {
 width: 200px;
 w\idth: 180px;
}
&lt;/pre&gt;

&lt;p&gt;An important thing to keep in mind is the exact placement of the escape character. 
Explorer 5 ignores the declaration only when the escape is inside the property name
and comes before any alphabetical character except of a, b, c, d, e, f. In fact, these
six alphabetical characters will be interpreted as hexadecimal Unicode characters, undoing the hack.
However, this hack is not valid, since the escaped property name will be interpreted as malformed.&lt;/p&gt;

&lt;h2&gt;The Star-HTML hack&lt;/h2&gt;
&lt;p&gt;This hack is used in order to deliver style rules only to Internet Explorer 6 (and lower). It relies
on a wrong DOM implementation that affects Explorer since 1997. According to the specifications,
the actual root element of any well-formed (X)HTML document is the &lt;code&gt;html&lt;/code&gt; element. Instead,
Explorer 6 (and lower) considers the &lt;code&gt;html&lt;/code&gt; element as wrapped in another unknown element. The pattern
is the following:&lt;/p&gt;

&lt;pre&gt;
* html #box {width: 200px}
&lt;/pre&gt;

&lt;p&gt;Variants of this pattern are now used in order to target Internet Explorer 7. The patterns are the following:&lt;/p&gt;

&lt;pre&gt;
*:first-child + html #box {width: 200px}
* + html #box {width: 200px}
&lt;/pre&gt;

&lt;h2&gt;CSS soup: hacks drawbacks&lt;/h2&gt;
&lt;p&gt;Hacks should be avoided for the following practical reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Hacks are a &lt;em&gt;short-term solution&lt;/em&gt;. They work as long as a browser supports (or doesn't support) a particular
feature or is affected by a particular bug. Browsers are changing and their CSS support is still improving. Hacks give no
guarantee for the future.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hacks make a style sheet &lt;em&gt;more difficult to read&lt;/em&gt; and even &lt;em&gt;more difficult to be maintained&lt;/em&gt;.
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are other techniques for addressing our problems with CSS, as we'll see in the next section.&lt;/p&gt;

&lt;h2&gt;A different approach&lt;/h2&gt;
&lt;p&gt;Since the overwhelming majority of CSS problems are usually related to the CSS support of Internet Explorer, we can address such
problems by using conditional comments to deliver particular styles only to Internet Explorer. Example:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;head&amp;gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;styles.css&amp;quot; type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot; /&amp;gt;
&amp;lt;!--[if lt IE 8]&amp;gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;ie.css&amp;quot; type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot; /&amp;gt;
&amp;lt;![endif]--&amp;gt;
&amp;lt;/head&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Since the second style sheet will be read only by Internet Explorer, we can use hacks inside it to deliver style rules to a specific
version of Internet Explorer. For example:&lt;/p&gt;

&lt;pre&gt;
* html p {color: green} /* IE6 and lower */
* + html p {color: olive} /* IE7 */
&lt;/pre&gt;

&lt;p&gt;To deliver style rules to browsers other than Internet Explorer, we can use JavaScript (or a more powerful server-side language)
to fulfill this task. The browser detection problem can be addressed through a simple object detection or more complicated string
search routines. A simple object detection routine for the Opera browser is shown in the following example.&lt;/p&gt;

&lt;pre&gt;
if(window.opera) {
 var head = document.getElementsByTagName("head")[0];
 var css = document.createElement("link");
 css.setAttribute("rel", "stylesheet");
 css.setAttribute("href", "opera.css");
 css.setAttribute("type", "text/css");
 css.setAttribute("media", "screen");
 head.appendChild(css);
}
&lt;/pre&gt;

&lt;p&gt;Note that in this example we've used the &lt;acronym title="World Wide Web Consortium"&gt;W3C&lt;/acronym&gt; DOM standard methods to attach
a style sheet to the current document, since the overused &lt;code&gt;document.write()&lt;/code&gt; method is not allowed when serving a document
as &lt;code&gt;application/xhtml+xml&lt;/code&gt;. In fact, we cannot add content to the document while the parsing process is still running.&lt;/p&gt;

&lt;p&gt;Finally, we can also use regular expressions in order to find a particular string inside the &lt;code&gt;userAgent&lt;/code&gt; property of the
&lt;code&gt;navigator&lt;/code&gt; object. The following example attaches a style sheet for the Firefox browser.&lt;/p&gt;

&lt;pre&gt;
var ua = /Firefox/.test(navigator.userAgent);
if (ua) {
 var head = document.getElementsByTagName("head")[0];
 var css = document.createElement("link");
 css.setAttribute("rel", "stylesheet");
 css.setAttribute("href", "firefox.css");
 css.setAttribute("type", "text/css");
 css.setAttribute("media", "screen");
 head.appendChild(css);
}
&lt;/pre&gt;

&lt;p&gt;On the server side you can either use the PHP's super-global &lt;code&gt;$_SERVER['HTTP_USER_AGENT']&lt;/code&gt; value or the &lt;a href="http://php.net/manual/en/function.get-browser.php"&gt;get_browser()&lt;/a&gt; function:&lt;/p&gt;

&lt;pre&gt;
echo $_SERVER['HTTP_USER_AGENT'] . "\n\n";

$browser = get_browser(null, true);
print_r($browser);
&lt;/pre&gt;

&lt;p&gt;This will output:&lt;/p&gt;

&lt;pre&gt;
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040803 Firefox/0.9.3

Array
(
    [browser_name_regex] =&amp;gt; ^mozilla/5\.0 (windows; .; windows nt 5\.1; .*rv:.*) gecko/.* firefox/0\.9.*$
    [browser_name_pattern] =&amp;gt; Mozilla/5.0 (Windows; ?; Windows NT 5.1; *rv:*) Gecko/* Firefox/0.9*
    [parent] =&amp;gt; Firefox 0.9
    [platform] =&amp;gt; WinXP
    [browser] =&amp;gt; Firefox
    [version] =&amp;gt; 0.9
    [majorver] =&amp;gt; 0
    [minorver] =&amp;gt; 9
    [cssversion] =&amp;gt; 2
    [frames] =&amp;gt; 1
    [iframes] =&amp;gt; 1
    [tables] =&amp;gt; 1
    [cookies] =&amp;gt; 1
    [backgroundsounds] =&amp;gt;
    [vbscript] =&amp;gt;
    [javascript] =&amp;gt; 1
    [javaapplets] =&amp;gt; 1
    [activexcontrols] =&amp;gt;
    [cdf] =&amp;gt;
    [aol] =&amp;gt;
    [beta] =&amp;gt; 1
    [win16] =&amp;gt;
    [crawler] =&amp;gt;
    [stripper] =&amp;gt;
    [wap] =&amp;gt;
    [netclr] =&amp;gt;
)
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-6773807082454539949?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/wylfK3gGzWQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/wylfK3gGzWQ/alternatives-to-css-hacks.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/alternatives-to-css-hacks.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-1104148122430662942</guid><pubDate>Sun, 05 Feb 2012 10:08:00 +0000</pubDate><atom:updated>2012-02-05T02:08:09.714-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><title>WordPress: compact posts</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/wordpress-tweak.jpg" class="aligncenter spaced" alt="" /&gt;WordPress posts are usually displayed as full posts. Now let's say that we want to display them in a compact way, e.g. the first post in full followed by an unordered list of posts which also feature a post thumbnail. Let's see the details.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;We can add the following code to the &lt;code&gt;functions.php&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;
function compact_posts() {

 $first_loop = new WP_Query(array('posts_per_page' =&amp;gt; 1));
 $id = null;
 if($first_loop-&amp;gt;have_posts()) {
 
  while ($first_loop-&amp;gt;have_posts()) : $first_loop-&amp;gt;the_post();
     $id = get_the_ID();
   ?&amp;gt;
  
  &amp;lt;div class=&amp;quot;post-single&amp;quot;&amp;gt;
    &amp;lt;h2&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;?php the_permalink() ?&amp;gt;&amp;quot; title=&amp;quot;&amp;lt;?php the_title(); ?&amp;gt;&amp;quot; rel=&amp;quot;bookmark&amp;quot;&amp;gt;&amp;lt;?php the_title(); ?&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/h2&amp;gt;
    
    &amp;lt;?php if ( has_post_thumbnail() ) {?&amp;gt;
    
      &amp;lt;?php if(is_home()) {?&amp;gt;
    
      &amp;lt;div class=&amp;quot;featured-thumbnail&amp;quot;&amp;gt;
       &amp;lt;?php the_post_thumbnail(array(220,180));?&amp;gt;
      &amp;lt;/div&amp;gt;
      
      &amp;lt;?php }?&amp;gt;
      
    &amp;lt;?php } ?&amp;gt;
    
    &amp;lt;div class=&amp;quot;post-meta&amp;quot;&amp;gt;
     &amp;lt;span class=&amp;quot;date&amp;quot;&amp;gt;&amp;lt;?php the_time('F j, Y');?&amp;gt;&amp;lt;/span&amp;gt; &amp;lt;span class=&amp;quot;author&amp;quot;&amp;gt;&amp;lt;?php _e(', by '); the_author_posts_link(); ?&amp;gt;&amp;lt;/span&amp;gt;
     &amp;lt;span class=&amp;quot;comments&amp;quot;&amp;gt;&amp;lt;?php comments_popup_link('No Comments', '1 Comment', '% Comments'); ?&amp;gt;&amp;lt;/span&amp;gt;
     &amp;lt;span class=&amp;quot;category&amp;quot;&amp;gt;&amp;lt;?php _e('Categories: '); the_category(', ') ?&amp;gt;&amp;lt;/span&amp;gt;
     &amp;lt;span class=&amp;quot;tags&amp;quot;&amp;gt;&amp;lt;?php if (the_tags('Tags: ', ', ', ' ')); ?&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;quot;post-content&amp;quot;&amp;gt;
     &amp;lt;?php the_content(__('Read more'));?&amp;gt;
    &amp;lt;/div&amp;gt;
    
   &amp;lt;/div&amp;gt;
   
   &amp;lt;?php
      endwhile;
       wp_reset_query();
    }
    
    $second_loop = new WP_Query(array('posts_per_page' =&amp;gt; 4, 'post__not_in' =&amp;gt; array($id)));
    
    if($second_loop-&amp;gt;have_posts()) {?&amp;gt;
    
    &amp;lt;div id=&amp;quot;other-posts&amp;quot;&amp;gt;    
    &amp;lt;h2&amp;gt;Other posts&amp;lt;/h2&amp;gt;
    
    &amp;lt;ul&amp;gt;&amp;lt;?php
 
   while ($second_loop-&amp;gt;have_posts()) : $second_loop-&amp;gt;the_post();?&amp;gt;
   
   &amp;lt;li&amp;gt;&amp;lt;?php the_post_thumbnail(array(70,70));?&amp;gt;&amp;lt;a href=&amp;quot;&amp;lt;?php the_permalink();?&amp;gt;&amp;quot; rel=&amp;quot;bookmark&amp;quot;&amp;gt;&amp;lt;?php the_title();?&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
   
  &amp;lt;?php
  
      endwhile;
       wp_reset_query();
       
             echo '&amp;lt;/ul&amp;gt;&amp;lt;/div&amp;gt;' . &amp;quot;\n&amp;quot;;
             
         } 
   
    
    



}
&lt;/pre&gt;

&lt;p&gt;We've used two Loops here: the last Loop excludes the first post (previously fetched) by using its ID stored in the &lt;code&gt;$id&lt;/code&gt; variable. Then we can add our function to the main &lt;code&gt;index.php&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;?php
if(is_home()) {

    compact_posts();

}
?&amp;gt;
&lt;/pre&gt;

&lt;p&gt;You can see the result below.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/wordpress-compact-posts.png" alt="" class="wide" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-1104148122430662942?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/h6W_V6nmGI8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/h6W_V6nmGI8/wordpress-compact-posts.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/wordpress-compact-posts.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-64441199016233077</guid><pubDate>Sat, 04 Feb 2012 20:28:00 +0000</pubDate><atom:updated>2012-02-04T12:28:52.709-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><title>WordPress: how  the eShop plugin works</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/wordpress_e-commerce.jpg" alt="" class="aligncenter spaced" /&gt;The most interesting working experience had so far with WordPress is surely the radical changes I had to make to the &lt;cite&gt;eShop&lt;/cite&gt; plugin. A client wanted that instead of processing orders the plugin should send an e-mail with a pre-order receipt. Further, the shopping cart must be modified so that it can accept a discounted value for each item. Said that, let's see how eShop works.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;eShop structure&lt;/h2&gt;

&lt;p&gt;eShop has the following structure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;archive-class.php&lt;/code&gt;
&lt;p&gt;Order download handler (as compressed or CSV files).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;authorizenet.php&lt;/code&gt;
&lt;p&gt;Payment handler with authorize.net.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;bank.php&lt;/code&gt;
&lt;p&gt;Bank payment handler.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cart-functions.php&lt;/code&gt;
&lt;p&gt;Cart functions. It performs the following operations:
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;displays the shopping cart&lt;/li&gt;
&lt;li&gt;calculates total and sub-total price&lt;/li&gt;
&lt;li&gt;sums up all cart items&lt;/li&gt;
&lt;li&gt;if present, it calculates the discount for each item&lt;/li&gt;
&lt;li&gt;checks whether a product has delivery costs&lt;/li&gt;
&lt;li&gt;applies the discount code&lt;/li&gt;
&lt;li&gt;checks whether a discount code is valid&lt;/li&gt;
&lt;li&gt;calculates the delivery costs for each country&lt;/li&gt;
&lt;li&gt;data validation&lt;/li&gt;
&lt;li&gt;inserts &lt;code&gt;hidden&lt;/code&gt; fields to process cart data&lt;/li&gt;
&lt;li&gt;saves the order in the database&lt;/li&gt;
&lt;li&gt;fetches the product thumbnail&lt;/li&gt;
&lt;li&gt;processes the shopping cart&lt;/li&gt;
&lt;li&gt;notifies users via e-mail&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;cash.php&lt;/code&gt;
&lt;p&gt;Payment registration.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;checkout.php&lt;/code&gt;
&lt;p&gt;Checkout handler.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eShop-add-cart.php&lt;/code&gt;
&lt;p&gt;This file determines how a product should be added to the cart.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eShop-admin-functions.php&lt;/code&gt;
&lt;p&gt;Back-end administration functions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eShop-all-data.php&lt;/code&gt;
&lt;p&gt;Database operations. It also provides a way to export data as CSV.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eShop-base.php&lt;/code&gt;
&lt;p&gt;Basic administrative functions.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eShop-dashboard.php&lt;/code&gt;
&lt;p&gt;Dashboard widgets.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eShop-discount-codes.php&lt;/code&gt;
&lt;p&gt;Discount code handler.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eShop-downloads.php&lt;/code&gt;
&lt;p&gt;Download handler for orders and products.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eShop-email.php&lt;/code&gt;
&lt;p&gt;User's e-mail handler.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eShop-user-orders.php&lt;/code&gt;
&lt;p&gt;Displays a summary of all orders for users and administrators.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;eShop.php&lt;/code&gt;
&lt;p&gt;Main file.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public-functions.php&lt;/code&gt;
&lt;p&gt;AJAX code in jQuery for the cart.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;Shopping cart&lt;/h2&gt;

&lt;p&gt;You can access all the items contained in the eShop shopping cart as follows:&lt;/p&gt;

&lt;pre&gt;
$shopping_cart = $_SESSION['eShopcart'.$blog_id];
&lt;/pre&gt;

&lt;p&gt;The shopping cart itself is a multidimensional associative array which you can navigate as follows:&lt;/p&gt;

&lt;pre&gt;
foreach($shopping_cart as $product =&amp;gt; $value) {

 $product_id = $value['postid'];
    $price = $value['price'];
    $quantity = $value['qty'];
    $product_name = $value['pname'];
    $product_desc = $value['item'];

}
&lt;/pre&gt;

&lt;p&gt;Remember: you can see the contents of the cart by simply printing it to the page whenever you want to (e.g. for testing purpose):&lt;/p&gt;

&lt;pre&gt;
print_r($_SESSION['eShopcart'.$blog_id]);
&lt;/pre&gt;

&lt;p&gt;As you can see, the whole cart is stored in the current PHP session. So if you want to empty the cart, you can do the following:&lt;/p&gt;

&lt;pre&gt;
unset($_SESSION['eShopcart'.$blog_id]);
$_SESSION['eShopcart'.$blog_id] = array();
&lt;/pre&gt;

&lt;p&gt;You can even add custom items to the cart by modifying the associative array. For example, in the &lt;code&gt;checkout.php&lt;/code&gt; file you can add the following:&lt;/p&gt;

&lt;pre&gt;
$shopping_cart = $_SESSION['eShopcart'.$blog_id];

if(isset($_POST['custom-discount'])) {    
              $custom = $_POST['custom-discount'];
            
              $discount = -1;
              
            
           foreach($shopping_cart as $item =&amp;gt; $value) {
                
               $discount++;
                    
                    if($custom[$discount] != '') {
                        
                        
                        $val = $custom[$discount];
                        
                            
                        $shopping_cart[$item]['custom-discount'] = $val;   
                            
                        
                    }
                    
                    

                
            } 
            
             
}
&lt;/pre&gt;

&lt;p&gt;Now our cart contains another item for each product, that is, &lt;code&gt;custom-discount&lt;/code&gt;. Bear in mind that if you have access to the shopping cart, you have also access to many interesting data related to each product. For example, you can get the thumbnail associated to each product (which is usually handled as a post):&lt;/p&gt;

&lt;pre&gt;
foreach($shopping_cart as $product =&amp;gt; $value) {

 $product_id = $value['postid'];
    $product_image = get_the_post_thumbnail($product_id, array(150,150));

}
&lt;/pre&gt;

&lt;p&gt;To sum up: if you understand properly how the eShop's shopping cart works, you have a fantastic tool in your hands for customizing this plugin.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-64441199016233077?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/BWKDOEuELR4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/BWKDOEuELR4/wordpress-how-eshop-plugin-works.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/wordpress-how-eshop-plugin-works.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-5690942223650692076</guid><pubDate>Sat, 04 Feb 2012 18:37:00 +0000</pubDate><atom:updated>2012-02-04T10:37:19.446-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: slot machine slideshow</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/12/slot-machine.jpg" alt="" class="wide spaced" /&gt;I'm currently working on a complex WordPress slideshow and in the meantime I'm also doing some preparatory testing. As a result, I've created a really simple jQuery slideshow that emulates the basic behavior of a slot machine thanks to the jQuery's &lt;cite&gt;Easing&lt;/cite&gt; plugin. Let's see the details.&lt;/p&gt;
&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;An hypothetic markup structure would be the following:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;div id=&amp;quot;slideshow&amp;quot;&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;up&amp;quot;&amp;gt;Up&amp;lt;/a&amp;gt;
 &amp;lt;div id=&amp;quot;slideshow-wrapper&amp;quot;&amp;gt;
 
    &amp;lt;div id=&amp;quot;slides&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;slide&amp;quot;&amp;gt;...&amp;lt;/div&amp;gt;
      &amp;lt;!--more slides--&amp;gt;
    &amp;lt;/div&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;a href=&amp;quot;#&amp;quot; id=&amp;quot;down&amp;quot;&amp;gt;Down&amp;lt;/a&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;With the following CSS styles:&lt;/p&gt;

&lt;pre&gt;
#slideshow {
 margin: 2em auto;
 width: 400px;
 overflow: hidden;
 position: relative;
}

#up, #down {
 display: block;
 width: 34px;
 height: 34px;
 margin-left: auto;
 margin-right: auto;
 text-indent: -1000em;
}

#up {
 margin-bottom: 1em;
 background: url(img/up.png) no-repeat;
}

#down {
 margin-top: 1em;
 background: url(img/down.png) no-repeat;
}

#slideshow-wrapper {
 width: 400px;
 height: 150px;
 overflow: hidden;
 position: relative;
 border-top: 1px solid;
 border-bottom: 1px solid;
}

#slides {
 width: 400px;
 height: 750px;
 position: relative;
}

div.slide {
 width: 400px;
 height: 150px;
}
&lt;/pre&gt;

&lt;p&gt;Nothing unusual here: the vertical overflow of the slide container has been hidden to show only one slide at time. Relative positioning set on the container has two purposes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;it allows us to make the container itself move vertically&lt;/li&gt;
&lt;li&gt;it automatically set a value for the &lt;code&gt;top&lt;/code&gt; property of each slide (handled by jQuery)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then we must include jQuery and the Easing plugin just before our code:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;jquery.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;jquery.easing.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;jquery.slotmachine.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;

&lt;p&gt;To make everything work smoothly, we only need to keep track of the current index of the slide in use. In a vertical slider, both controls increment or decrement the global index. Here's the code:&lt;/p&gt;

&lt;pre&gt;
(function($) {


 $.fn.slotmachine = function(options) {
 
  var that = this;
  var settings = {
  
   up: $('#up', that),
   down: $('#down', that),
   wrapper: $('#slides', that),
   slides: $('div.slide', that),
   speed: 1000
  
  };
  
  options = $.extend(settings, options);
  
  var SlotMachine = new function() {
  
      var current = -1,
          len = options.slides.length;
  
   var move = function(element) {
   
    options.wrapper.animate({
     top: - element.position().top
    }, options.speed, 'easeOutBounce');
   
   
   };
   
   
   var controls = function() {
   
    options.up.click(function(e) {
    
     current++;
     
     if(current == len) {
     
      current = 0;
     
     }
     
     var slide = options.slides.eq(current);
     
     move(slide);
    
     e.preventDefault();
    
    });
    
    options.down.click(function(e) {
    
     current--;
     
     if(current == -1) {
     
      current = 0;
     
     }
     
     var slide = options.slides.eq(current);
     
     move(slide);
    
     e.preventDefault();
    
    });
   
   
   };
   
   this.init = function() {
   
    controls();
   
   
   };
  
  
  
  }();
  
  return that.each(function() {
  
  
   SlotMachine.init();
  
  
  });
 
 
 };



})(jQuery);
&lt;/pre&gt;

&lt;p&gt;The internal logic of the plugin is entirely handled by the &lt;code&gt;SlotMachine&lt;/code&gt; singleton object. It has two private methods and one public method (the latter simply kicks things off):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;move(element)&lt;/code&gt;: makes the wrapper move vertically by using the top offset of the current slide (passed in as its sole argument)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;controls()&lt;/code&gt;: handles the up and down buttons by incrementing or decrementing the global index, respectively&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can use this plugin as follows:&lt;/p&gt;

&lt;pre&gt;
$(function() {

 $('#slideshow').slotmachine();

});
&lt;/pre&gt;

&lt;p&gt;You can see a demo below.&lt;/p&gt;

&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-slot-machine/"&gt;Live demo&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-slideshow-slot-machine/jquery-slideshow-slot-machine.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-5690942223650692076?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/f_jNbBWXVL8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/f_jNbBWXVL8/jquery-slot-machine-slideshow.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/jquery-slot-machine-slideshow.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-4083836400383850801</guid><pubDate>Sat, 04 Feb 2012 10:33:00 +0000</pubDate><atom:updated>2012-02-04T02:33:41.827-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>CSS: a web standard in context</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/css3.jpg" alt="" class="aligncenter spaced" /&gt;In this article I'll introduce Cascading Style Sheets (CSS) through a brief
historical overview on its origin and some remarks about standards and their
usage. I'll explain what is CSS, why it's been created, why we should know CSS and,
overall, why CSS can be regarded as the present and the future of web documents.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;Content and formatting: two separate objects&lt;/h2&gt;
&lt;p&gt;A web document is, in its essence, made up by two components: the actual document's content
and the formatting presented to the user. The task of all SGML-based markup languages 
(HTML, XHTML, XML, etc.) consists of coding content by specifying its structure and the semantic
role of every single element.&lt;/p&gt;

&lt;p&gt;Content structure shows the role (or function) that each object plays in the
document's context. For example, in (X)HTML headings, paragraphs and lists are marked up
as &lt;code&gt;h1...h6&lt;/code&gt;, &lt;code&gt;p&lt;/code&gt; and &lt;code&gt;ul&lt;/code&gt; (or &lt;code&gt;ol&lt;/code&gt;, etc.), 
respectively.&lt;/p&gt;

&lt;pre&gt;
&amp;lt;body&amp;gt;
 &amp;lt;h1&amp;gt;Heading 1&amp;lt;/h1&amp;gt;
 &amp;lt;p&amp;gt;A paragraph.&amp;lt;/p&amp;gt;
 &amp;lt;h2&amp;gt;Heading 2&amp;lt;/h2&amp;gt;
 &amp;lt;p&amp;gt;A paragraph.&amp;lt;/p&amp;gt;
 &amp;lt;h3&amp;gt;Heading 3&amp;lt;/h3&amp;gt;
 &amp;lt;ul&amp;gt;
  &amp;lt;li&amp;gt;An item.&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;An item.&amp;lt;/li&amp;gt;
  &amp;lt;li&amp;gt;An item.&amp;lt;/li&amp;gt;
 &amp;lt;/ul&amp;gt;
&amp;lt;/body&amp;gt;
&lt;/pre&gt;

&lt;p&gt;By default, the visual rendering of each element is determined by the browser.
For example, headings are generally displayed in bold and have a decreasing font size.
They are separated from other elements by vertical margins like paragraphs, while lists
have markers on the left side and are pushed rightwards.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.css-zibaldone.com/articles/web-standards/figure-1.png" alt="" class="wide" /&gt;&lt;/p&gt;

&lt;p&gt;In other words, a browser uses its default rules for (X)HTML documents and renders
the document accordingly (obviously this is not the case of 
&lt;acronym title="eXtensible Markup Language"&gt;XML&lt;/acronym&gt;, since this language doesn't have
a predefined set of elements). However, an user can always change the default rendering
by setting some options in the browser's GUI (Graphical User Interface).&lt;/p&gt;

&lt;h2&gt;No more tag soup&lt;/h2&gt;
&lt;p&gt;Before the invention of CSS, authors (web designers,
web developers, content developers etc.) couldn't modify the criteria used by browsers for
document's rendering. To satisfy the increasing, visual needs of authors, new (X)HTML elements
(such as &lt;code&gt;font&lt;/code&gt;) and attributes (such as &lt;code&gt;bgcolor&lt;/code&gt;) were introduced to 
the specifications. The purpose of this addition was actually related to the visual presentation
of web documents, not to their semantic structure. However, the elements mentioned above
allowed authors only to define the foreground and background color of their pages.
There was no way of positioning elements within a page, except for the &lt;code&gt;align&lt;/code&gt;
attribute used for images. To build complete, complex and compelling layouts, authors
started relying on tables (whose actual task is to provide a structure for tabular data),
transparent images and other visual tricks that led the markup to become redundant, less
structured and even harder to read.&lt;/p&gt;

&lt;p&gt;Authors were used to insert elements without knowing and understanding their 
semantic role, but only to control the visual layout of their documents.
The structural consistence of documents was sacrificed for the design and,
consequently, the size of web pages increased exponentially with a significant waste of
bandwidth.&lt;/p&gt;

&lt;p&gt;What's more, the worldwide spread of WYSIWYG (What You See Is What You Get) editors added
a further, harmful factor to this (worst-case) scenario (such programs are visual editors that
allow authors to create web pages without editing the code, that is, without knowing markup
elements).&lt;/p&gt;

&lt;p&gt;Therefore, content became a hodgepodge of ill-formed tags that most developers call a tag
soup. Tag soup is the worst-case scenario, especially when thinking of web documents in terms
of content accessibility. Assistive technologies encounter several problems when they have
to render tag soup documents. For example, when a screen reader runs across a neverending
sequence of spacer GIFs or nested table elements, an user might lose his/her way through the
document. In other words, the content is no longer accessible, since such assistive programs
follow the source code order of a document. Even though some applications (e.g. Jaws) deploy
shortcut techniques to deal with the tag soup problem, providing a non-standard document is
the worst authoring practice. However, this scenario was only the logical consequence of
the lack of proper tools for authoring web documents by separating content from formatting.&lt;/p&gt;

&lt;h2&gt;The CSS invention&lt;/h2&gt;
&lt;p&gt;In 1996 and 1998 the World Wide Web Consortium (W3C) released the CSS1 and CSS2 specifications,
providing authors with a powerful tool that allows them to write well-formed, semantically correct
(X)HTML code, controlling at the same time the visual layout of their documents.
Conceptually speaking, CSS consists of a set of rules that instruct web browsers how to render
the content inserted in a document. In practice, CSS allows authors to specify the rendering
of each (X)HTML element.&lt;/p&gt;

&lt;p&gt;Since CSS is interpreted by the rendering engine of a web browser, CSS support has been
a real pain in the neck for a long time. Some years ago, browsers misinterpreted the specifications,
causing several problems for authors even with simple page layouts. Now the situation is
radically changed: browsers such as Internet Explorer, Firefox, Chrome, Opera, Safari and Konqueror
support CSS well and their support is still improving. Therefore, many websites with a tag soup
mentality have actually become obsolete, as Jeffrey Zeldman pointed out in his famous article
for &lt;cite&gt;Digital Web&lt;/cite&gt;.&lt;/p&gt;

&lt;p&gt;With the turn of the century, CSS gained a new level of complexity with its third release (CSS3).
Now CSS3 allows us to manipulate box and text shadows, rounded corners, gradients, graphical effects such as transitions
and transformations and even animations. And much more!&lt;/p&gt;

&lt;p&gt;The main benefit for us is a radical change of mentality. Now we can rediscover the
web.&lt;/p&gt;

&lt;h2&gt;The benefits of web standards&lt;/h2&gt;

&lt;h3&gt;Compatibility&lt;/h3&gt;
&lt;p&gt;W3C standards are the common basis for browsers and Internet devices development.
Consequently, a standard compliant site is compatible with past and future browsers and
Internet devices. Compatibility doesn't imply a pixel-perfect uniformity in rendering.
For example, a document viewed on a handheld device will appear in a different way on a computer
screen and vice versa. Nevertheless, the same document remains accessible to any (X)HTML-capable device.
&lt;/p&gt;

&lt;h3&gt;Device independence&lt;/h3&gt;
&lt;p&gt;Standard compliant documents work well on different programs and devices, such as
PCs, palmtops, cellphones and a wide range of browsers (text, aural, braille, etc.) Thanks to CSS
we can even create different presentations targeted on a specific device.&lt;/p&gt;

&lt;h3&gt;Accessibility&lt;/h3&gt;
&lt;p&gt;Standard compliance doesn't necessarily imply full accessibility, but it's only a minimum
level that allows users to fully enjoy a document even when CSS is turned off or not supported.&lt;/p&gt;

&lt;h3&gt;Code maintenance&lt;/h3&gt;
&lt;p&gt;Standard code is simpler and neater than tag soup. Each element is inserted on the basis
of its structural function and semantic meaning. Updating and modifying the code become simple
operations, since such a code doesn't mix structural and presentational elements.
What's more, standard code reduces document's size and, consequently, the amount of time required
to download a page. Keep in mind that CSS, like images, is stored in the browser cache.&lt;/p&gt;

&lt;h3&gt;Search engines indexing&lt;/h3&gt;
&lt;p&gt;As many authors know, search engines index the text contained in web documents.
When there is more text than markup, the page is better indexed. CSS allows authors to reduce
the amount of redundant markup, helping pages to be better positioned. It's important to keep
in mind that search engines tend to honour the semantic of page elements. For example, search engines
search for keywords within certain elements, such as (X)HTML headings.&lt;/p&gt;

&lt;h2&gt;A new philosophy&lt;/h2&gt;
&lt;p&gt;Standard compliance should be kept separate from mere code validation. A valid document is
only a document that honours a known DTD (Document Type Definition), that is, a formal and
prescriptive grammar that defines the syntax of a markup language (such as XHTML 1.0) and the
contextual relation between its elements. For example, a page that uses tables and spacer images
might have all its tags correctly nested, all its attributes enclosed between single or double
quotes and, say, all its elements inserted in the right context. Such a page is valid according
to the W3C validator, although there is a total and evident lack of semantic and accessibility.
In other words, standard compliance is the result of a more complex process that involves several
factors. Validation, in my opinion, constitutes only the first step of this process.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-4083836400383850801?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/FLK0d_FEzU0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/FLK0d_FEzU0/css-web-standard-in-context.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/css-web-standard-in-context.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-7415215007341552292</guid><pubDate>Sat, 04 Feb 2012 08:37:00 +0000</pubDate><atom:updated>2012-02-04T00:37:11.841-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>CSS counters tutorial</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/counters.jpg" alt="" class="wide spaced" /&gt;Counters are a powerful feature of &lt;a href="http://www.w3.org/TR/CSS21/generate.html" title="CSS generated content"&gt;generated
content&lt;/a&gt;. Through counters we can add an automatic numbering to the elements of a web document. Thanks to the &lt;code&gt;:before&lt;/code&gt; and
&lt;code&gt;:after&lt;/code&gt; pseudo-elements, the numbering will appear before or after the actual content of an element, respectively.
In this article I'll explain how to use counters by providing some useful examples.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;Adding counters to elements&lt;/h2&gt;
&lt;p&gt;The automatic numbering of &lt;acronym title="Cascading Style Sheets"&gt;CSS&lt;/acronym&gt; is controlled by two properties, 
&lt;code&gt;counter-reset&lt;/code&gt; and &lt;code&gt;counter-increment&lt;/code&gt;. Counters defined by these properties are then used with
the &lt;code&gt;counter()&lt;/code&gt; and &lt;code&gt;counters()&lt;/code&gt; functions of the &lt;code&gt;content&lt;/code&gt; property.&lt;/p&gt;


&lt;p&gt;The &lt;code&gt;counter-reset&lt;/code&gt; property can contain one or more names of counters (identifiers), optionally followed by an integer.
The integer sets the value that will be incremented by the &lt;code&gt;counter-increment&lt;/code&gt; property for any occurence of the
given element. The default value is 0. Negative values are allowed.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;counter-increment&lt;/code&gt; property is similar to the previous property. The basic difference here is that this
property actually increments a counter. Its default increment is 1. Negative values are allowed.&lt;/p&gt;

&lt;p&gt;Now we are ready to create a practical example. Given the following markup:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;dl&amp;gt;
 &amp;lt;dt&amp;gt;term&amp;lt;/dt&amp;gt;
 &amp;lt;dd&amp;gt;definition&amp;lt;/dd&amp;gt;
 &amp;lt;dt&amp;gt;term&amp;lt;/dt&amp;gt;
 &amp;lt;dd&amp;gt;definition&amp;lt;/dd&amp;gt;
 &amp;lt;dt&amp;gt;term&amp;lt;/dt&amp;gt;
 &amp;lt;dd&amp;gt;definition&amp;lt;/dd&amp;gt;
&amp;lt;/dl&amp;gt;
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing1.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;we want to add a progressive numbering (1, 2, 3) to each definition term (&lt;code&gt;dt&lt;/code&gt;) in the list. The relevant CSS is the
following:&lt;/p&gt;

&lt;pre&gt;
dl {
 counter-reset: term;
}
dt:before {
 counter-increment: term;
 content: counter(term);
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing2.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first rule in the previous listing sets a counter for the definition list. This is called a scope.
The name (an identifier) of the counter is &lt;code&gt;term&lt;/code&gt;. Keep in mind that once we've chosen a name
for our counter this must be the same also in the &lt;code&gt;counter-increment&lt;/code&gt; property (of course se should
use a meaningful name).&lt;/p&gt;

&lt;p&gt;In the second rule we attach the &lt;code&gt;:before&lt;/code&gt; pseudo-element to the &lt;code&gt;dt&lt;/code&gt; element, since we want to insert
the counter exactly before the actual content of the element. Now let's take a closer look at the second declaration of the
second rule. The &lt;code&gt;counter()&lt;/code&gt; function accepts our identifier (&lt;code&gt;term&lt;/code&gt;) as its argument and the 
&lt;code&gt;content&lt;/code&gt; property actually generates the counter.&lt;/p&gt;

&lt;p&gt;As you can see, there's no space between the number and the content of the element. If we want to add more space and, say,
a period (.) after the number, we could insert the following string in the &lt;code&gt;content&lt;/code&gt; property:&lt;/p&gt;

&lt;pre&gt;
dt:before {
 content: counter(term) ". ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing3.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that the string inside the double quotes is treated literally, that is, the space after the period is inserted
as we've typed it on the keyboard. In fact, the &lt;code&gt;content&lt;/code&gt; property can be regarded as the CSS counterpart of the
JavaScript &lt;code&gt;document.write()&lt;/code&gt; method except that this property doesn't add real content to the document. Simply put,
the &lt;code&gt;content&lt;/code&gt; property creates a mere abstraction on the document tree but it doesn't modify it.&lt;/p&gt;

&lt;p&gt;In case you're wondering, we can add more styles to counters by applying other properties to the attached pseudo-element.
For example:&lt;/p&gt;

&lt;pre&gt;
dt:before {
 content: counter(term);
 padding: 1px 2px;
 margin-right: 0.2em;
 background: #ffc;
 color: #000;
 border: 1px solid #999;
 font-weight: bold;
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing4.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've just set a background color, added some padding and a right margin, made the font bold and outlined
the counters with a thin solid border. Now our counters are a little more attractive.&lt;/p&gt;

&lt;p&gt;Furthermore, counters can be negative. When dealing with negative counters, we should only keep in mind a little maths, namely
the part concerning addition and subtraction of negative and positive numbers. For example, if we need a progressive numbering
starting from 0, we could write the following:&lt;/p&gt;

&lt;pre&gt;
dl {
 counter-reset: term -1;
}

dt:before {
 counter-increment: term;
 content: counter(term) ". ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing5.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By setting the &lt;code&gt;counter-reset&lt;/code&gt; property to -1 and incrementing it by 1, the resulting value is 0 and the numbering
will actually start from that value. Negative counters can combine with positive counters to create interesting results. Consider
the following example:&lt;/p&gt;

&lt;pre&gt;
dl {
 counter-reset: term -1;
}

dt:before {
 counter-increment: term 3;
 content: counter(term) ". ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing6.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, addition and substraction of negative and positive numbers yield a wide range of combination between counters.
With just a simple set of calculations we can get a complete control over this automatic numbering.&lt;/p&gt;

&lt;h2&gt;Nested counters&lt;/h2&gt;
&lt;p&gt;Another interesting feature of CSS counters lies in their capability of being nested. In fact, numbering may proceed also
by using progressive sublevels, such as 1.1, 1.1.1, 2.1 and so on. For example, if we want to add a sublevel to the elements of our
list, we could write the following:&lt;/p&gt;

&lt;pre&gt;
dl {
 counter-reset: term definition;
}

dt:before {
 counter-increment: term;
 content: counter(term) ". ";
}

dd:before {
 counter-increment: definition;
 content: counter(term) "." counter(definition) " ";
}

&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing7.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This example is similar to the first one, but in this case we have two counters, &lt;code&gt;term&lt;/code&gt; and &lt;code&gt;definition&lt;/code&gt;.
The scope of both counters is set by the first rule and &amp;quot;lives&amp;quot; in the &lt;code&gt;dl&lt;/code&gt; element.
The second rule inserts the first counter before each definition term of the list. This rule is not particularly interesting, since
its effect is already known. Instead, the last rule is the core of our code because it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;increments the second counter (&lt;code&gt;definition&lt;/code&gt;) on &lt;code&gt;dd&lt;/code&gt; elements&lt;/li&gt;
&lt;li&gt;inserts the first counter (&lt;code&gt;term&lt;/code&gt;), followed by a period&lt;/li&gt;
&lt;li&gt;inserts the second counter (&lt;code&gt;definition&lt;/code&gt;), followed by a space.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that steps #2 and #3 are both performed by the &lt;code&gt;content&lt;/code&gt; property used on the &lt;code&gt;:before&lt;/code&gt; pseudo-element
attached to the definition term.&lt;/p&gt;

&lt;p&gt;Another interesting thing to remember is that counters are &amp;quot;self-nesting&amp;quot; in the sense that resetting a counter
on a descendant element (or pseudo-element) automatically creates a new instance of the counter. This is useful in the case of
(X)HTML lists, where elements may be nested with arbitrary depth. However, it's not always possible to specify a different
counter for each list, since this approach might produce a really redundant code. In that vein, it's useful to mention the
&lt;code&gt;counters()&lt;/code&gt; function. This function creates a string containing all the counters having the same name of the
given counter in the scope. Counters are then separated by a string. For example, given the following markup:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;ol&amp;gt;
 &amp;lt;li&amp;gt;item&amp;lt;/li&amp;gt;
 &amp;lt;li&amp;gt;item
  &amp;lt;ol&amp;gt;
   &amp;lt;li&amp;gt;item&amp;lt;/li&amp;gt;
   &amp;lt;li&amp;gt;item&amp;lt;/li&amp;gt;
   &amp;lt;li&amp;gt;item
    &amp;lt;ol&amp;gt;
     &amp;lt;li&amp;gt;item&amp;lt;/li&amp;gt;
     &amp;lt;li&amp;gt;item&amp;lt;/li&amp;gt;
    &amp;lt;/ol&amp;gt;
   &amp;lt;/li&amp;gt;
  &amp;lt;/ol&amp;gt;
 &amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing8.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following CSS numbers the nested list items as 1, 1.1, 1.1.1, etc.&lt;/p&gt;

&lt;pre&gt;
ol {
 counter-reset: item;
}

li {
 display: block;
}

li:before {
 counter-increment: item;
 content: counters(item, ".") " ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing9.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example we have only the &lt;code&gt;item&lt;/code&gt; counter for each nesting level. Instead of writing three different counters
(e.g. &lt;code&gt;item1&lt;/code&gt;, &lt;code&gt;item2&lt;/code&gt;, &lt;code&gt;item3&lt;/code&gt;) and thus creating three different scopes for each nested &lt;code&gt;ol&lt;/code&gt; element, we can rely on the &lt;code&gt;counters()&lt;/code&gt; function to achieve this goal. The second rule is really important and
deserves a further explanation. Since ordered lists have a default marker (a number), we get rid of these marker by turning the list
items into block-level elements. Keep in mind that only elements with &lt;code&gt;display: list-items&lt;/code&gt; have markers. Now we can
look carefully at the third rule that actually does the work. The first declaration increments the counter previously set on the
outermost list. Then, in the second declaration, the &lt;code&gt;counters()&lt;/code&gt; function creates all the counter's instances for
the innermost lists. The structure of this function is as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;its first argument is the name of the given counter, immediately followed by a comma&lt;/li&gt;
&lt;li&gt;its second argument is a period inserted in double quotes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that we've inserted a space after the &lt;code&gt;counters()&lt;/code&gt; function in order to keep the numbers separate from the
actual content of the list items.&lt;/p&gt;

&lt;h2&gt;Styles of counters&lt;/h2&gt;
&lt;p&gt;Counters are formatted with decimal numbers by default. However, the styles of the &lt;code&gt;list-style-type&lt;/code&gt; property
are also available for counters. The default notation is &lt;code&gt;counter(name)&lt;/code&gt; (no style) or 
&lt;code&gt;counter(name, 'list-style-type')&lt;/code&gt; if we want to change the default formatting. In practice, the recommended styles are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;decimal&lt;/code&gt;&lt;/li&gt; 
&lt;li&gt;&lt;code&gt;decimal-leading-zero&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lower-roman&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;upper-roman&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lower-greek&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lower-latin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;upper-latin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;lower-alpha&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;upper-alpha&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;because we should always bear in mind that we're working with numeric systems. Furthermore, we should also be aware of the fact
that the specifications don't define the rendering of alphabetical systems at the end of the alphabet. For example, after 26 list
items the rendering of &lt;code&gt;lower-latin&lt;/code&gt; is undefined. Real numbers are thus recommended for long lists. Here's an
example:&lt;/p&gt;

&lt;pre&gt;
dl {
 counter-reset: term definition;
}

dt:before {
 counter-increment: term;
 content: counter(term, upper-latin) ". ";
}

dd:before {
 counter-increment: definition;
 content: counter(definition, lower-latin) ". ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing10.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also add styles to the &lt;code&gt;counters()&lt;/code&gt; function, as shown in the following example.&lt;/p&gt;

&lt;pre&gt;
li:before {
 counter-increment: item;
 content: counters(item, ".", lower-roman) " ";
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/counters/examples/listing11.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that the &lt;code&gt;counters()&lt;/code&gt; function can also accept a third argument (&lt;code&gt;lower-roman&lt;/code&gt;) as the last member of its arguments list, separated by a second
comma from the preceding period. However, the &lt;code&gt;counters()&lt;/code&gt; function doesn't allow us to specify different styles for each level of nesting.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-7415215007341552292?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/1_f8c54Vi-k" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/1_f8c54Vi-k/css-counters-tutorial.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/css-counters-tutorial.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-690046757642746341</guid><pubDate>Fri, 03 Feb 2012 18:42:00 +0000</pubDate><atom:updated>2012-02-03T10:45:07.888-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><category domain="http://www.blogger.com/atom/ns#">ajax</category><category domain="http://www.blogger.com/atom/ns#">json</category><title>jQuery: serialize a form as a JSON object</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/12/jquery-plugin.jpg" width="500" height="400" alt="" class="aligncenter spaced" /&gt;If you're using AJAX with a form and you want to pass a JSON object to one of the jQuery's AJAX methods used to process the request, you will probably wonder how this could be done. Basically, you should convert your form values to a plain array, loop through all the items in the array and finally return a plain object literal. Let's see the details.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;We can put all the aforementioned routines in a simple jQuery plugin:&lt;/p&gt;

&lt;pre&gt;
(function($) {
$.fn.serializeFormJSON = function() {

   var o = {};
   var a = this.serializeArray();
   $.each(a, function() {
       if (o[this.name]) {
           if (!o[this.name].push) {
               o[this.name] = [o[this.name]];
           }
           o[this.name].push(this.value || '');
       } else {
           o[this.name] = this.value || '';
       }
   });
   return o;
};
})(jQuery);
&lt;/pre&gt;

&lt;p&gt;We start with an empty object literal which will be populated by looping through the array returned by the &lt;code&gt;serializeArray()&lt;/code&gt; function. Here's a use case:&lt;/p&gt;

&lt;pre&gt;
$('#contact').submit(function(e) {

 var $form = $(this);
 var data = $form.serializeFormJSON();
 
 $.post('process.php', data, function(output) {
 
  // do something here
 
 });

 e.preventDefault();

});
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-690046757642746341?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/Om1IPmJIJSM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/Om1IPmJIJSM/jquery-serialize-form-as-json-object.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/jquery-serialize-form-as-json-object.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-3458499686818883298</guid><pubDate>Fri, 03 Feb 2012 10:47:00 +0000</pubDate><atom:updated>2012-02-03T02:47:39.310-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>CSS: better styling for code blocks</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/code.jpg" alt="" class="wide spaced" /&gt;In this article I'll explain how to use &lt;acronym title="Cascading Style Sheets"&gt;CSS&lt;/acronym&gt; for styling code blocks.
Code blocks are generally formatted by using the &lt;code&gt;pre&lt;/code&gt; element. &lt;cite&gt;Roger Johansson&lt;/cite&gt; has proposed another
way to accomplish this task and I'll follow his example with further improvements.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;The markup&lt;/h2&gt;

&lt;p&gt;The proposed markup for code blocks is the following:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;ol class=&amp;quot;code&amp;quot;&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;code&amp;gt;/* static */&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;
...omission...
&amp;lt;li class=&amp;quot;indent1&amp;quot;&amp;gt;&amp;lt;code&amp;gt;gLexTableSetup = PR_TRUE;&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;
...omission...
&amp;lt;li class=&amp;quot;indent2&amp;quot;&amp;gt;&amp;lt;code&amp;gt;lt[i] |= IS_IDENT | START_IDENT;&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;
...omission...
&amp;lt;li class=&amp;quot;indent3&amp;quot;&amp;gt;&amp;lt;code&amp;gt;lt[i] |= IS_HEX_DIGIT;&amp;lt;/code&amp;gt;&amp;lt;/li&amp;gt;
...omission...
&amp;lt;li id=&amp;quot;last&amp;quot;&amp;gt;...&amp;lt;/li&amp;gt;
&amp;lt;/ol&amp;gt;
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/code-blocks/examples/1/1.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since we're dealing with computer code, the most semantic way to mark it up is by using the &lt;code&gt;code&lt;/code&gt; element. Furthermore,
by using an unordered list instead of a &lt;code&gt;pre&lt;/code&gt; element we can be sure that the content of the block will not overflow its
container when we change the size of the window or the dimensions of the container itself.&lt;/p&gt;


&lt;h2&gt;General styles&lt;/h2&gt;

&lt;p&gt;The general style are really simple.&lt;/p&gt;

&lt;pre&gt;
ol.code {
background: #e7e7f5;
color: #333;
margin: 0;
padding: 0.5em;
width: 55%;
list-style: none;
}
ol.code li {
border-bottom: 1px solid #666;
}
ol.code li#last {
border-bottom: none;
}
ol.code code {
font: small "Courier New", Courier, monospace;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/code-blocks/examples/2/2.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've set a width, some padding, resetted the default margins and got rid of the list marker on the &lt;code&gt;ol&lt;/code&gt;
element. All list items will have a bottom border, except the item with the ID &lt;code&gt;#last&lt;/code&gt;. Finally, we've set
the font size and family on the &lt;code&gt;code&lt;/code&gt; element.&lt;/p&gt;

&lt;h2&gt;Creating indentations&lt;/h2&gt;

&lt;p&gt;Also this step is actually simple.&lt;/p&gt;

&lt;pre&gt;
ol.code .indent1 {
padding-left: 1em;
}
ol.code .indent2 {
padding-left: 2em;
}
ol.code .indent3 {
padding-left: 3em;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/code-blocks/examples/3/3.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've created progressive, meaningful classes to be applied to the elements in the list.
Each classes have a progressive left padding that actually creates the required indentations.&lt;/p&gt;


&lt;h2&gt;Adding a vertical scrollbar&lt;/h2&gt;

&lt;p&gt;Adding a vertical scrollbar to the code block requires only two simple declarations.&lt;/p&gt;

&lt;pre&gt;
ol.code {
height: 100px;
overflow: auto;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/code-blocks/examples/final/final.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first declaration sets an height on the list. In order to make it work, the height must be always less than
the global amount of the list's content. By doing so, browsers are forced to let the content overflow its container.
The second declaration, in fact, deals with the overflowing content through the &lt;code&gt;auto&lt;/code&gt; value of the
&lt;code&gt;overflow&lt;/code&gt; property. Since the specifications state that in case of overflowing content browsers must always
provide a scrolling mechanism for viewing the content, browsers add a vertical scrollbar to our list.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-3458499686818883298?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/IWjaMmy3FxI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/IWjaMmy3FxI/css-better-styling-for-code-blocks.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/css-better-styling-for-code-blocks.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-4884095674582558141</guid><pubDate>Wed, 01 Feb 2012 19:18:00 +0000</pubDate><atom:updated>2012-02-01T11:18:27.758-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><category domain="http://www.blogger.com/atom/ns#">css</category><title>WordPress: use a post title as a thumbnail overlay</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/wordpress-tweak.jpg" alt="" class="aligncenter spaced" /&gt;We can easily create the effect of post titles used as overlays over post thumbnails by combining a little WordPress coding and some CSS techniques. Let's see the details.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;


&lt;p&gt;In the &lt;code&gt;single.php&lt;/code&gt; you can insert the following code, where the thumbnail dimensions are purely indicative:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;div class=&amp;quot;post-thumb-title&amp;quot;&amp;gt;
 &amp;lt;?php the_post_thumbnail(array(500,470));?&amp;gt;
 &amp;lt;p class=&amp;quot;thumb-title&amp;quot;&amp;gt;&amp;lt;?php the_title(); ?&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;?php the_content(); ?&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Then add the following CSS styles to your main theme style sheet:&lt;/p&gt;

&lt;pre&gt;
/*= Post thumb with title */

div.post-thumb-title {
 width: 500px;
 margin: 1em auto;
}

div.post-thumb-title img {
 display: block;
 min-width: 100%;
}

div.post-thumb-title p.thumb-title {
 margin: 0;
 height: 2em;
 line-height: 2;
 position: relative;
 top: -2em;
 max-width: 100%;
 text-align: center;
 color: #fff;
 background: rgba(0, 0, 0, 0.7);
}
&lt;/pre&gt;

&lt;p&gt;By adjusting minimum and maximum widths with CSS, we can get the following result:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/02/wordpress-post-images-caption.jpg" alt="" class="wide" /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-4884095674582558141?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/2r-Sw9JJivw" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/2r-Sw9JJivw/wordpress-use-post-title-as-thumbnail.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/02/wordpress-use-post-title-as-thumbnail.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-7272202624652305148</guid><pubDate>Sun, 29 Jan 2012 19:44:00 +0000</pubDate><atom:updated>2012-01-29T11:44:50.235-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: AJAX contact form for WordPress</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/08/wordpress_jquery.jpg" alt="" class="aligncenter spaced"/&gt;jQuery can actually interact very well with WordPress. A typical example of this is surely a contact form enhanced with AJAX. Let's see how things work from the client-side point of view.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;The first thing to bear in mind is that a WordPress contact page is self-processed, meaning that the value of the &lt;code&gt;action&lt;/code&gt; attribute corresponds to the current page.&lt;/p&gt;

&lt;p&gt;For that reason, we need to use this value as our target URL. Then we need to attach an extra POST variable to notify the server-side script (which also handles data validation) that our form has been submitted. We also need to attach another variable to make sure that the output of the server-side script will be displayed only when the form has been actually sent:&lt;/p&gt;

&lt;pre&gt;
(function($) {


 $(function() {
 
  var Contact = function() {
  
   var form = '#contact';
   
   
   
   
   this.process = function() {
   
   
   $(form).submit(function(event) {
   
    var $form = $(this);
    var url = $form.attr('action');
    var data = 'from=' + $('#from', $form).val() + '&amp;email=' + $('#email', $form).val() +
                '&amp;subject=' + $('#subject', $form).val() +
                '&amp;message=' + $('#message', $form).val() +
                '&amp;captcha=' + $('#captcha', $form).val() +
                '&amp;contact-submit=Send&amp;ajax=true';
    
    $.ajax({
     type: 'POST',
     dataType: 'text',
     url: url,
     data: data,
     success: function(txt) {
     
         $('div.success, div.error', $form).remove();
     
      $(txt).prependTo($('ul', $form));
      
      $('html, body').animate({
       scrollTop: $form.offset().top
      }, 500);
      
     
     
     }
     
    });
    
    
    event.preventDefault();
   
   
   });
   
   }
  
  
  };
  
  var contact = new Contact();
  
  if($('#contact').length) {
  
   contact.process();
   
  }
 
 
 });


})(jQuery);
&lt;/pre&gt;

&lt;p&gt;In the &lt;code&gt;success()&lt;/code&gt; callback method we remove any message generated by the server-side script before adding further messages. Then we use the &lt;code&gt;scrollTop&lt;/code&gt; property to make the entire page scroll up to the top of the form:&lt;/p&gt;

&lt;pre&gt;
$('div.success, div.error', $form).remove();
     
$(txt).prependTo($('ul', $form));
      
$('html, body').animate({
 scrollTop: $form.offset().top
}, 500);
&lt;/pre&gt;

&lt;p&gt;You can see the demo below.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="420" height="315" src="http://www.youtube.com/embed/PFvTvuJ4Lb8?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-7272202624652305148?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/DudFuzoI6vY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/DudFuzoI6vY/jquery-ajax-contact-form-for-wordpress.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/PFvTvuJ4Lb8/default.jpg" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/jquery-ajax-contact-form-for-wordpress.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-7242249903320676094</guid><pubDate>Wed, 25 Jan 2012 18:16:00 +0000</pubDate><atom:updated>2012-01-25T10:16:08.858-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>CSS: create layouts with table values</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/images/css.png" alt="" class="alignright"/&gt;In this article I'll explain how to use the table values of the &lt;acronym title="Cascading Style Sheets"&gt;CSS&lt;/acronym&gt;
&lt;code&gt;display&lt;/code&gt; property to format certain sections of a simple three-columns layout.&lt;/p&gt; 

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;The final layout is shown in the
picture below.
&lt;/p&gt;

&lt;div class="picture"&gt;
&lt;a href="http://www.css-zibaldone.com/articles/table-values/examples/final/final.html"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/table-values/img/final.png" alt="The final layout" /&gt;
&lt;/a&gt;
&lt;/div&gt;

&lt;p&gt;The relevant sections that will be formatted with such values are highlighted in the following picture.&lt;/p&gt;

&lt;div class="picture"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/table-values/img/highlight.png" alt="Navigation, sub-header and post title" /&gt;
&lt;/div&gt;

&lt;h2 id="navigation-menu"&gt;The navigation menu&lt;/h2&gt;
&lt;p&gt;We start with the following markup:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;div id=&amp;quot;header&amp;quot;&amp;gt;
&amp;lt;h1&amp;gt;CSS Magazine&amp;lt;/h1&amp;gt;
&amp;lt;ul id=&amp;quot;nav&amp;quot;&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;strong&amp;gt;Home&amp;lt;/strong&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Articles&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Tests&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot;&amp;gt;Tutorials&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;As you can see, the navigation menu (&lt;code&gt;#nav&lt;/code&gt;) is contained in the &lt;code&gt;#header&lt;/code&gt;
section, where there is also the main title of the page (an &lt;code&gt;h1&lt;/code&gt; element. The styles could
be the following:&lt;/p&gt;

&lt;pre&gt;
#header {
height: 8em;
min-height: 80px;
border-bottom: 1px solid #333;
background: #fff url("img/banner.png") no-repeat 0 0;
position: relative;
}
#header h1 {
position: absolute;
top: -1000em;
}
#nav {
display: table;
position: absolute;
top: 0;
right: 0;
height: 100%;
border-left: 1px solid;
margin: 0;
padding: 0;
border-collapse: collapse;
width: 15%;
}
#nav li {
display: table-row;
}
#nav li a, #nav li strong {
display: table-cell;
border: 1px solid #000;
font-size: 120%;
width: 100%;
padding: 0 0.3em;
text-decoration: none;
}
#nav li a:hover {
background: #800;
color: #fff;
}
#nav li strong {
background: #800;
color: #fff;
}
&lt;/pre&gt;

&lt;p&gt;&lt;a href="http://www.css-zibaldone.com/articles/table-values/examples/3/3.html"&gt;View the example&lt;/a&gt; -
&lt;a href="http://www.css-zibaldone.com/articles/table-values/img/3.png"&gt;View the screenshot&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;The first two rules give a basic formatting to our header. We've set a height in ems and a
minimum height in pixels. The latter equals the height of the background image that we'll use as
a banner. A minimum height gives a full visibility to our background image even when the user
decreases the base font size or when the specified font used on the page is not available. The last
declaration of the first rule creates a new context positioning through the value &lt;code&gt;relative&lt;/code&gt;
of the &lt;code&gt;position&lt;/code&gt; property. Thanks to this declaration, we can absolutely position our
navigation menu by taking the header section as a reference and not the whole viewport. Then we want
to get rid of the heading's text, since it must be replaced by the background image. We use absolute
positioning with an enormous negative value for the &lt;code&gt;top&lt;/code&gt; property. This value will
actually make the text disappear from the page.&lt;/p&gt;

&lt;p&gt;Then comes our navigation menu.
The first declaration of the third rule turns our unordered list into a table.
Since we're working now with tables, we should be sure that there will be no extra space
between the cells. For that reason, we use the &lt;code&gt;border-collapse&lt;/code&gt; property set to
&lt;code&gt;collapse&lt;/code&gt;. By doing so, the borders of the single cells will collapse to form an unique
border. Tables can be floated and absolutely positioned, since they're actually block-level elements or,
more precisely, elements that work in a block-level formatting context.
Our menu will be absolutely positioned on the right and with a left border. Its height will equal the
height of its container, while its width will be 15% of the container's width.&lt;/p&gt;

&lt;p&gt;Now we need table rows to host our cells. We turn the list items into table rows by declaring
&lt;code&gt;display: table-row&lt;/code&gt; on each &lt;code&gt;li&lt;/code&gt; element.&lt;/p&gt;

&lt;p&gt;Finally, we create the table cells in the fifth rule by declaring
&lt;code&gt;display: table-cell&lt;/code&gt; on the &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;strong&lt;/code&gt; elements.
The border of these cells will collapse to form an unique border, as said above.
The width of the cells will be 100% of the total, plus a 0.3em of left and right padding.
In case you're wondering, the content of the cells will not overflow its container because of the
type of table layout set on our menu. Tables can have two types of layout, controlled by the
&lt;code&gt;table-layout&lt;/code&gt; property: &lt;code&gt;auto&lt;/code&gt; and &lt;code&gt;fixed&lt;/code&gt;. The first value
is used by default on all tables and it's used also on our menu. With this value, the global width
of the table will be determined by the width (and the content) of its single cells. In other words,
we have a fluid table that will expand automatically together with its cells.&lt;/p&gt;

&lt;h2 id="sub-header"&gt;The sub-header&lt;/h2&gt;

&lt;p&gt;The sub-header is marked up as follows:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;div id=&amp;quot;subheader&amp;quot;&amp;gt;
&amp;lt;p id=&amp;quot;issue&amp;quot;&amp;gt;Issue 1, August 2008&amp;lt;/p&amp;gt;
&amp;lt;form id=&amp;quot;search&amp;quot; action=&amp;quot;#&amp;quot;&amp;gt;
&amp;lt;div&amp;gt;
&amp;lt;label for=&amp;quot;text&amp;quot;&amp;gt;Search:&amp;lt;/label&amp;gt;
&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;text&amp;quot; id=&amp;quot;text&amp;quot; /&amp;gt;
&amp;lt;input type=&amp;quot;submit&amp;quot; id=&amp;quot;btn&amp;quot; name=&amp;quot;btn&amp;quot; value=&amp;quot;Go&amp;quot; /&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;We want to put the &lt;code&gt;#issue&lt;/code&gt; element on the left and the search form on the right.
The code could be the following:&lt;/p&gt;

&lt;pre&gt;
#subheader {
display: table;
width: 100%;
height: 1.4em;
border-bottom: 1px solid #000;
font-size: 120%;
}
#subheader #issue {
display: table-cell;
width: 30%;
vertical-align: middle;
font-weight: bold;
padding: 0 0.5em;
text-transform: uppercase;
}
#subheader form {
display: table-cell;
width: 68%;
text-align: right;
vertical-align: middle;
padding: 0.5em;
}
#subheader form label {
font-weight: bold;
}
#subheader form input {
font: 1em Verdana, sans-serif;
}
#subheader form input#text {
border: 1px solid #000;
background: #fff;
color: #333;
}
#subheader form input#btn {
background: #800;
color: #fff;
font-weight: bold;
border: 1px solid #800;
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/table-values/examples/4/4.html"&gt;View the example&lt;/a&gt; -
&lt;a href="http://www.css-zibaldone.com/articles/table-values/img/4.png"&gt;View the screenshot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first rule turns the sub-header section into a table, sets a global height and width
plus a bottom border. The second rule turns the &lt;code&gt;#issue&lt;/code&gt; element into a table cell, sets
a width on the element plus the vertical alignment of the text inside the cell (&lt;code&gt;middle&lt;/code&gt;).
The third rule turns the form into a table cell. As for the previous element, also in this case
the vertical margins of this element will be resetted, since table cells cannot have vertical margins.
The width of this element covers almost all the available space and this is actually our intended
purpose. In fact, with the declaration &lt;code&gt;text-align: right&lt;/code&gt; we push the form elements to
the right of the sub-header, as we do want. Also in this case the elements will be vertically
aligned, thanks to the declaration &lt;code&gt;vertical-align: middle&lt;/code&gt;.
The fifth rule deserves a further explanation: since the dimensions of form elements are determined
also by the type and size of the used font, a good way to get consistency across browsers is an explicit
declaration of font type/size on the elements we want to format (in this case, &lt;code&gt;input&lt;/code&gt;).&lt;/p&gt;

&lt;h2 id="post-title"&gt;The post title&lt;/h2&gt;
&lt;p&gt;The markup for this section is really simple, as you can see below.&lt;/p&gt;

&lt;pre&gt;
&amp;lt;div class=&amp;quot;art-title&amp;quot;&amp;gt;
&amp;lt;h2&amp;gt;Lorem ipsum&amp;lt;/h2&amp;gt;
&amp;lt;p class=&amp;quot;date&amp;quot;&amp;gt;8/17/2008&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;

&lt;p&gt;The post title has been inserted through a &lt;code&gt;h2&lt;/code&gt; element and the date of the post is
marked up with a paragraph having &lt;code&gt;.date&lt;/code&gt; as its own class. The styles could be the
following:&lt;/p&gt;




&lt;pre&gt;
.art-title {
background: #800;
color: #fff;
display: table;
width: 100%;
margin-top: 1em;
padding: 0.3em 0;
}
.art-title h2 {
font-size: 1.4em;
display: table-cell;
width: 40%;
vertical-align: middle;
color: #fff;
padding-left: 3px;
}
.art-title .date {
display: table-cell;
width: 60%;
vertical-align: middle;
text-align: right;
padding-right: 3px;
font-style: italic;
font-weight: bold;
}
&lt;/pre&gt;

&lt;p class="example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/table-values/examples/6/6.html"&gt;View the example&lt;/a&gt; -
&lt;a href="http://www.css-zibaldone.com/articles/table-values/img/6.png"&gt;View the screenshot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Again, we've turned the outermost container into a table and its children into table cells.
The vertical alignment of the text is controlled by the &lt;code&gt;vertical-align&lt;/code&gt; property.
The width of each element can be adjusted in order to satisfy particular needs. In this case,
we could change the value 40% with 60%, since the content of a date doesn't require so much space.&lt;/p&gt;






&lt;h3 id="download"&gt;Download&lt;/h3&gt;
&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/table-values/examples.zip"&gt;examples.zip&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-7242249903320676094?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/DQdKYSpCv-4" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/DQdKYSpCv-4/css-create-layouts-with-table-values.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/css-create-layouts-with-table-values.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-1765152487891134157</guid><pubDate>Tue, 24 Jan 2012 10:55:00 +0000</pubDate><atom:updated>2012-01-24T02:55:22.448-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><category domain="http://www.blogger.com/atom/ns#">twitter</category><title>WordPress: publish a tweet as a post</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/social-media-icons-wordpress.jpg" alt="" class="aligncenter spaced" /&gt;Twitter is surely one the most popular social networks on the web, and WordPress is surely one the most popular CMS available today. Usually these two platforms interact only in one way: you get something from Twitter, you post something on Twitter. Let's say that you want to publish your latest tweet as a post on your WordPress site, also checking if there is another brand new tweet available. How we can to this?&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;The first thing you need to do is to create a category for your tweets. Let's name this category &lt;code&gt;tweets&lt;/code&gt; and assume that its assigned category ID is 145 (you can see the ID by hovering the category link with your mouse on the WordPress backend).&lt;/p&gt;

&lt;p&gt;Then add the following code to the &lt;code&gt;functions.php&lt;/code&gt; file of your theme:&lt;/p&gt;


&lt;pre&gt;
function get_insert_latest_tweet() {
 global $wpdb;
 $post = array();
 $url = &amp;quot;http://twitter.com/statuses/user_timeline/yourusername.xml?count=1&amp;quot;;
 
 if(file_get_contents($url)) {
 
  $xml = new SimpleXMLElement(file_get_contents($url));
  $status = $xml-&amp;gt;status-&amp;gt;text;
  $time = nice_time(strtotime($xml-&amp;gt;status-&amp;gt;created_at));
  $tweet = preg_replace('/http:\/\/(.*?)\/[^ ]*/', '&amp;lt;a href=&amp;quot;\\0&amp;quot;&amp;gt;\\0&amp;lt;/a&amp;gt;', $status);
  $title = preg_replace('/http:\/\/(.*?)\/[^ ]*/', '', $status);
  
  $result = $wpdb-&amp;gt;get_row(&amp;quot;SELECT * FROM $wpdb-&amp;gt;posts WHERE post_title = '$title'&amp;quot;);
  
  $post['post_title'] = $title;
  $post['post_content'] = '&amp;lt;p&amp;gt;' . $tweet . ' &amp;lt;small&amp;gt;' . $time . '&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;';
  $post['post_status'] = 'publish';
  $post['post_category'] = array(145);
  $post['tags_input'] = 'tweet';
  
  if(is_null($result)) {
   wp_insert_post($post);
  }
  
 } else {
 
  return;
 
 }
 
 
 
}

add_action( 'pre_get_posts', 'get_insert_latest_tweet');



function nice_time($time) {
  $delta = time() - $time;
  if ($delta &amp;lt; 60) {
    return 'less than a minute ago.';
  } else if ($delta &amp;lt; 120) {
    return 'about 1 minute ago.';
  } else if ($delta &amp;lt; (45 * 60)) {
    return floor($delta / 60) . ' minutes ago.';
  } else if ($delta &amp;lt; (90 * 60)) {
    return 'about 1 hour ago.';
  } else if ($delta &amp;lt; (24 * 60 * 60)) {
    return 'about ' . floor($delta / 3600) . ' hours ago.';
  } else if ($delta &amp;lt; (48 * 60 * 60)) {
    return '1 day ago.';
  } else {
    return floor($delta / 86400) . ' days ago.';
  }
}
&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;get_insert_latest_tweet()&lt;/code&gt; create a new post from your Twitter feed through the &lt;a href="http://codex.wordpress.org/Function_Reference/wp_insert_post"&gt;wp_insert_post()&lt;/a&gt; function. Before creating a new post, though, it checks whether the current tweet has already been inserted. If so, it does nothing.&lt;/p&gt;

&lt;p&gt;The WordPress action used here is &lt;code&gt;pre_get_posts&lt;/code&gt; which means that the current tweet is fetched within your main WordPress Loop. You can change this behavior by moving the above function in a separate plugin that requires your deliberate action to create a new post from a tweet.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-1765152487891134157?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/YLn1e1SErOU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/YLn1e1SErOU/wordpress-publish-tweet-as-post.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/wordpress-publish-tweet-as-post.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-6259059497409226742</guid><pubDate>Mon, 23 Jan 2012 18:35:00 +0000</pubDate><atom:updated>2012-01-23T10:35:28.262-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">css</category><title>CSS: how to style form elements</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/form.jpg" alt="" class="aligncenter spaced" /&gt;In this article I'll explain how to format form elements by using &lt;acronym title="Cascading Style Sheets"&gt;CSS&lt;/acronym&gt;.
Finally, I'll provide a series of screenshots taken from the various browsers.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;The markup&lt;/h2&gt;

&lt;p&gt;We start with the following markup:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;form action=&amp;quot;#&amp;quot; method=&amp;quot;post&amp;quot;&amp;gt;
 &amp;lt;fieldset&amp;gt;
 &amp;lt;legend&amp;gt;Personal information&amp;lt;/legend&amp;gt;
 &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
  &amp;lt;label for=&amp;quot;name&amp;quot;&amp;gt;Name:&amp;lt;/label&amp;gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;name&amp;quot; id=&amp;quot;name&amp;quot; /&amp;gt;
  &amp;lt;label for=&amp;quot;email&amp;quot;&amp;gt;Email:&amp;lt;/label&amp;gt;
  &amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;email&amp;quot; id=&amp;quot;email&amp;quot; /&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
  &amp;lt;label for=&amp;quot;male&amp;quot;&amp;gt;Male&amp;lt;/label&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; value=&amp;quot;male&amp;quot; id=&amp;quot;male&amp;quot; name=&amp;quot;male&amp;quot; /&amp;gt;
  &amp;lt;label for=&amp;quot;female&amp;quot;&amp;gt;Female&amp;lt;/label&amp;gt;
  &amp;lt;input type=&amp;quot;checkbox&amp;quot; value=&amp;quot;female&amp;quot; id=&amp;quot;female&amp;quot; name=&amp;quot;female&amp;quot; /&amp;gt;
  &amp;lt;label for=&amp;quot;country&amp;quot;&amp;gt;Country:&amp;lt;/label&amp;gt;
  &amp;lt;select name=&amp;quot;country&amp;quot; id=&amp;quot;country&amp;quot;&amp;gt;
   &amp;lt;option value=&amp;quot;USA&amp;quot;&amp;gt;USA&amp;lt;/option&amp;gt;
   &amp;lt;option value=&amp;quot;Italy&amp;quot;&amp;gt;Italy&amp;lt;/option&amp;gt;
  &amp;lt;/select&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
  &amp;lt;h2&amp;gt;Comments&amp;lt;/h2&amp;gt;
  &amp;lt;textarea rows=&amp;quot;10&amp;quot; cols=&amp;quot;40&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;
  &amp;lt;input type=&amp;quot;submit&amp;quot; id=&amp;quot;btn&amp;quot; name=&amp;quot;btn&amp;quot; value=&amp;quot;Send&amp;quot; /&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;/fieldset&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/1/1.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We're going to stylize the following elements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;form&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fieldset&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;legend&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;label&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;input&lt;/code&gt; as:
&lt;ul&gt;
&lt;li&gt;text field&lt;/li&gt;
&lt;li&gt;checkbox&lt;/li&gt;
&lt;li&gt;submit button&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;select&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;textarea&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note that we've used proper attributes for each element, due to accessibility reasons.&lt;/p&gt;

&lt;h2&gt;General styles&lt;/h2&gt;

&lt;p&gt;The following styles set only the backbone for further and more advanced styles.&lt;/p&gt;


&lt;pre&gt;
form, fieldset {
 margin: 0;
 padding: 0;
}

form {
 width: 500px;
 background: #ffe;
 color: #000;
 font: small Verdana, sans-serif;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/2/2.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We've resetted the default margin and padding on the &lt;code&gt;form&lt;/code&gt; and &lt;code&gt;fieldset&lt;/code&gt; elements.
Then we've specified a width for our form, plus font and colors.&lt;/p&gt;

&lt;h2&gt;Adding some padding to the form&lt;/h2&gt;

&lt;p&gt;We need some vertical padding to create a certain amount of vertical spaces above and below the blocks. So
we can write the following:&lt;/p&gt;

&lt;pre&gt;
form {
 padding: 1em 0;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/3/3.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;Fieldset and legend&lt;/h2&gt;

&lt;p&gt;Now we can start stylizing the &lt;code&gt;fieldset&lt;/code&gt; and &lt;code&gt;legend&lt;/code&gt; elements. Styles are the following:&lt;/p&gt;

&lt;pre&gt;
fieldset {
 display: block;
 width: 90%;
 margin: 0 auto;
 border: 1px solid #666;
}

legend {
 padding: 0 0.2em;
 background: #c00;
 color: #fff;
 font-weight: bold;
 text-transform: uppercase;
 margin-left: 0.5em;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/4/4.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fieldset&lt;/code&gt; is actually a block-level element, but we've declared it explicitly in order to prevent browsers
from applying their internal algorithms for handling form elements. Then we've specified a width and we've centered this
element through horizontal automatic margins. On the contrary, &lt;code&gt;legend&lt;/code&gt; is an inline element, so we've only added
a left margin and some horizontal padding. Just for the record, Internet Explorer 7 (and lower) doesn't need a left margin to
keep this element separated from the &lt;code&gt;fieldset&lt;/code&gt;'s left border, so we've used the following code only for Internet
Explorer:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;!--[if lt IE 8]&amp;gt;
&amp;lt;style type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot;&amp;gt;
legend {margin-left: 0}
&amp;lt;/style&amp;gt;
&amp;lt;![endif]--&amp;gt;
&lt;/pre&gt;

&lt;p&gt;What's more, &lt;code&gt;legend&lt;/code&gt; is one of those elements that is actually &amp;quot;locked&amp;quot; by browser's algorithms so that
we can specify only a few styles on it.&lt;/p&gt;

&lt;h2&gt;Creating centered rows&lt;/h2&gt;

&lt;p&gt;After centering the main content of our form, we want to center the other elements. This can be done very easily.&lt;/p&gt;

&lt;pre&gt;
div.row {
 width: 90%;
 margin: 0 auto;
 padding: 1em 0;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/5/5.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We use vertical padding instead of margins in order to avoid some problems with Internet Explorer 7 (and lower), namely
the wrong computation of margins in a form.&lt;/p&gt;

&lt;h2&gt;Input and label&lt;/h2&gt;

&lt;p&gt;Now we can stylize the text fields and the &lt;code&gt;label&lt;/code&gt; elements.&lt;/p&gt;


&lt;pre&gt;
label {
 vertical-align: middle;
 font-weight: bold;
}

input {
 font: 1em Verdana, sans-serif;
 vertical-align: middle;
}
input#name, input#email {
 width: 100px;
 border: 1px solid #c00;
 background: #fff;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/6/6.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;To vertically align the elements, we've used the &lt;code&gt;vertical-align&lt;/code&gt; property set to &lt;code&gt;middle&lt;/code&gt;.
Another important thing to keep in mind is that the actual dimensions of text fields are determined by the type and
size of the font in use. For that reason, we've specified a font family and a font size on each &lt;code&gt;input&lt;/code&gt; element, so
that the vertical alignment can be handled correctly.&lt;/p&gt;

&lt;p&gt;However, the rendering of checkboxes is really inconsistent, so we've skipped these elements. Again, this kind of elements
seems to be &amp;quot;locked&amp;quot; by the default algorithms of most browsers.&lt;/p&gt;

&lt;h2&gt;Select&lt;/h2&gt;

&lt;p&gt;The styles for the &lt;code&gt;select&lt;/code&gt; element are really simple.&lt;/p&gt;

&lt;pre&gt;
select {
 font: 1em Verdana, sans-serif;
 vertical-align: middle;
 width: 95px;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/7/7.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As for the &lt;code&gt;input&lt;/code&gt; element, we've vertically aligned this element and specified the same
font family and size used above. In this case, Internet Explorer 7 (and lower) has some problems with
the specified width, so it needs the following code:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;!--[if lt IE 8]&amp;gt;
&amp;lt;style type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot;&amp;gt;
select {width: 99px}
&amp;lt;/style&amp;gt;
&amp;lt;![endif]--&amp;gt;
&lt;/pre&gt;

&lt;p&gt;However, the rendering of the &lt;code&gt;option&lt;/code&gt; elements is really inconsistent, so we've skipped these elements. Again, this kind of elements
seems to be &amp;quot;locked&amp;quot; by the default algorithms of most browsers.&lt;/p&gt;

&lt;h2&gt;Textarea and submit button&lt;/h2&gt;

&lt;p&gt;These elements have the following styles:&lt;/p&gt;

&lt;pre&gt;
textarea {
 display: block;
 width: 100%;
 background: #fff;
 border: 1px solid #c00;
 font: 1em Verdana, sans-serif;
 overflow: auto;
}

input#btn {
 background: #c00;
 border: 1px solid #800;
 color: #fff;
 font-weight: bold;
}
&lt;/pre&gt;

&lt;p class="view-example"&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/8/8.html"&gt;View the example&lt;/a&gt;&lt;/p&gt;


&lt;p&gt;The &lt;code&gt;textarea&lt;/code&gt; element is an inline-block element, so we've declared it as a block-level
element. The declaration &lt;code&gt;overflow: auto&lt;/code&gt; should prevent browsers from showing the trackbar
for the vertical scrollbar, but this solution doesn't work in all cases. What's more, Internet Explorer
7 (and lower) has some problems with the correct calculation of the width of the element and it needs
the following code:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;!--[if lt IE 8]&amp;gt;
&amp;lt;style type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot;&amp;gt;
textarea {width: 99%}
&amp;lt;/style&amp;gt;
&amp;lt;![endif]--&amp;gt;
&lt;/pre&gt;

&lt;h2&gt;Final result&lt;/h2&gt;

&lt;p&gt;Our &lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples/final/final.html"&gt;final layout&lt;/a&gt; appears as follows in the four major browsers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;div class="picture"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/form-elements/img/firefox.png" alt="Firefox" /&gt;
&lt;p&gt;Firefox&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="picture"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/form-elements/img/ie.png" alt="Internet Explorer" /&gt;
&lt;p&gt;Internet Explorer&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="picture"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/form-elements/img/opera.png" alt="Opera" /&gt;
&lt;p&gt;Opera&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class="picture"&gt;
&lt;img src="http://www.css-zibaldone.com/articles/form-elements/img/safari.png" alt="Safari" /&gt;
&lt;p&gt;Safari&lt;/p&gt;
&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;Download examples&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.css-zibaldone.com/articles/form-elements/examples.zip"&gt;examples.zip&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-6259059497409226742?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/9xyH1qsgWck" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/9xyH1qsgWck/css-how-to-style-form-elements.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/css-how-to-style-form-elements.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-857423399525164555</guid><pubDate>Sun, 22 Jan 2012 15:55:00 +0000</pubDate><atom:updated>2012-01-22T07:55:28.064-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">javascript</category><title>JavaScript syntax highlighting is bad for performance</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/syntax-highlighting.png" alt="" class="aligncenter spaced" /&gt;My visitor's satisfaction is one of the top priorities of this blog. For that reason, I decided to remove syntax highlighting completely. I found out that syntax highlighters are bad for performance. In fact, all the syntax highlighters tools used since the very beginning of this blog were actually poor when it comes to performance. Most of my visitors come from the USA, but there's a significant percentage of people who connect to this site from Asia. When the distance increases, it also affects latency and response times.  I'd like to explain why JavaScript syntax highlighters are bad for performance using very simple words.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;Too many GET requests&lt;/h2&gt;

&lt;p&gt;Generally speaking, a JavaScript syntax highlighter is made up of a single core file and several additional language files. Let's say that on your blog your main topics are CSS, JavaScript, HTML5 and PHP.&lt;/p&gt;

&lt;p&gt;Four languages mean four different language files, plus the main core file. The total of five JavaScript files forces a browser to perform five different GET requests.&lt;/p&gt;

&lt;p&gt;These additional requests, added to the overall amount of the HTTP requests of your site, result in an increased loading time of your pages. I didn't take the exact timing of such delays, but I reasonably think that they should be approximately of more that 5-10 seconds, especially on high-traffic web sites.&lt;/p&gt;

&lt;h2&gt;Poor string manipulation&lt;/h2&gt;

&lt;p&gt;In JavaScript, advanced string manipulation is handled by regular expressions (Perl-compatible, with some differences). Usually a syntax highlighter works on a target element by replacing its HTML content with new content created on the fly by searching and replacing some strings which have a special meaning for the code in use.&lt;/p&gt;

&lt;p&gt;For example, a DOM structure like the following:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;pre class=&amp;quot;js&amp;quot;&amp;gt;
function A() {}
&amp;lt;/pre&amp;gt;
&lt;/pre&gt;

&lt;p&gt;becomes:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;pre class=&amp;quot;js&amp;quot;&amp;gt;
&amp;lt;span class=&amp;quot;kwd&amp;quot;&amp;gt;function&amp;lt;/span&amp;gt; A() {}
&amp;lt;/pre&amp;gt
&lt;/pre&gt;

&lt;p&gt;This search-and-replace routine is performed several times on each code block on the page. To get an idea of the process behind syntax highlighting, you should measure the duration of a single routine, multiply it for the number of significant strings of each block and finally multiply the result for the number of blocks of a page.&lt;/p&gt;

&lt;h2&gt;DOM loading delays&lt;/h2&gt;

&lt;p&gt;Most of these routines take place on page loading. More specifically, the event used is &lt;code&gt;DOMContentReady&lt;/code&gt; or, if it's not available, the &lt;code&gt;load&lt;/code&gt; event of the &lt;code&gt;body&lt;/code&gt; element is used instead.&lt;/p&gt;

&lt;p&gt;The problem is that if your page contains several other assets, such as media elements or JavaScript widgets, DOM loading will be further delayed. In fact, syntax highlighters don't feature a really flexible way of handling the bootstrapping (so to speak) of the library, meaning that you cannot preload them without affecting the way by which your code blocks will be displayed.&lt;/p&gt;

&lt;p&gt;If you load a library too soon or too late, you won't see the CSS styles applied to your code blocks but only raw code.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-857423399525164555?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/2sJfZ3pQsb8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/2sJfZ3pQsb8/javascript-syntax-highlighting-is-bad.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>3</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/javascript-syntax-highlighting-is-bad.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-2522885338773339683</guid><pubDate>Sat, 21 Jan 2012 12:41:00 +0000</pubDate><atom:updated>2012-01-21T04:41:52.530-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: Mati, professional image gallery</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/07/matilde.jpg" alt="" class="aligncenter spaced" /&gt;&lt;cite&gt;Mati&lt;/cite&gt; is a professional jQuery image gallery that I've created as an homage to my little niece Matilde. It's a grid-based image gallery that allows you to navigate through the image sets and view the full-size image preview. It's free. The only thing you should do is to add an image preloading routine to improve performance. I hope you find it useful.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h3&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-mati-image-gallery/"&gt;Mati image gallery&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-mati-image-gallery/jquery-mati-image-gallery.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-2522885338773339683?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/qA2hlmCf2-c" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/qA2hlmCf2-c/jquery-mati-professional-image-gallery.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/jquery-mati-professional-image-gallery.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-2579358297457191967</guid><pubDate>Sun, 08 Jan 2012 07:20:00 +0000</pubDate><atom:updated>2012-01-07T23:20:46.286-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">wordpress</category><category domain="http://www.blogger.com/atom/ns#">jquery</category><title>jQuery: the moreLink plugin for WordPress</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2011/08/wordpress_jquery.jpg" alt="" class="aligncenter spaced" /&gt;&lt;cite&gt;moreLink&lt;/cite&gt; is a jQuery plugin written by me that handles the 'More' links of a WordPress site by fetching the linked post via AJAX without refreshing the page.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;h2&gt;Base usage&lt;/h2&gt;

&lt;pre class="prettyprint lang-jquery"&gt;
$('a.more-link').moreLink(options);
&lt;/pre&gt;

&lt;h2&gt;Options&lt;/h2&gt;

&lt;dl&gt;
&lt;dt&gt;&lt;code&gt;target&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The CSS selector that identifies your post wrapper in the target page (e.g. &lt;code&gt;div.post&lt;/code&gt;).&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;parent&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The outermost parent of the link in the current page.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;loader&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The full path to the animated GIF used while the fetched post is loading.&lt;/dd&gt;
&lt;dt&gt;&lt;code&gt;loaderStyles&lt;/code&gt;&lt;/dt&gt;
&lt;dd&gt;The CSS styles given as an object to the &lt;code&gt;css()&lt;/code&gt; method to stylize the animated spinner.&lt;/dd&gt;
&lt;/dl&gt;

&lt;h2&gt;Demo&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="420" height="315" class="wide" src="http://www.youtube.com/embed/jUCgCfP7jzc?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;

&lt;h3&gt;Download&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://gabrieleromanato.com/esempi/jquery/jquery-plugin-more-link/jquery-plugin-more-link.zip"&gt;ZIP file&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-2579358297457191967?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/ppfkq4-YPV8" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/ppfkq4-YPV8/jquery-morelink-plugin-for-wordpress.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/jUCgCfP7jzc/default.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/jquery-morelink-plugin-for-wordpress.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-4835543129581941165.post-8435711570057567245</guid><pubDate>Thu, 05 Jan 2012 08:46:00 +0000</pubDate><atom:updated>2012-01-05T00:46:42.591-08:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">blogger</category><title>Blogger: inserting social media buttons selectively</title><description>&lt;p&gt;&lt;img src="http://gabrieleromanato.com/wp-content/uploads/2012/01/blogging.jpg" alt="" class="wide spaced" /&gt;Blogger already provides a way to include social media buttons on its pages but not selectively. We want that our social buttons appear only on posts and not on the homepage. Fortunately, Blogger also provides a series of tags (all starting with &lt;code&gt;b&lt;/code&gt;) to perform some specific tasks within a template. Let's see how we can accomplish this task.&lt;/p&gt;

&lt;a name='more'&gt;&lt;/a&gt;

&lt;p&gt;From &lt;cite&gt;Template&lt;/cite&gt;, select &lt;cite&gt;Edit HTML&lt;/cite&gt; and put the following conditional expression where you want the social buttons appear:&lt;/p&gt;

&lt;pre class="prettyprint"&gt;
&amp;lt;b:if cond='data:blog.url != data:blog.homepageUrl'&amp;gt;

  &amp;lt;!-- social buttons code here --&amp;gt;

&amp;lt;/b:if&amp;gt;
&lt;/pre&gt;

&lt;p&gt;The above instruction checks whether the current URL is different from your homepage's URL. Then you can include your social buttons code within that conditional block, as follows:&lt;/p&gt;


&lt;pre class="prettyprint"&gt;
&amp;lt;b:if cond='data:blog.url != data:blog.homepageUrl'&amp;gt;

    &amp;lt;div class='share'&amp;gt;
&amp;lt;span class='twitter'&amp;gt;
&amp;lt;a class='twitter-share-button' data-lang='en' data-via='username' href='https://twitter.com/share'&amp;gt;Tweet&amp;lt;/a&amp;gt;
&amp;lt;script&amp;gt;!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=&amp;quot;//platform.twitter.com/widgets.js&amp;quot;;fjs.parentNode.insertBefore(js,fjs);}}(document,&amp;quot;script&amp;quot;,&amp;quot;twitter-wjs&amp;quot;);&amp;lt;/script&amp;gt;
&amp;lt;/span&amp;gt;
&amp;lt;span class='google-plus'&amp;gt;
&amp;lt;g:plusone annotation='inline' size='small' width='120'/&amp;gt;
&amp;lt;script type='text/javascript'&amp;gt;
  (function() {
    var po = document.createElement(&amp;#39;script&amp;#39;); po.type = &amp;#39;text/javascript&amp;#39;; po.async = true;
    po.src = &amp;#39;https://apis.google.com/js/plusone.js&amp;#39;;
    var s = document.getElementsByTagName(&amp;#39;script&amp;#39;)[0]; s.parentNode.insertBefore(po, s);
  })();
&amp;lt;/script&amp;gt;
&amp;lt;/span&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;/b:if&amp;gt;
&lt;/pre&gt;

&lt;p&gt;Easy enough, isn't it?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4835543129581941165-8435711570057567245?l=onwebdev.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/onwebdev/~4/RQw0d9emeTk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/blogspot/onwebdev/~3/RQw0d9emeTk/blogger-inserting-social-media-buttons.html</link><author>noreply@blogger.com (Gabriele Romanato)</author><thr:total>1</thr:total><feedburner:origLink>http://onwebdev.blogspot.com/2012/01/blogger-inserting-social-media-buttons.html</feedburner:origLink></item></channel></rss>

