Production and Development Releases: Use the Branch pull-down to select which code base to view. Youāll always see the most recent production version when you first visit the page.
Past Versions: Each version of BlogIt is identified by a tag. Use the tag pull-down to select a specific version.
Download: After selecting a branch/version use cunningly the hidden āDownload Sourceā link near the top right, to download a zip or tarball.
Just a quick update to let you know that the Ajaxification of BlogIt is moving forward pretty well. Most recently added was some full Ajax on comment editing. You can see it in action if you check out one of the test blog entries on the BlogIt test site. Login using password āblogadminā, click "quick editā next to a comment, and see the wonders ensue!
Itās been a while since I did anything with jqTOC, a jQuery plugin I wrote 3 years ago that generates a table of contents for a page. Time seems to have treated it well. At some point though the ability to show multiple TOCs broke, and that meant the demo didnāt work. Not a very good advertisement for potential users.
This latest revision fixes the problem, and so itās now possible to generate more than one TOC on a page. For instance, if you had separate containers within your page, that you want separate table of contents for. The fix involved a minor change to to the CSS, so if you happen to be upgrading from an earlier version, then you need to update your CSS to reference toc_header and toc_content as classes, not IDs.
The recent 1.4.0 version of BlogIt adds a bunch of user-interface fancies, and Ajax goodies. The cost of doing this was the addition of jQuery, jQuery-UI, and a couple of jQuery libraries, all weighing in at over 100k. Unfortunately, depending on how your host is configured, this might make BlogIt driven sites load a little slower.
One way to minimize the effect of this is to force your visitors browser to cache javascript, css, and image files, by adding future expiry headers. This wonāt affect the load speed the first time visitors hit your site, but it will help for subsequent loads by that visitor. If you host uses Apache, and have the mod_expires module loaded, then you can use the ExpiresByType directive to set an expiration date relative to the current date.
Shortly after writing a quick guide on how to set IFRAME height based on size of remotely loaded content an error came to light where Chrome and Firefox would either keep growing the iframe with after each load, or would set the iframe too large if subsequent content was shorter than the initial content.
I wasnāt able to determine the exact cause of the problem, but I implemented a work around which cured the problem. Iāve extracted the core code as a template to resolve the problem. Basically we call a function periodically, and try to see if the IFRAME height remains constant. If it does, then assume itās stopped changing, and call the local resizing function with the hopefully correct height.
varIFRAME={};functionisHeightStatic(h, x){IFRAME.resizeHeight[IFRAME.resizeHeight.length]= h;// Test to see if h has changed over last x iterations.for(var i=IFRAME.resizeHeight.length-1; i >=IFRAME.resizeHeight.length-x; i--)// don't test last element, as we just added itif(i <0||IFRAME.resizeHeight[i]!=h)returnfalse;//value is or may still be changingreturntrue;}functioniframeResizePipe(){// noticable when subsequent content is shorter.//var height = jQuery(document.body).height();var height = document.body.parentNode.scrollHeight;var heightStatic =isHeightStatic(height,4);//same height for 1 second? (4 * 250ms)if(IFRAME.resizeHeight.length>48|| heightStatic)//Iterate 50 times at 250ms delay = 12 seconds load timeclearInterval(IFRAME.resizeTimer);if(!heightStatic){// Going to 'pipe' the data to the parent through the helpframe..var pipe = document.getElementById('helpframe');if( pipe ==undefined)return;// Cachebuster a precaution here to stop browser caching interfering
pipe.src ='http://local.com/helper.html?height=height&cacheb='+Math.random();}}jQuery(document.body).ready(function(){// Ready event seems to trigger before remote images are loaded. When images don't speficy height,// cause page height to be calculated wrongly (from Larger Images).// So ping every 250ms to see if the height has increase, and reset the iframe size.IFRAME.resizeTimer =setInterval('iframeResizePipe()',250);});
NOTE: Code extracted from working code, based around jQuery, which has been commented out, with the exception of the onload handler which is performed by jQuery above.
This is the start of improving the BlogIt user interface, and making the admin workflow smoother. Many of the typical admin functions now use Ajax, which allows an action to take place without having to reload the page. That means rather than clicking to approve a comment, and waiting a few seconds for the page to reload, the approval is 'immediate! So, approving, unapproving, and deleting comments now happens instantaneously. You click the delete comment link, and it will disappear before your very eyes.
Just a quick note to let you know that progress on the next version of Blogit is going well. As promised weāve got some Ajax goodies in this release. As an initial dive, many admin functions are now ajaxified:
Approving and unapproving comments is near immediate, as is deleting comments ā no waiting for the page to reload. Click and itās done.
Blocking commenter IP addresses is another tool in the fight against spam. Add commenter IP addresses to the BlockList with a direct link ā thatās ajax as well.
Field validations are now done client-side, which means you get to see the error submitting the page. Much nicer.
Ever lost some work by clicking Cancel, or Back in error? Now youāll get a message verifying whether you want to loose your hard written work.
All with a nice shiny look. Of course all existing bugs have been quelled, squashed, and removed. Check out the BlogIt Known Issues list for a full account of whatās changing.
A little more testing and we should be done. In the meantime take a look over on the BlogIt test blog for a feel of whatās coming.
Blix is one of the more popular skins Iāve ported over from other systems. Itās pretty flexible, and gets used as a foundation for some adaptions. That, and itās pretty colorful by default, but can be muted down pretty easily.
Update 31-Jul-2010:Check out the updated version for a slightly more concise function.
This is an updated PHP based date validator, correcting some issues with the original version. An additional parameter has been added specifying the expected format of the date, using PHP date expressions.
functionbi_IsDate($d,$f='m-H:%M'){if(empty($d))returntrue;#Convert Unix timestamp to a std format (must not include regular expressions)if(preg_match('!\d{5,}!',$d))$d=strftime($f,$d);$re_day='%d|%e';$re_month='%m';$re_year='%g|%G|%y|%Y';$re_sep='[\/\-\.]';$re=array('/'.$re_day.'/'=>'(0?[1-9]|[12][0-9]|3[01])','/'.$re_month.'/'=>'(0?[1-9]|1[012])','/'.$re_year.'/'=>'(19\d\d|20\d\d)','/%H|%I|%l/'=>'([0-1]?\d|2[0-3])','/%M/'=>'([0-5]\d)');$re_date=preg_replace(array_keys($re),array_values($re),$f);#convert $f into a regular expression#does %d match the regular expression version of $f?if(preg_match('!^'.$re_date.'$!',$d,$x)#determine expected date order based on $f and checkdate&&((preg_match('!^('.$re_day.')'.$re_sep.'('.$re_month.')'.$re_sep.'('.$re_year.')!',$f)&&checkdate($x[2],$x[1],$x[3]))||(preg_match('!^('.$re_month.')'.$re_sep.'('.$re_day.')'.$re_sep.'('.$re_year.')!',$f)&&checkdate($x[1],$x[2],$x[3]))||(preg_match('!^('.$re_year.')'.$re_sep.'('.$re_month.')'.$re_sep.'('.$re_day.')!',$f)&&checkdate($x[3],$x[1],$x[2]))))returntrue;returnfalse;}
The main new user feature in this release is the new UI for comment editing. The UI basically re-uses the exiting comment entry form, but exposes fields that would normally be hidden to the average user; as such it required very few lines of code. This is a good thing. As a general goal Iām trying to keep the size of BlogIt small, primarily to keep the entry barrier low for new contributors, and partly to keep maintenance overheads low.
Most other changes were developer oriented, aimed at grouping similar variables together into arrays, which hopefully makes things a little easier to read. One change I did make was to update the date validation routine. This has been flaky for a while, and I finally broke down and took a different approach to the validation. This version should allow for a little more variation in the date formats, as well as handling international formats a little better.
Next release will be a little more user oriented, and should see some Ajax goodness.