Archive for May, 2006

revenge of the css

Well, I’m still hard at work revising the entry page for SCLRR. I have a number of variations, here, here, here, and here. Of course there’s the usual stuff in dealing with a committee of people and a plurality of decisions. We’ll get there. Also the switch over between a shell account with a redirect for the domain (sooo late nineties…) to an actual hosted domain has gone fairly smoothly, although I expect I shall shortly hear from a multitude of volunteers who had their computers memorize their passwords so that they’ve long since forgotten what they are…

The real story is in those drop down menus. I got the idea from A List Apart which has a gorgeous css only (well mostly) drop down menu styling. It seemed like this would be the perfect solution to so many links as on the old one.

Oh dear. That “mostly” contains a drama in of itself. Because it seems that most browsers do just fine with the css definitions which basically involve defining the display to none for the li containers in the ul list (really, really elegant) and then changing the display back to block on hover.

Except of course our dear old friend Internet Explorer 6 doesn’t do hover when it’s not a link. Pish. So there’s a little javascript hackery that rewrites the hover routines on the fly for IE6. All well and good, I snarfed the css file examples, integrated them into the css and js files and went about happily buffing and polishing the newindex page.

Of course, the astute reader will recall that not only do I use Firefox, but I also work on Linux (Ubuntu, and yes I’m ecstatic that Dapper Drake comes out tomorrow, though I’ve been using the Dapper Beta for the last month and titch) so he or she will spot the looming cliff that I am oblivious to. I am also dealing with a crew of very non tech people, so they are all using IE6 hands down.

And of course it turns out that the dropdowns aren’t working at all in IE6. Figuring a conflict between css elements from the original css file with the new stuff, I copied just the example over and sure enough that worked. So I slowly added in all the decorative elements: the background, border, table, finally the multiple column…and it all works!!

So why doesn’t it work on the index?? I start to add in the actual copy (bidding farewell to the trusty lorem ipsum) piece by piece and it finally dawns on me that the javascript for the slideshow is conflicting with the javascript for the hover rewrite. At first I thought it was due to some IE6 weirdness about mixing inline and external js (the slideshow has some elements that must be inline because the perl script generates the values on the fly) but that wasn’t the case. I finally tracked it down to a conflict over the onLoad in windows. Seems that IE6 doesn’t like two of them. When I combined the calls in a single function, it demonstrated its further fussiness by working only when the two were called in a certain order. (I tested this in IE7, by the way, and it worked without the javascript: hallelujia, praise the lord and pass the ammunition.)

So, it was very wrong of me to blame all the problems on the css. I’ve learned that lesson…

del.icio.us:revenge of the css  digg:revenge of the css

Comments

a mountain out of allow_url_fopen

It seems that DreamHost has disabled this option. What is it? Good question. From the online PHP manual,

This option enables the URL-aware fopen wrappers that enable accessing URL object like files. Default wrappers are provided for the access of remote files using the ftp or http protocol, some extensions like zlib may register additional wrappers.

What are the security issues with allowing url’s to be openable in a PHP script? Well some of them are pretty hair raising and there’s a excellent overview of the problems with allowing urls to be opened in PHP programs. So that’s all well and good. I appreciate the fact that DreamHost takes steps to put together a secure hosting system.

And as a side note, my hair’s still standing on end with the way PHP allows some of this stuff. Granted, you get security issues in Perl, especially if you’re going to shovel userinput through system calls, or even sometimes just blatting stuff into email messages. But there’s convenient utilities to sanitize such input, plus judicous ways to call the system function to foil such attacks. But this url thing, especially the way it can be used to trick a site into including and running a remote file… :-O The one that really blows my wig back is where the file name is garnered from the GET url, so that you could change, just by typing on your own browser to attack, http://example.com?goodfile.php to http://example.com?badfile.php and just sit back and watch the mayhem unfold.

Goodness gracious.

But let’s zoom back to that DreamHost Wiki document for a second. Reading through it, one gets the impression that include is on the no-no list. Oh, and require is mentioned at the very last moment too. At a guess, I’d say fopen was also verboten, though that’s not mentioned here. So we’re left with a bit of mystery as far as the process of de-allow_url_fopen-ing goes.

Codesnippet is one of the plugins that’s creating my mysterious error message, so I grep thru all of its files for instances of the include or require calls. I don’t find either, but I do find require_once and at a guess, I’d say it’s on the shit list too. Hmmm.

So I google for more info on allow_url_fopen and it’s astonishing how little info there is.

OK, let’s recap. Basically, you can’t specify url’s to a set of functions that take url’s as arguments. So far I have: and fopen.

One method for bypassing the problem is to specify the file in such a way it’s no longer an url. The important thing to remember is that this property holds in a case like this:


require_once('/home/coolblog/www.urlname.com/blog/wp-config.php');

If you can connect to blog with http://urlname.com/blog/), then it’s a url, even though you don’t have the http prefix. As DreamHost’s Wiki entry notes, you can fix the problem like this:


require_once($_SERVER['DOCUMENT_ROOT'].'/blog/wp-config.php');

But there are more complex cases out there, that require cURL to solve. Wandering over to that page we immediately notice this example


<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://example.com/");
curl_setopt($ch, CURLOPT_HEADER, 0);
c u r l _ e x e c($ch);
curl_close($ch);

given for fetching a web page. Also, there appear to be some new candidates for the “shit list” here: file_get_contents(), and file(). Is this list complete? I don’t know for sure. CURL, Client URL Library Functions is actually a pretty interesting wrapper, especially if you scroll down the page and peruse the commentary.

As a postscript, in case you were wondering why c u r l _ e x e c was written that way, well so am I. If I don’t break it up, I can’t save this post! I’m guessing some kind of hyperactive filter checking for cruft in here? Even though it’s not going to be executed here, etc. It took me quite some time to figure out what was going on, the message I kept getting was

Service Temporarily Unavailable
The server is temporarily unable to service your request due to maintenance downtime or capacity problems. Please try again later.

So I saved off the file locally and left it alone for the rest of the night, even though I couldn’t find anything in the status logs. But later on, I wound up creating a new post, and then, believing that all was well, returned to this post and got stonewalled again…So I went back and put in one line at a time to find out where the problem was…Aiee…

In any case, I have some questions into Dreamhost I’m waiting on, so I’ll go ahead and publish this. But I’d like to get together sort of a conversion kit that’s a bit more comprehensive than the information I found.

del.icio.us:a mountain out of allow_url_fopen  digg:a mountain out of allow_url_fopen

Comments (2)

examining rss feeds

In bloglines, I notice some subscriptions have either their favicons appear on the subscription link (for example, any blog powered by Blogger), or have a small graphic that appears in the header (for example, wunderground.com’s weather channels). My DR subscription, though, doesn’t show any icons or graphics. This therefore has to be something that’s being sent by the feed.

Feeds come in three basic flavors these days — as I understand it, Atom is the newest kid on the block, the most widely used is probably RSS 2.0, and RSS 1 is still used by a few places but largely deprecated in favor of RSS 2. I found all the usual disagreements over which was the best, which would be most easily extensible in the future and so on and so forth. In the end, though it seems to me that much of the time a site will offer both Atom and RSS2.

Atom and RSS 2 provide a means to package up a site (an HTML page) into an XML representation which can then be used by a feed reader and/or aggregator, to put up the info about the site into the aggregator/feed reader. If you use Bloglines (or Google Reader, or any of a dozen other similar programs out there), that XML is what they’re using to snag info from your subscriptions. These programs will query your subscription sites regularly for any updates and download those into your reader.

To see your own WordPress atom and rss2 feeds, add feed/atom to your WordPress blog address, and just feed for rss2. So for example, DR’s RSS2 feed is at http://www.digitalramble.com/feed and it’s atom feed at http://www.digitalramble.com/feed/atom. Note that to see the atom feed, you’ll have to save it to a file and open it with a text editor (browsers do not “recognize” Atom pages yet.)

In tracking down the feeds for these examples, I found XML descriptors of the format channel->description->image->url and the url’s would be the locations of the images being used. Obviously, my own feed generators are not doing this, because even though I jumped through all the hoops to get favicons up for my site, they’re not showing up in a Bloglines subscription.

I, of course, must fix this.

So WordPress generates two feeds in a basic setup (at least, basic here at DreamHost?). I have three relevant files in my top wordpress directory: wp-atom.php, wp-rss.php, and wp-rss2.php. Because RSS 2’s so popular, let’s look at that one first. There’s a RSS 2 specification here. So as an experiment, I edit the wp-rss2.php file to contain


<image>
<link>http://digitalramble.com/</link>
<url>http://digitalramble/wordpress/favinit.gif</url>
<title>Digital Ramble</title>
</image>

Of course once I get into the php file and look around, I change this to use the same php bloginfo to genericize it:

        <image>
                <link><?php bloginfo_rss('url') ?></link>
                <url><?php echo get_option('siteurl'); ?>/favinit.gif</url>
                <title><?php bloginfo_rss('name'); ?></title>
        </image>

This isn’t perfectly ideal of course. Seems like there should be a favicon per theme, which loads in with the theme, and updates the icon in the browser tabs, bookmarks, and feeds. As it is, I’ve only got one favicon installed, and if I change things around I would have to change the current theme’s header.php, and the wp-content’s atom/rss generators.

Maybe I should make this a plugin, for the experience of creating an addition to the Dashboard, where you can enter your favicon, and then add the appropriate calls in your atom/rss2 feeds and your header…hmmm not a bad idea. Not today though :) This is just proof of concept.

OK, onto Atom. Googling around, I find its specification here. In scanning down this file, I find the relevant item: atom:icon about half way down the text. This looks like it. Here’s what it says:

The “atom:icon” element’s content is an IRI reference [RFC3987] that identifies an image that provides iconic visual identification for a feed.


atomIcon = element atom:icon {
   atomCommonAttributes,
   (atomUri)
}

The image SHOULD have an aspect ratio of one (horizontal) to one (vertical) and SHOULD be suitable for presentation at a small size.

There’s also atom:logo which is almost the same, except for a 2:1 horizontal:vertical aspect ratio. OK, so after some tinkering around, I decide on adding:


<icon><?php echo get_option('siteurl'); ?>/favinit.gif"</icon>

I’m not as certain of this one, because the atom feeds I was able to look at, on sites that have icons showing (such as DistroWatch), don’t seem to contain any icon information in their atom description! I did come across some comments that some aggregator sites will just pull the favicons from the feeding sites (but in that case the favicon.ico I have in my root directory should show up, unless that’s not really the root directory, which could well be the case…)

Now to publish this so I can see the results if any in Bloglines…!

del.icio.us:examining rss feeds  digg:examining rss feeds

Comments

putting together a plugin…

Well I scripted up some quick code in the sidebar to do a blogroll derived from Blogline’s info. It’s working nicely, and it occurred to me that I should try to turn it into a plugin for the exercise.

Interestingly enough, when I googled for a WordPress plugin using Bloglines, I didn’t find anything that created a blogroll from Bloglines (no doubt since WP has its own blogrolling facilities). What I did find were utilities that would let the reader add the feed into their Blogline account that sort of thing.

Checking around, Bloglines does have an API, although I did not find a PHP hook into it, there are Perl, etc modules. But, there’s this http call that PHP can use, which is what makes up the basis of my plugin.

So the initial cut of the code, directly into my sidebar, was as follows:

[code lang="php"]

    • $ch = curl_init();
      $timeout = 5; // set to zero for no timeout
      curl_setopt ($ch, CURLOPT_URL, 'http://rpc.bloglines.com/blogroll?html=1&id=digitalramble');
      curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
      $file_contents = curl_e x e c ($ch);
      curl_close($ch);
      $lines = array();
      $lines = explode("\n", $file_contents);

      // display file line by line
      foreach($lines as $line_num => $line) {
      //echo "

    • ".htmlspecialchars($line)."
      \n";
      if (ereg('http', $line) &&
      !ereg('Powered', $line)) {
      echo "
    • $line\n";
      }
      }
      ?>
  • [/code]

    Since Bloglines is kind enough to provide access to shared links (see their share information), I made use of that in the code above. I did check around their API documentation and there’s modules for Perl, Ruby, and Python, plus a number of various widgets and plugins, but oddly enough none for WordPress.

    Now, to make it into a plugin. First I peek at a couple of other plugins that I have, to see the general format and I mock up my initial file:

    [code lang="php"]
    /*
    Plugin Name: Bloglines Blogroll
    Plugin URI: http://www.digitalramble.com/
    Description: Uses your bloglines account to create a blogroll in your sidebar.
    Author: Cindy Moore
    Author URI: http://digitalramble.com
    Version: 1.0
    Disclaimer: Use at your own risk. No warranty expressed or implied is provided.
    */
    [/code]

    All the plugins start out with this kind of header, and this info is used when you add a plugin to your plugins directory then look on your Dashboard/Plugins to see what you can activate or deactivate. Obviously once I get this working later on I'll put together a page for BloglinesBlogroll's very own.

    Next step is to decide on the parameters of the function call. If you go back to Blogline's Share information, it says

    Use the following wizard to generate the HTML for your blog. If you leave the Folder field blank, all of your public subscriptions will be displayed. If you leave the Link Target field blank, links will load in same window as the blogroll.

    So it will need three pieces of information, two of which are optional. The required bit is the public Bloglines username. The two optional are the folder and the target information. Because this is plugging into the sidebar, we'll also need a title. So putting that together, the next section is:
    [code lang="php"]
    function printBloglinesBlogroll($title, $id, $folder='', $target='')
    [/code]
    So now from this information, construct the calling URI that Bloglines will expect:
    [code lang="php"]
    $blprefix = 'http://rpc.bloglines.com/blogroll?html=1&id=';
    $blurl = $blprefix.$id;
    if (strlen($folder)>0)
    {
    $blurl .= '&folder='.$folder;
    }
    if (strlen($target)>0)
    {
    $blurl .= '&target='.$target;
    }
    [/code]
    OK, so now we're ready to output. Instead of just printing as I go, I've chosen to collect the output into a variable for printing at the end. (If later on I want to modify that output before printing it, I can do so with minimum trouble.)
    [code lang="php"]
    $output .= "

  • \n";
    $output .= $title."\n";
    $output .= "
      \n";
      [/code]
      I had to play around a little bit with this. PHP treats single quotes/apostrophe marks differently from quotes (two marks) and in terms of printable output, " works better. The .= is just a catenation function, which says, put this stuff at the end of $output, keeping what's already in $output safe. I'm wrapping this up in a blogroll class so that it can be styled in the css by the individual if they wish. (I may go back and add more for the individual items, but for now I've left it alone.)

      Now we're back to the CURL replacement functions. Since not all places have curl support compiled into them, I've added commentary for people to switch things around should they wish to, since I'll be releasing this as a plugin.
      [code lang="php"]
      // safely download contents of external url using CURL
      // if no curl support, just replace the next nine lines with this one
      // $lines = file('http://example.com/');
      $ch = curl_init();
      $timeout = 5; // set to zero for no timeout
      curl_setopt ($ch, CURLOPT_URL, $blurl);
      curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
      curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
      $file_contents = curl_e x e c($ch);
      curl_close($ch);
      $lines = array();
      $lines = explode("\n", $file_contents);
      // end CURL file() substitute
      [/code]
      As I've noted elsewhere, I cannot quote curl_e x e c() in my posts. At the end of this, $lines is an array of single lines as handed back by Bloglines. This has some extra stuff it in (their own wrapper stuff, which isn't necessarily set up to go into a WP sidebar) so what I do next is toss out anything that isn't a simple link:
      [code lang="php"]
      // display file line by line
      foreach($lines as $line_num => $line)
      {
      if (ereg('http', $line) &&
      !ereg('Powered', $line))
      {
      $output .= "

    • $line
    • \n";
      }
      }

      [/code]
      You'll notice how I've modified this slightly so that the line is actually just added on to the $output variable. Time to wrap things up:
      [code lang="php"]
      $output .= "
      \nAcquired from Bloglines\n";
      $output .= "

    \n";
    $output .= "

  • \n";
    [/code]
    Close off all the html, etc. And now print it out:
    [code lang="php"]
    echo $output;
    return;
    }

    ?>
    [/code]

    At this point I saved it off into a php file and put that in my plugins directory. Going over to Dashboard/Plugins and voila! There it was! My first plugin popped up like a pro! Activating it, though, was interesting. I got an error message that made no real sense, and looking at the file didn't give me any answers. So googling on the error message, I found this:

    And this error:
    Warning: Cannot modify header information - headers already sent by (output started at /home/facethem/public_html/wp-content/plugins/wpvideo.php:1)
    tells there is a blank space in line 1 of the plugin file. Edit it in a plain text ediotr and check for blank space/line

    Interesting. So it's persnickety about that -- I'll have to remember that cos I'm a big believer in extra white space for readability and so on. In any case, removing the offending lines cleared it up and I was able to activate the plugin and put in the call to my sidebar, and voila!

    I've tested it as follows: I've given it a public folder, and it's properly retrieved feeds from that. I've given it no folder, and put some public feeds inside a public folder, and it retrieved all the feeds and printed them out, without any nesting or lossage of interior feeds (that's what I wanted, a blogroll really doesn't need to be anything more complicated than a list of links). I removed feeds, added feeds, set feeds to public and private and back again, and the plugin handled all the cases. It handled being given a private folder, a non existent folder and a public one.

    I think for using this, I would recommend creating a single folder and putting all the subscriptions you want to appear in your WP into that folder. That way you can have your own subscriptions which you may want to keep private or at least off your WP because they are off topic, etc.

    del.icio.us:putting together a plugin...  digg:putting together a plugin...

    Comments

    network neutrality

    Looks like an important victory today, with a bipartisan majority of the House Judiciary Committee passing the Internet Freedom and Nondiscrimination Act of 2006. There’s an excellent summary of the issues to be found here.

    Next step? It goes up to the full House for a vote after Congress returns from its Memorial Day recess. Check out SaveTheInternet for more info…

    del.icio.us:network neutrality  digg:network neutrality

    Comments

    « Previous entries Next Page » Next Page »

    Bad Behavior has blocked 449 access attempts in the last 7 days.