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  }
Toggle Line Numbers

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)
Toggle Line Numbers

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>
Toggle Line Numbers


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


2 Comments

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  
Toggle Line Numbers

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  }
    
    Toggle Line Numbers
  • 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


Upgraded work engineering log to Drupal 4.5.0. Here's what I did:

  • Followed the upgrade instructions (duh!)
  • copied the contents of the bluemarine theme directory to a new directory and replaced the .css file with my old xtemplate themes .css file.
  • Tweeked the template so that the main title is not a link and is aligned to the right of the logo, not under it (i.e. added align="left" to the image properties).
  • added an entry for the new site-name style to change the colour and text size of the main title.
  • Altered my wilki.module file to work with drupal 4.5.0. Mainly copied how it was done in the textile module as the drupal developer documents were a bit vague. However, for a filter it only means defining two functions.
  • Altered my sendhome.module to work. This was mainly implementation of the sendhome_menu function as described in the developer documents.

In the boilerplate _menu hook function there is a line that goes:

    if ($may_cache) {

This line stops the simple callback for the /sendhome page from working. It's ok if I comment it out so I'll leave it at that for now. This module is only for me to forward articles from the work blog to my personal blog.

The upgrade gave me a chance to prune out modules I don't use. It seems to be running ok, the improvement over 4.4.0 is not remarkable but there are some nice new features.


Filed under: blog drupal php theme wilki


This is a recipe to add a block that contains a list of the terms in a particular vocabulary. Each item in the list is a link to a page full of nodes that have been associated with that particular term. On my website this is used to create the 'Categories' block.

  • Create a block and give it a name and description
  • Set it's type php and paste in the following code:
       1  $VID = 2;  /* Desired vocabulary term ID */
       2  
       3  $result = db_query("SELECT * FROM {term_data} d WHERE d.vid = $VID ORDER BY d.name");
       4  
       5  while ($term = db_fetch_object($result)) {
       6     $strURL = url("taxonomy/term/or/$term->tid");
       7     $strName = $term->name;
       8     $items[] = l( $strName, $strURL);
       9  }
      10  
      11  return theme('node_list', $items);
    
    Toggle Line Numbers
  • edit the php with the correct vocabulary id (you can find this by going to the taxonomy administration screen, moving the mouse over the vocabulary in question and looking at the number of the vocabulary being edited in the URL in the status bar).
  • enable the block

Filed under: drupal php theme


Getting Drupal to run on Site5 was not entirely straightforward. I used the fantastico script thing to install it but I got 403 errors whenever I tried to access the site. The error told me that I could not access /index.php. This was resolved by putting the following in my .htaccess file:

Options ExecCGI

Then I was still getting a 403 error on the directory /. The error log said:

[Thu Sep  9 06:07:36 2004] [error] [client 80.88.204.40] Options FollowSymLinks or
SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden:
/home/bisiand/public_html/403.shtml

So I changed .htaccess as follows:

# Set some options
Options -Indexes
Options +ExecCGI
Options +FollowSymLinks
Options +SymLinksIfOwnerMatch

Drupal started working but I kept getting the following errors on each page:

warning: Cannot modify header information - headers already sent

This was because I had been editing the Drupal conf.php file using Site5's NetAdmin tool and whenever I saved the file a blank line was added to the end. php was treating this as content to be output. I had to download the conf.php file, edit it in Vim to delete the blank lines and upload it again.

Trying to modify the Drupal theme, I then got an error from marvin.theme about no base class to inherit from. To fix this I had to move the directories themes/marvin and themes/unconed to the /tmp directory to hide them. There may be a fix to get them going but I don't really care.

After this, everything was fine.


2 Comments

Created a new hosting account with site5. Impressed so far, 1.5G of storage, PHP, unlimited MySQL databases, auto-install of drupal, fast server, all for $7 a month. Sorry if this sounds like an advert.

My previous blog was hosted on Python Community Server and written using Python Desktop Server. I have a couple of reasons for changing, especially to something I have to pay for (!)

  • My Python Desktop Server install was not the 'official' version, it was a Gentoo package installation and it suffered from a number of little problems that I didn't have time to fix.
  • I've used Drupal at work and on another site and I really like it. Even when I have to drop into the php code I am not totally lost, the code is easy to follow.
  • Drupal is better documented.
  • All my blog entries are stored in a standard database format, not something obscure (heard of metakit ?).
  • I (think) I can set things up so that I can moderate comments. I was getting comment spam and I hate it, it makes me feel violated.
  • Drupal data entry has a cool 'preview' button, with Python Desktop Server it just gets published, complete with formatting errors.
  • Drupal search facilities just work. I never did work out the hack required to add a search to my Python Cumminity Server. The only way to find old posts was using the calendar thing, and that was buggy and did not link every day that had postings.

I could go on and on but the fact is, here I am.

ToDo list:

  • Create nice custom theme
  • Upload old blog

1 Comment

I have been fiddling for days on getting decent wiki formatting working in Drupal. My requirements are modest (ahem):

  • Bullet points entered typing a simple asterisk and a space: no toolbars, nothing more elaborate.
  • New style hyperlinks, far easier than restructuredtext e.g:
  • Facility to put in raw html, specificly source code snippets that have been syntax highlighted using vim.
  • No need to edit snippets, such as inserting indents in every line, just adding a start and end tag.

Drupal's problem, acknowledged in the forums, is that the system of filtering that is used to convert the raw text to the formatted html does not really work very well: the filters step on each other's toes. My specific problem was that code snippets I put in would be altered by later filters, specificly text in square brackets would be converted to hyperlinks that didn't work. The wiki module also managed to interfere with itself: every line was transformed unless an exclamation mark was put at the start of each line: a tedious amount of extra editing.

I tried a number of options:

  • try to get the latest phpwiki source to work with Drupal. I got this to a state where it was kinda working but it continually messed up external links. The code was hard work, complex object model, no useful comments (only FixMes). I gave up on this as my head was hurting from banging on a brick wall.
  • try using textile. I didn't like this ones syntax.
  • try using bbcode but the syntax is worse, virtually html using [] instead of <>.
  • try using the markdown module but this is not free for commercial use.
  • hack on the existing wiki module, adding the concept of blocks that are not processed by other forms of markup within the wiki module itself.

I've gone for the last option, I've added two forms of block tags:

<verbatim> tag
html entities are escaped so < > & etc can all be used:
  $text = str_replace("<p>%::%</p>";,"",$text);
  $text = str_replace("%::%</p>","",$text);
  $text = str_replace("%::%","",$text);
  $text .= $DontScrewWithSquareBrackets[9];
  $two = 1 & 1;

<rawhtml> tag
insert raw html, e.g. pre syntax-highlighted code

<?php
// $Id: wiki.module,v 1.8 2004/02/08 22:39:38 tdobes Exp $
/**
 * wiki.module - mostly taken from <http://phpwiki.sourceforge.net/>, v1.2.2
 */

function wiki_link($type) {
  if ($type == "system") {
    menu("wiki", t("Wiki Text Formatting Rules"), "wiki_page", 0, MENU_HIDE);
  }
}

function wiki_page()
{
  if (!user_access("access content")) {
    print theme("page", message_access(), t("Access Denied"));
    return;
  }

I'm not entirely happy with this as a solution, beating on the phpwiki code would have been better as that is a far more complete language. Maybe I will give that another try?

Update: I beat some more and did fix my problem. However, I came across other problems:

  • The vertabim tag is equivalent to my code tag, it does not allow raw html to pass through
  • phpwiki allows certain raw html tags to pass through, for example b, small, etc but not the font tag. The regexp matching that it uses is restrictive and does not allow tags with attributes past. This could not be fixed without hacking on the phpwiki code itself. I don't want to use a library I have to hack on directly. I could work around it by subclassing but what if the base classes get changed (ref broken PyDS problems).
  • phpwiki has a 'RawHTML' plugin but that applies to the whole page, not sections thereof. Also this did not work as it relied upon the larger phpwiki structure rather then the bit that converted a string to html.
  • phpwiki folk are paranoid about javascript security holes in raw html. I want this for intranet so anyone who breaks things gets sacked.
  • there are also purists who think the markup should be enough and html is a cop out. They are probably not people who like to push boundaries, they prefer to erect them.

I'll stick with my hacked wiki module until something better comes along.


Filed under: drupal php pyds theme vim

1 Comment

At work I am using Drupal as a CMS for blogging, organising project related information etc. I feel it is more suited to a collaborative role than PyDS which is essentially a private tool for publishing to a community server. The community servers available do not appear to be strong CMS systems.

Drupal is very nicely written and even I, a PHP n00b, have managed to write a Drupal module that enables me to email a posting from the work server to my home PyDS installation where it can be posted to my personal/public blog. The email->PyDS gateway that I set up for photo blogging does the posting of the email to the blog.

Main stubling block encountered was when random pieces of the email message received were missing. This turned out to be because the message was stored in the database with \r line delimiters rather than \n. When the message was transmitted this looked to the email stuff like VERY long lines so it proceeded to screw up. I'm not sure where these came from, whether the web browser uses these in text fields or what. This script turns them to \n's which everybody loves (except dos/mac zealots).

Here is my Drupal 'sendhome.module' which does the posting.

   1  <?php
   2  /*
   3   * Add option to send postings to home.
   4   * Inspired by the emailpage module but simplified.
   5   * No admin options, edit this module.
   6   */
   7  
   8  function sendhome_help($section = 'admin/help#sendhome') {
   9    $output = "";
  10  
  11    switch ($section) {
  12      case 'admin/modules#description':
  13        $output = t("Send page home");
  14        break;
  15    }
  16    return $output;
  17  }
  18  
  19  function sendhome_link($type, $node=0, $main) {
  20    global $user;
  21  
  22    $links = array();
  23  
  24    /*
  25     * If logged in user is moi, give me the option of sending this home.
  26     */
  27    if( $user->name == 'my drupal login name') {
  28          $links[] = l(t("Send Page Home"), "sendhome/confirm/$node->nid", array("title" => t("Send Page Home."), "callback" => "sendhome_page"));
  29    }
  30    return $links;
  31  }
  32  
  33  /**
  34   * Implementation of hook_menu().
  35   */
  36  function sendhome_menu($may_cache) {
  37      global $user;
  38      $items = array();
  39  
  40  //    if ($may_cache) {
  41          /*
  42           * Register mapping of path to callback function.
  43           */
  44          $items[] = array('path' => 'sendhome/confirm',
  45          'callback' => 'sendhome_page',
  46          'access' => user_access('access content'),
  47          'type' => MENU_CALLBACK);
  48   //   }
  49  
  50      return $items;
  51  }
  52  
  53  
  54  function sendhome_page( $uid = 0) {
  55    /*
  56     * Get function parameters.
  57     */
  58    $op = $_POST["op"];
  59    $edit = $_POST["edit"];
  60  
  61    if( empty($op)) {
  62    	/*
  63    	 * In initial link nid is in the url
  64    	 */
  65    	if( arg(1) == 'confirm') {
  66    		$nid = arg(2);
  67    	}
  68    } else {
  69    	/*
  70    	 * From the send button the nid is in a hidden field.
  71    	 */
  72    	$nid = $edit["nid"];
  73    }
  74  
  75    /*
  76     * Search db for nodes.
  77     */
  78    $nodes = db_query("SELECT nid, title, teaser, created FROM {node} WHERE nid = %d", $nid);
  79  
  80      drupal_set_breadcrumb(array(l(t('Home'), NULL), l(t('View'), "node/view/$nid")));
  81  
  82    while ($node = db_fetch_object($nodes)) {
  83    	/*
  84    	** Load the specified node:
  85    	*/
  86    	$item = node_load(array('nid' => $node->nid));
  87  
  88    	/*
  89    	 * Add the title and the body to the output under construction.
  90    	 */
  91    	$output .= $item->title;
  92    	$output .= "\n";
  93    	$body = str_replace( '<!--break-->', '', $item->body);
  94    	/* Pass body through filters to create html */
  95  //  	$output .= check_output( $body);
  96    	$output .= $body;
  97    }
  98  
  99    /*
 100     * Maybe it's my fault for using windows but \r line delimiters lead to VERY
 101     * long lines that don't make it through email without random bits missing.
 102     */
 103    $output = str_replace( "\r\n", "\n", $output);
 104    $output = str_replace( "\r", "\n", $output);
 105  
 106    if ($op != t("Send")) {
 107    	/*
 108    	 * Display the posting that is to be sent and a send button.
 109    	 */
 110    	$output = "<div class=\"node\">$output</div>";
 111    	$output .= form( form_submit(t("Send")) . form_hidden("nid", $nid));
 112    	print theme( "page", $output, "Post Message Home?");
 113    }
 114    else {
 115    	/*
 116    	 * Set email parameters.
 117    	 */
 118    	$strTo = "censored@microsoft.com";
 119    	$strFrom = "me@here";
 120    	$strMagicSubjectLine = "hush, it's a secret";
 121  
 122    	/*
 123    	 * Send operation so send the post and show a 'Done' page.
 124    	 */
 125    	mail( $strTo, $strMagicSubjectLine, $output, "From: $strFrom\r\n", "-f$strFrom");
 126    	print theme( "page", '', "Posted Message");
 127    }
 128  }
 129  
 130  ?>
Toggle Line Numbers

Filed under: blog drupal php pyds theme windows


In a weak moment I signed up for Stardock Object Desktop which is a set of various utilities for Windows. It's mostly a stupid toy but there are useful things in there.

Highlights:

Window Blinds

Flexible skinning for windows which I dabbled with before. I've found one theme that has readable colour schemes (not black text on dark blackground: 90% of theme designers appear to be Goths). The one I chose makes it hard to tell if a check box is checked.

SkinStudio

Skin editor. Very complex but it does mean I can create some bright cheerful themes to make people happy (or maybe I can't be bothered).

DesktopX

Put objects on the desktop. Have cute fish swim across the screen as you edit. Have a transparent clock 'always on top'. It is scriptable, it supports activescript but it only enables VBScript and JScript (MS version of JavaScript) not python, apperently because they could be bothered to support python syntax highlighting in the editor.

DriveScan

Incredibly useful tool to scan directory tree and show you where all those gigabytes have disappeared to. Shows pie charts, allows you to go into subfolders and delete stuff in place. Not a tool to use every day but good at what it does.

There is various other stuff to play with but I am wary of having too much crap installed.

One of the DesktopX toys was a text-to-speech thing using Microsoft SAM which I didn't realise existed in XP. I only have a male voice. I may try getting the desk top objects to say rude things as I move round the screen (what other use is text to speech?).

One nice thing about it is the licence: I can use it on as many computers as I like but only one at a time, like the old Borland Turbo Pascal paperback licence of the 80's.


Filed under: desktopx python theme windows


I changed the colour scheme of the weblog:

  • made the font slightly smaller

  • put underlines on links

  • made it all blue

These were all changes to the pyds.css style sheet, made via the themes link on the pyds desktop. I found I had to clear Mozillas cache to force the style sheet to be reloaded. Whether this is due to Mozilla or pyds I know not. I could test it with IE but I don't care that much.

I'd like to make the aggregator use less padding.


Filed under: pyds theme


Set Palm up so record button opens BigClock. Pressing and holding the select button brings up the World Clock app but the delay is annoying.

Downloaded a star trek theme for BigClock to make palm look more like a tricorder. Needs some flashing leds.

For palm buttons, I now have:

Button 1

Zlauncher

Button 2

DateBk5

Button 3

DayNotez

Button 4

Zlauncher Quicklaunch

Record

BigClock


Filed under: daynotez palm theme