Peter's Blog

Redefining the Impossible

Items filed under theme


There are three ways to blog from a pocketpc that I have found:

  1. open your blog in a web browser and edit it as normal. This doesn't work so well in practise unless your web page has been designed with a css style sheet that works nicely on a pda. I tried modifying my drupal theme accordingly and made it presentable but it's not up to data entry.
  2. try using an application for posting to blogs. There are a couple of these about but those that I tried were buggy or had tiny little edit boxes.
  3. write the article and submit by email. This is how I am posting this, I use phatnotes, a notetaking application that can send the notes via email. I don't use pocket outlook for the simple reason that it doesn't seem to save sent mail so I cannot edit the article and send it again to modify it. I use my old mailbot script on the server to capture posts and poke them into drupal.

So far this has worked ok and I can compose posts offline and upload them at my leisure.

Disadvantages:

  • No preview unless I go online, hence I keep posts simple.
  • cutting and pasting urls is fiddly and I cannot be bothered with it.
  • my script adds tags by scanning the database for existing tags, searching the post for the tag words and adding the tags that it finds. This can give irrelevant tags and I cannot define new tags. I need a neat way to specify tags in the post.

Advantages:

  • the convenience of whipping my pda out and having a quick blog. I don't have to go upstairs and get my laptop.
  • can lay on settee and blog in comfort.

2 Comments

Working on a web site, trying to get it to look ok in both Firefox and IE. Firefox is ok, a large GIF image on the site renders in the size I would expect, about 600x400. In IE however, it is shown proportionally larger as if zoomed in a bit and hence the site looks poor, especially as the resizing has distorted the image.

Looking through IE options there is nothing to control this. Text Zoom only alters text size, not the size of images.

On a hunch I looked at my Display settings in Control Panel. I had the font size (Display/Settings/Advanced) set extra large, 132 dpi. I tend to use large fonts because of my poor eyesite. I reset the font size to normal (96 dpi) and did the mandatory reboot and, lo and behold, images in IE were of normal size and my website looked publishable.

It's one thing having to either use large fonts or squint all the time, it's another when MS are plotting to make all websites look awful to the optically challenged.


Filed under: firefox ie theme


Updated this blog to Drupal. Went smoothly enough, tried using the democratica theme as it is one of the few drupal themes that resizes horizontally to fit screen width but it had some problems:

  • if main content was not long enough, there was an error whereby the background to the right side panel was not long enough and did not meet the footer.
  • viewing in IE6 on my Dell inspiron 500m, the background to the page loaded horribly slowly and I had to edit the css to make it plan grey
  • it's css is vastly complicated and spread over a number of css files. Does not strike me as a clean or efficient design.

so I went back to my theme although I am a little sick of it.

I have wanted to categorise my blog entries using tags for a while now but there is still no official drupal module to do it (an api for developers but no user level module). I had a google and found awTags which is exactly what I want. You can now see the nice tags block on my site.

So I had a nice tagging system and over 700 articles with no tags. asTags provides an admin page to add tags to nodes with selected existing tags but no more. Looking through the code it had a nice clean api and I was able to hack to to do a search on the database for a search term and add a tag to matching nodes. I used the mysql REGEXP operator so that I could match whole words:

   1  function awTagsAPI_AddToExistingTagSearch($search, $addTag) {
   2    $addTid = awTagsAPI_GetTagID($addTag);
   3  
   4    if ($addTid == FALSE)
   5      $addTid = awTagsAPI_AddTag($addTag);
   6  
   7      $strSearch = str_replace( "'", "''", $search);
   8    $result = db_query("SELECT nid FROM {node} WHERE body REGEXP " +
   9                       "'[[:<:]]%s[[:>:]]' OR title REGEXP '[[:<:]]%s[[:>:]]'", $strSearch, $strSearch);
  10    $nCount = 0;
  11    while ($nid = db_fetch_object($result)) {
  12      awTagsAPI_AddTagToNode($nid->nid, $addTid, TRUE);
  13      $nCount = $nCount + 1;
  14    }
  15  
  16    return $nCount; // return count to display in summary
  17  }

In an ideal world I would have used drupals own search facility but the api for that is horribly mixed up with user interface code so I searched the database directly. The above allows an amount of regexp syntax to be used, e.g. search for (outlook|thunderbird|exchange|gmail) and tag with 'email'. However, the above does not search comments, only node title and body.

Still, it worked good enough for me and I've added lots of tags.


1 Comment

I've been contemplating some python web development. This is mainly for the following reasons:

  • I'd like my blog to have features for threading subjects based on keywords, a kind of related articles list. This would be dynamically updated, old articles could link to newer articles. This is possible in Drupal but the taxonomy system is laborious to configure through the web interface. There is a new keyword feature (folksonomies) but it appears to be a library for other modules to use. There are some modules that promise this kind of thing but they are not what I am looking for. The most important thing is that old articles are displayed with links to new articles, which involves messing around with themeing to add links to a cached page or figuring out how to flush the cache and put articles through a filter that would add the links.
  • I'd rather spend my limited programming time being creative with technologies I am already familiar with. I don't like php enough to want to learn it any more. I know and like python.
  • I don't want to spend my time trying to figure out how the Drupal code base works. Ok, I'm lazy and I have a short attention span and I'm not very interested in how it works.
  • If I do this as a spare time project I want to enjoy it, I don't want it to feel like a maintenance exercise. I can do that at work.
  • I have found that using librarys etc written by third partys can give you 95% of what you want, then you spend weeks trying to hack them to get the extra 5%. The only exception to this rule I can think of is the python standard library which is way cool.

So I looked at a few web application frameworks. This is a little lightweight and short on detail, I did most of it a few weeks ago and I didn't take notes.

cherrypy: Requires python 2.3 and my hosting service will only give me python 2.2 with cgi. I think generator functions are way cool and I'd love to use them. Do I stand any chance of getting my hosting service to upgrade? I'll email them and ask.

quixote: got the demo going, although I had to fix some of the urls within it as they appeared to be broken. It worked easily enough with cgi, the 1.3 version worked with python 2.2. However, again they have just released version 2 which has a couple of yield statements in it, limiting it python 2.3.

webware: I don't think I could see the advantage of 'servlets' and their web site (presumably powered by webware but it only says 'python powered') is not an impressive display of it's capabilities.

zope/plone: I've toyed with zope in the past (version 2) and found it's learning curve to be almighty. It may be very capable but you have to learn the zope way to do everything. The developers seem to be concentrating on inventing new object-orientated paradigms rather than keeping things simple and I hate huge complex object models. I don't like the web-based source editor (what, no syntax highlighting?: although I could use mozex and edit in vim). Also, non-cgi.

I was most interested in quixote until I came to the python 2.3 stumbling block with the new version 2. I don't want to settle for an old version. This led me on to think about what these frameworks actually give me:

  • map urls to class/method calls
    • big deal
  • session management
    • do I need it for my simple purposes?
  • templating systems
  • interface to cgi/mod_python/fastcgi/whatever
    • I can only have cgi anyway
  • easy form generation
    • classes to build the contents of a form. How many forms will I need? Can't templates do this?
  • already used on the internet and exposed to hackers
    • lets not be too ambitious with what we do. Keep drupal in the background for data entry.
  • learning curves

Which has led me to... straight cgi. Run my own scripts from cgi, using the cgi module in the standard python library to get the url parameters and generate a nice error page when things go wrong. I can get it going easily enough and below, with just a few hours hacking, is something that can display nodes from the drupal database. The output is themed through the Cheetah template engine and gives me the same look as my drupal theme. Given that it is only cgi it is not massively scalable, but I understand every line of it and that means a lot in terms of development time. Given that it generates pages that look like the drupal pages, I can chop and change, leaving some bits to drupal (data entry) and others in python (presentation). It's a lash up but so what?

The main challenge is porting my wilki module to python, particularly the geshi syntax highlighting.

I am not planning to rewrite Drupal and I probably won't release Yet Another Python Web Framework. I may not even finish it. It is something for me to play with.

   1  #!/usr/bin/python
   2  #
   3  import Cheetah.Template
   4  import cgi
   5  import cgitb; cgitb.enable()
   6  import time
   7  import datetime
   8  import os
   9  import pdo
  10  
  11  def ThemeAndOutput( strPageTitle, strContent, oParams={}):
  12      "Theme the site"
  13  
  14      strSideBar = """
  15      <div class="block">
  16      <h2>Reports</h2>
  17      <ul>
  18          <li><a href="Intranet.cgi">Drupal Emulator</a></li>
  19      </ul>
  20      </div>"""
  21  
  22      oDict = {
  23          'Root': '/SMB',
  24          'Url': '/Intranet/Intranet.cgi',
  25          'Title': 'Drupal Emulator',
  26          'Slogan': 'There are no Problems, only Challenges',
  27          'PrimaryLinks': [ '<a href="http://intranet.org">Intranet</a>',
  28                              '<a href="http://www.google.co.uk">Google</a>'],
  29          'PageTitle': strPageTitle,
  30          'SideBar': strSideBar,
  31          'Footer': 'Copyright 2005 Peter Wilkinson'
  32      }
  33  
  34      #
  35      # Read page template and shove in the content.
  36      #
  37      strTemplate = open( 'PageTemplate.html').read() % { 'Content': strContent}
  38  
  39      #
  40      # Run template and content through cheetah in one go.
  41      # Is this faster? Doubt it.
  42      #
  43      oHtml = Cheetah.Template.Template( strTemplate, [oDict, oParams])
  44  
  45      print str(oHtml)
  46  
  47  def MainPage( oForm):
  48      "Main welcome page: tell user what is going on"
  49  
  50      #
  51      # Determine how many links to show.
  52      #
  53      strFrom = oForm.getfirst( 'from')
  54      if strFrom == None:
  55          strLimit = ' LIMIT 10'
  56      else:
  57          try:
  58              nLimit = int(strFrom)
  59              strLimit = ' LIMIT %d, 10' % nLimit
  60          except:
  61              strLimit = ' LIMIT 10'
  62  
  63      c = pdo.connect( 'Module=MySQLdb;user=drupal;passwd=secret;db=drupal')
  64      rs = c.open( 'SELECT * FROM node ORDER BY created DESC %s' % strLimit)
  65  
  66      strTitles = []
  67      while rs.next():
  68          strTitles.append( '<a href="Intranet.cgi?node=%s">%s</a>' %
  69                (rs.fields['nid'].value, rs.fields['title'].value))
  70  
  71      strPage = """
  72  <ul>
  73  #for $strTitle in $titles
  74  <li>$strTitle</li>
  75  #end for
  76  </ul>
  77      """
  78  
  79      ThemeAndOutput( "Welcome", strPage, { 'titles': strTitles})
  80  
  81  def NodePage( oForm):
  82      "Display a node"
  83  
  84      strNode = oForm.getfirst( 'node')
  85      if strNode == None:
  86          ErrorPage()
  87          return
  88      else:
  89          try:
  90              nNode = int(strNode)
  91          except:
  92              ErrorPage()
  93              return
  94  
  95      c = pdo.connect( 'Module=MySQLdb;user=drupal;passwd=secret;db=drupal')
  96      rs = c.open( 'SELECT * FROM node WHERE nid = %d' % nNode)
  97  
  98      if rs.next():
  99          strTitle = rs.fields['title'].value
 100          strBody = rs.fields['body'].value
 101      else:
 102          ErrorPage()
 103          return
 104  
 105      strPage = """
 106  <h2>$strTitle</h2>
 107  
 108  <pre>
 109  $strBody
 110  </pre>
 111      """
 112  
 113      ThemeAndOutput( strTitle, strPage,
 114            { 'strTitle': strTitle, 'strBody': strBody})
 115  
 116  def ErrorPage():
 117      strPage = """<p>There has been some kind of navigation error, the link
 118  you just clicked is broken</p>
 119  <p>Better <a href="mailto:someone@somewhere.com">complain about it</a>.</p>
 120      """
 121  
 122      ThemeAndOutput( "Drupal emulator", strPage)
 123  
 124  oForm=cgi.FieldStorage()
 125  
 126  node = oForm.getfirst( 'node')
 127  if node:
 128      NodePage( oForm)
 129  else:
 130      MainPage( oForm)

The page template is kept in a seperate file. It is based on the phptemplate of my drupal theme and was ported over in less than an hour. Theming engines? A specialisation of templates.

   1  Content-Type: text/html
   2  
   3  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   4   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
   5  <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
   6  <head>
   7  <title>$Title</title>
   8  <meta http-equiv="Content-Style-Type" content="text/css"/>
   9  <style type="text/css">@import url(style.css);</style>
  10  </head>
  11  <body>
  12      <div id="headerleft">
  13      </div>
  14      <div id="headermain">
  15          <div id="ie6hack">
  16          </div>
  17      </div>
  18      <div id="headertitle">
  19          <h1>
  20              <a href="$Url" title="$Title">
  21              $Title</a>
  22          </h1>
  23      </div>
  24      <div class="slogan">
  25          $Slogan
  26      </div>
  27      <div id="logo">
  28          <a href="$Url" title="$Title">
  29              <img src="ITL.gif"/>
  30          </a>
  31      </div>
  32      <div id="headerright">
  33      </div>
  34  #if len($PrimaryLinks) > 0
  35      <div id="primarylinks">
  36          <ul>
  37  #for $PrimaryLink in $PrimaryLinks
  38              <li>$PrimaryLink</li>
  39  #end for
  40          </ul>
  41      </div>
  42  #end if
  43  
  44      <div id="ie5forcemargininsidehack">
  45          <div id="main">
  46              <div class="tab">
  47                  <div class="tabbackground">
  48                      <div class="tableft">
  49                          <h3>
  50                              $PageTitle
  51                          </h3>
  52                      </div>
  53                  </div>
  54              </div>
  55              <div class="tabbody">
  56                  <div class="ieisbuggy">
  57                  </div>
  58                  <div id="content">
  59                      %(Content)s
  60                  </div>
  61                  <div class="ieisbuggy">
  62                  </div>
  63              </div>
  64          </div>
  65          <div id="footer">
  66              <div class="footerleft">
  67                  <p>
  68                  $Footer
  69                  </p>
  70              </div>
  71          </div>
  72      </div>
  73      <div id="sidebarright">
  74          <div id="sidebar">
  75              <div class="sidebarbox">
  76                  $SideBar
  77              </div>
  78          </div>
  79          <div id="sidebarbottom">
  80          </div>
  81      </div>
  82  </body>


Update engineering log to Drupal 4.6.0.

Notes:

  • Followed upgrade instructions, no big problems
  • My Theme worked after installing phptemplate.
  • Wilki module worked after reading and writing filter settings.
  • Could not find 4.6 version of smileys module. Copied 4.5 version and edited smileys.module to change instances of drupal_specialChars to check_plain as described here.
  • If this reaches my public blog then the sendhome module is working.

So far, see no big changes. It keeps moaning about some image library that I don't need not being installed and there are some icons in the admin logs. Looking forward to trying the improved search . I found google site search more useful than the old search but the engineering log is behind a firewall and beyond google's reach.


Filed under: blog drupal google theme wilki


Put my new Drupal theme in place on my site. Some design notes:

  • It is xhtml + css, no tables, hand coded. That means big time trial and error.
  • It uses fancy rounded corners and shadows as these have been fascinating me. It's more a technology thing than a statement. My design skills are not good enough for this to be a statement.
  • It uses the Drupal phptemplate engine.
  • For a development tool I wrote a python script that would allow me to code the html like this:
    <div id="abox">
        <style>
            background: blue;
            font-family: verdana;
        </style>
        Hello Peter.
    </div>
    
    The python script parses this using the HTMLParser library, extracts all the <style> declarations and automatically generates the css file, e.g:
    .abox {
        background: blue;
        font-family: verdana;
    }
    
    I found this a better way for me to work, without having to switch between an html file and a css file (a process akin to maintaining c and h files in C programming).
  • The screen is resizable, it doesn't restrict the viewer to a 600 pixel wide strip down the middle of their £1000 21 inch monitor.
  • Choosing a colour scheme is hard for an engineer, especially a male one. I used this colour scheme generator in an effort to make it tasteful.
  • Tested on:
    • Firefox 1
    • IE 5
    • IE 6
    • Opera 7.54
    • Mozilla 1.6
    • Lynx

If it is broken in your browser then please let me know, unless you use some old version of netscape or IE3 in which case you should be accustomed to broken web sites.


Filed under: drupal firefox python theme

6 Comments

Been working on a new theme for my sites, something with round corners and shadows, xhtml and css. It's a really hard process of trial and error, testing it out in available browsers:

  • Firefox
  • IE5
  • IE6
  • Mozilla 1.6
  • Lynx

I've just spent a few hours on a weird problem in IE6 showing round corner bitmaps: the images were all slightly corrupted, as if they were not being displayed in the right place by a few pixels or were being partially overwritten:

images/ie6bug.gif

I spent hours fiddling with this, making sure my gif's didn't have transparent bits, googling for IE6 bugs etc but no joy. On a hunch I checked out the Drupal site and saw that the rounded corners there were corrupted as well.

I tried my new site with IE6 on my desktop pc and it was perfect.

Problem must be something strange about the graphics drivers on my Dell Inspiron 500m laptop.

New theme coming soon: it's already XHTML validated and has earnt a little badge: unlike Drupals bluebeach smile


1 Comment

Been trying the Drupal image module, using it to create a family photo album. It's ok but I do have a few issues with it:

  • The html it generates for the table in a gallery page is incorrect. It follows the form:
   1  
   2  <table>
   3  <td></td><td></td><td></td>
   4  <tr class="gallery_album_upper_row">
   5  </tr>
   6  <tr class="gallery_album_lower_row">
   7  
   8  </tr>
   9  <td></td><td></td><td></td>
  10  </table>
  11  

i.e. the td's are not between the tr's. It still displays ok.

  • The code is supposed to automatically regenerate thumbnails if it cannot find them. I wanted to alter the size of my thumbnails so I deleted the thumbnail files. However, the code generated a load of errors but no thumbnails. This turned out to be because of the following line in the function image_page:
$sql = "SELECT n.nid, n.title, n.teaser, n.body, i.thumb_path FROM {node} n, {term_node} t, {image} i
   WHERE n.nid = t.nid AND n.nid = i.nid AND t.tid = '". $tid ."' AND i.personal = 0 AND n.moderate = 0
   AND n.status = 1 ORDER BY ". _image_get_thumb_order();

This should be:

$sql = "SELECT n.nid, n.title, n.teaser, n.body, i.image_path, i.thumb_path FROM {node} n, {term_node} t, {image} i
   WHERE n.nid = t.nid AND n.nid = i.nid AND t.tid = '". $tid ."' AND i.personal = 0 AND n.moderate = 0
   AND n.status = 1 ORDER BY ". _image_get_thumb_order();

because the function theme_image_gallery_album expects image_path to be amongst the node data.

  • I take photos in both landscape and portrait format and I wanted the thumbnails to be the same area. As it is the code makes the height or width of all thumbnails the same size so landscapes might be 100x75 and portraits 100x133 (same width, vastly different height). I altered the code as follows to make landscape images (for example) 640x480 and portrait images 480x640. There may be a proper way to apply a custom theme but I've found Drupal theme code impenetrable so far.
       1  function _image_make_thumbnail($imagename, $thumbname) {
       2    $error = '';
       3    $lib = variable_get('image_lib', 'imagemagick');
       4    if (($image = image_open($imagename)) != false) {
       5      list($thx, $thy) = split('x', variable_get('image_default_thumb_size', '100'));
       6      $size = getimagesize($imagename);
       7      // pcw: make images same size, allowing for portrait mode
       8      if( $size[1] > $size[0]) {
       9          // portrait: swap required x and y dimensions
      10          $tmp = $thx;
      11          $thx = $thy;
      12          $thy = $tmp;
      13      }
      14      if (!is_numeric($thy)) {
      15        // Set default thumbnail width to 100 if nothing was specified
      16        $thx = is_numeric($thx) ? $thx : 100;
      17        // Compute thumbnail height to keep aspect ratio
      18        $thy = round($size[1] * $thx / $size[0]);
      19      }
      20      else if (!is_numeric($thx)){
      21        // Compute thumbnail width to keep aspect ratio
      22        $thx = round($size[0] * $thy / $size[1]);
      23      }
      24      image_scale($image, $thx, $thy);
      25      image_close($image, $thumbname);
      26    }
      27    else {
      28      $error = t("unable to open image %img", array("%img" => $imagename));
      29    }
      30    return $error;
      31  }
    
  • For the record, the font for the images titles can be altered in style.css thus:
    #image .title {
      font-size: 1.0em;
      font-weight: normal;
    }
    

Filed under: drupal php theme


The good news: Drupal Talk is back on the front page of Drupal.org. It went away when they upgraded to Drupal 4.5.0 and a new theme. I used to get a lot of referrals from Drupal.org, I think by virtue of Drupal Talk. They've all disappeared now.

The bad news: searching the Drupal Forums gives this:

The following list of sites is compiled dynamically. All Drupal installations may
optionally ping a Drupal directory server via XML-RPC. This server collects all
active installations and displays them here. More information is available on
this page in the Drupal handbook.

Fatal error: Call to undefined function: drupal_directory_page() in
/var/www/drupal.org/includes/common.inc(1809) : eval()'d code on line 2

My guess is someone has broken the forums, removed them from the Drupal front page and put Drupal Talk back in to fill the empty space.

Moral: Peter like Drupal Talk.


Filed under: drupal theme

5 Comments

Updated site to Drupal 4.5.0. Used same strategy as at work. All went fairly smoothly.

Tweeked the site theme a bit to make it a bit less Drupally (I don't blame them for keeping the new Drupal site theme under wraps), not too happy with the results, needs further tweeking. Spent a while fighting an annoying IE bug with 100% width tables, margins and borders. I've resolved it for now by setting the table width to 99% but it still irks me. I tried changing em dimensions to px to no avail.

Smileys still work smile

print "Wilki Module still works"

Filed under: drupal python theme wilki