Disabling pagination in Arras archives

  1. Removing the pagination links (next/prev) from archive.php:27 was trivial:
    <div id="archive-posts">
        <?php arras_render_posts( null, arras_get_option('archive_display') ) ?>     
    
        <?php if(function_exists('wp_pagenavi')) wp_pagenavi(); else { ?>
            <div>
                <div><?php next_posts_link( __('Older Entries', 'arras') ) ?></div>
                <div><?php previous_posts_link( __('Newer Entries', 'arras') ) ?></div>
            </div>
        <?php } ?>
        </div><!-- #archive-posts -->
  2. arras_render_posts() (library/template.php:157) uses the WP’s loop query, which has posts_per_page set to 10 globally, and it seems by the time Arras’s archive.php is invoked it’s too late — the query was already processed and cannot be modified?
    function arras_render_posts( $args = null, /*...*/ ) {
        /*...*/
        if ( ! $args ) {  
            $query = $wp_query;
        } else {
            $query = new WP_Query( $args );
        }
  3. A workaround would be to pass a new query instead of null. But how to keep the WP query’s other parameters, and modify just posts_per_page (or posts_per_archive_page)? And, for efficiency, how to avoid running another query by modifying WP’s?
  4. Or, an ugly hack around this, was to run another query, thus replacing the global $wp_query:
    query_posts($query_string . '&posts_per_archive_page=-1');  
    arras_render_posts( null, /*...*/);
  5. But really, this is definitely not the place to hardcode this option.

Adding placeholders to Contact Forms 7

HTML5 provides a placeholder attribute. How to get CF7 to use it? How to workaround stupid IE with jQuery?

Effect we want: show a placeholder in unmodified inputs, hide (delete) it when field gains focus, and restore it on blur if left empty. Preferably, don’t submit it.

Before HTML5 this trick was popular:

<input type="text" onfocus="if(this.value=='Message')this.value='';" onblur="if(this.value=='')this.value='Message';" name="foo">

Context

  1. In Contact Forms 7 (CF7), form fields are defined using shortcodes, not HTML, so can’t add the onfocus/onblur attributes. Unless we mess with CF7′s code, of course:
    $html = '<input type="text" name="'.$name.'" value="'.esc_attr($value).'" '.$atts.' onblur="if(this.value==\'\')this.value=\''.esc_attr($value).'\';" onfocus="if(this.value==\''.esc_attr($value).'\')this.value=\'\';">';

    And correspondingly for textarea, mutatis mutandis. But this is, obviously, unmaintainable.

  2. Unobtrusive JavaScript? Anyway, it would be more efficient (think many fields) to have jQuery do it instead.
  3. Using input’s default value as a placeholder doesn’t seem semantically correct.
  4. WAI?

Fixing layout bug in hacked Arras

Problem is sidebar “drops” in subsequent pages of the home page.

Investigating…

  1. Using Arras 1.5.1.2, with a few tweaks, so at first suspected hacked templates.
  2. Specific difficulty is common with CSS layouts using floats, but…
  3. Weird, this only happens when “paged”… no, actually, only on the second page!?
  4. Let’s look at the DOM. The CSS path to the “Older Entries” link is html body.rtl div#wrapper div#main.clearfix div#container.clearfix div#content.section div.navigation div.floatleft a, in all but the second page, where instead it’s html body.rtl div#wrapper div#main.clearfix div#container.clearfix div.navigation div.floatleft a, outside #content.
  5. That’s it then: all three divs #container, #primary, and #secondary should have been inside #main, but on this page the last two aren’t, thus breaking the layout.
  6. … Found it: a spurious </div>, right before an embedded video iframe, in post 39: html body.rtl div#wrapper div#main.clearfix div#container.clearfix div#content.section div#archive-posts div.traditional div.post-39 div.entry-content p iframe. That last p should’ve been inside an additional div[dir=rtl]. (Divitis! And what’s with the redundant dir attribute?)
  7. Can’t see it in TinyMCE, only in Firebug, but anyway the editor inserts an img into the post, which is later converted into an iframe, presumably.
  8. Anyway, un-publishing that post fixes the layout.
  9. Who’s fault? [Ultimate] TinyMCE? Or the user inserted it manually? No, removed it, and this post’s layout is still broken, only now a closing </div> seems missing, somewhere before <a name=”comments”>.
  10. Tracing the execution to find which PHP templates rendered this mess is so painful!
  11. The correct DOM of a “single” view (in HAML-like notation ;o):
    #main
       #container
          #content-top
          #content
             #post-156
                h3.entry-title
                .entry-content
                .about-author
                .written-by
             a[name="comments"]
          #content-bottom
       #primary
  12. The broken DOM implicates the WYSIWYG editor:
    #post-39
       h3.entry-title
       .entry-content
          div[data-mce-style]
          .about-author
          .written-by
       a[name="comments"]
  13. Paragraphs in the correct .entry-content are (needlessly) wrapped in div[style="direction:rtl"], whereas the broken entry uses semantic p elements (and tables for embedded images). Nu. Anyway, the last p contains an img.mceItemIframe, and I’m guessing is right (near?) where things went south.

Accordion menu for WordPress

The navigation menu in our theme Lavender is in the sidebar, and in order to keep it above the fold, at least initially, we want to collapse the nested levels using an accordion effect.

Requirements

  1. Hierarchical menu
  2. Only leaves are links
  3. Link to pages, categories, or anything?
  4. jQuery (WP’s?)

Searching for a WP plugin…

  1. Super Slider: MooTools based.
  2. BySlideMenu:  MooTools, horizontal, images.
  3. Accordion Image Menu: MooTools, images, with “lightbox” effect.
  4. Tabbed Widgets: jQuery UI. Messed with it for quite a while — unintuitive. Makes “tabs” of other widgets in the widget area, but…

… Nevermind

Can’t find a simple, usable plugin.I mean, there’s Accordion Menu, which only works with the Pages widget (hardcoded to li.widget_pages), limited to three levels, and the code looks convoluted. Foo?

But this ought to be trivial to hack with jQuery:

  1. Add a listener on clicks to list items;
  2. Collapse everything initially (ie, on document ready);
  3. Toggle visibility when clicked;
  4. Use WP’s jQuery; make sure it’s inserted when the menu is rendered.

Implementation

The DOM we expect:

li#nav_menu-3.widget_nav_menu
   .menu-navigation-container
      ul#menu-navigation.menu
         li#menu-item-14.menu-item
            a "Foo"
            ul.sub-menu
               li#menu-item-10.menu-item
                  a "Bar"

Algorithm for the event handler is now apparent: if the clicked anchor is followed by an unordered list sibling, toggle that UL’s visibility:

function() {
	var sub = jQuery(this).next("ul");
	if (!sub.length)
		return true; //??? Is it necessary?
	if (sub.is(":hidden"))
		sub.slideDown();
	else
		sub.slideUp();
	return false;
}

Now apply this handler to anchors in the menu:

jQuery('ul#menu-navigation > li.menu-item > a').click(…);

and run all this on document ready.

Oh, and collapse them initially:

jQuery('ul#menu-navigation > li.menu-item > ul.sub-menu').hide();

URL rewriting in WP

I hate Apache’s mod_rewrite!

Trying to set up a dynamic page in WordPress. Need to capture requests of the form /dir/foo/bar/baz, where {foo,bar,baz} are optional. “dir” would be the slug of a page whose template generates dynamic content based on the… URI? Or query string?

Continued

corpusifier.py

A script I’m writing to extract text from emails in a Gmail mailbox into a single plain text file. Python, IMAP

We’ll use it to record a corpus (hence the ugly name) for the 1,000 Tables event (1KT).

Issues

  1. Extract how? IMAP, for efficiency, because we’ll want to scrape the mailbox repeatedly as 1KT unfolds. IMAP lets us download just the index and track which emails we’ve already read. Many will be accessing that mailbox, so can’t delete processed emails nor rely on Gmail’s POP3, I guess?
  2. Avoid polling? To improve efficiency and reduce latency, we can use IMAP IDLE.

Continued

WordPress: “Error saving media attachment”

Stupid (useless) error message, ugly (complicated, inconsistent) code, horrible (noisy, and worse) programming language, and… why does it take forever to fix this silly problem? Countless threads, frustrated users, over years. Why? How does this happen? What should be done to prevent/improve this?

Notes towards…

Mobile Web unconference

Monday 2011-01-03 saw some 60 (mostly new) faces gather at The Hub Tel-Aviv for a Mobile Web unconference [also FB] orchestrated by Eyal. After his superb presentation on best practices we hacked on code and discussed project ideas in smaller groups. Was great! (Even Ronny says. ;o)

One group wrote a funny mobile Web app from scratch, complete with CSS3 animations, JavaScript, using interesting Web development and collaboration tools… all that jazz, and deployed it publicly!

My group (Nir, Oz, Uzi, Dima, Itay, Uri…) planned a study of jQuery related topics. Fascinating discussions, about everything, and, as usual, lots of buzzwords: jQTouch, Zepto.js, XUI

Continued

Tel-Aviv Perl Mongers tag soup

Tel Aviv Perl Mongers today was even worse (than PyWeb): a bunch of geniuses, mind blowing, I don’t dare repeat the soup of abstract concepts, design patterns, and black humor… Way too much fun.

I’ve a hunch these guys can maybe answer, at last, questions that are haunting me about evolution and adoption of software technologies — the human and especially social factors. I promised a presentation about Web frameworks for next month…

PyWeb-IL #22 tag cloud

PyWeb-IL today was, as usual, exhilarating.

Stormy arguments about a mind boggling torrent of buzzwords: eco-systems, Django, WordPress, migrations, South, Flask, Dancer, Rails, Ruby, DSLs, Pylons, concurrency, Twisted, Node.js, ExtJS, jQuery, DOM manipulation vs UI platform, (py)bidi, mobile, canvas, Bespin, Wave, Haskell vs PHP, phpBB, PostNuke, git, Fabric, Buildout, deployment, provisioning, WebFaction, VPS, Open Wonderland, semantic Web, HAML vs client-side templating, nonrel vs SQL, MongoDB, CouchDB, persistence, stored procedures, Delphi.., Sencha Touch.

My latest obsession: how come WordPress is so insanely successful and based on such a rotten foundation?