Blog Posts
Dreamweaver, Text Editors, and Webmasters
I picked up on this article on Friday, glanced through it and moved on, but noticed this evening it had been slashdotted — at which point I realized the author is the current CGI::Application maintainer, so I looked again.
At my first glance through it, it appeared the author was looking for a nice, easy-to-use pre-processor script for generating a site out of templates and content files. To that end, he, in the end, recommended ttree, part of the Template Toolkit distribution.
However, the real gist of the article — something that should probably have been summarized at the end — is that the author was looking for a free and OSS replacement for DreamWeaver's Templates functionality. This functionality allows a developer to create a template with placeholders for content, lock it, and then create pages that have the bits and pieces of content. Finally, the developer compiles the site — creating final HTML pages out of the content merged with the templates.
Now, I can see something like this being useful. I've used webmake for a couple of projects, and, obviously, utilize PHP in many places as a templating language. However, several comments on Slashdot also gave some pause. The tone of these comments was to the effect of, "real developers shouldn't use DW; they should understand HTML and code it directly." Part of me felt this was elitist — the web is such an egalitarian medium that there should be few barriers to entry. However, the webmaster in me — the professional who gets paid each pay period and makes a living off the web — also agreed with this substantially.
I've worked — both professionally and as a freelancer — with individuals who use and rely on DW. The problem I see with the tool and others of its breed is precisely their empowerment of people. Let me explain.
I really do feel anybody should be able to have a presence on the 'net. However, HTML is a fragile language: trivial errors can cause tremendous changes in how a page is rendered — and even crash browsers on occasion. The problem I see is that DW and other GUI webpage applications create, from my viewpoint, garbage HTML. I cannot tell you how many pages generated by these applications that I've had to clean up and reformat. They spuriously add tags, often around empty content, that are simply unnecessary.
The problem is compounded when individuals have neither time nor inclination to learn HTML, but continue using the tool to create pages. They get a false sense of accomplishment — that can be quickly followed by a very real sense of incompetence when the page inexplicably breaks due to an edit they've made — especially when the content is part of a larger framework that includes other files. Of course, as a web professional, I get paid to fix such mistakes. But I feel that this does everybody a disservice — the individual/company has basically paid twice for the presentation of content — once to the person generating it, a second time to me to fix the errors.
This is a big part of the reason why I've been leaning more and more heavily on database-driven web applications. Content then goes into the database, and contains minimal — if any — markup. It is then injected into templates, which go through a formal review process, as well as through the W3C validators, to prevent display problems. This puts everybody in a position of strength: the editor generating content, the designer creating the look-and-feel, and the programmer developing the methods for mapping content with the templates.
There's still a part of me that struggles with what I perceive as an elitist position. However, there's another part of me that has struggled heavily with the multitasking demands made on all web professionals — we're expected to be editors, graphic designers, programmers, and more. In most cases, we're lucky if we're strong in one or two such areas, much less passionate about staying abreast of the changing face of our medium.
Happy New Year!
It's about 50 minutes shy of 2005 here, and Maeve has finally succumbed to sleep, I'm almost done with my stout, and we're in West Bolton without TV for the second year running (yay!).
I hope the new year brings peace and happiness to one and all! Happy coding!
Smarty $_SERVER vars
I don't know why I never bothered to look this up, but I didn't. One thing I
typically do in my parent Cgiapp classes is to pass $_SERVER['SCRIPT_NAME']
to the template. I just found out — through the pear-general newsgroup — that
this is unnecessary: use $smarty.server.KEY_NAME
to access any $_SERVER
vars
your template might need.
Sign of a Geek
It's now been confirmed: I'm a geek.
Okay, so that probably comes as no shocker to those of you who know me, but it's the little things that make me realize it myself.
I've been frequenting Perl Monks for a couple of years now, mainly to garner ideas and code to help me with my personal or work projects. I rarely post comments, and I've only once submitted a question to the site. However, I do frequent the site regularly, and the few comments I've put in — generally regarding usage of CGI::Application — have been typically well-moderated.
Well, yesterday I made a comment to a user asking about editors to use with perl. I was incensed by a remark he made about VIM not having the features he needed. Now, as I said in my comment, I've used VIM on a daily basis for over two years, and I'm still discovering new features — and I've used all of the features he was looking for.
This is where I discovered I'm a geek: my comment made it into the Daily Best for today, peaking around number 5. The fact that that made my day indicates to me that I must be a geek.
Oh — and VIM rules!
Cgiapp mentioned in php|architect!
A new Cgiapp user reported they had stumbled across the project in php|architect! It's in the current, October 2004 issue, in the News section, prominently displayed in the upper right corner of the page. The announcement blurb is straight from my freshmeat project page for version 1.4. Cgiapp is carving a name for itself!
Cgiapp 1.5.1 released
At work this week, I discovered a bug with how I was calling
set_error_handler()
in Cgiapp's run()
method. Evidently passing a reference
in a PHP callback causes issues! So, I corrected that.
I also made a minor, one-character change to query()
to make it explicitly
return a reference to the $_CGIAPP_REQUEST
property array.
You can see full details at the Cgiapp download page.
Cgiapp 1.5 released
Cgiapp 1.5 has been released; you may now download it.
This release fixes a subtle bug I hadn't encountered before; namely, when a
method name or function name is passed as an argument to mode_param()
, run()
was receiving the requested run mode… and then attempting to process that as the
mode param. The behaviour is now fixed, and is actually simpler than the
previous (non-working) behaviour.
Also, on reading Chris Shiflet's paper on PHP security, I
decided to reinstate the query()
method. I had been using $_REQUEST
to check
for a run mode parameter; because this combines the $_GET
, $_POST
, and
$_COOKIE
arrays, it's considered a bit of a security risk. query()
now
creates a combined array of $_GET
and $_POST
variable ($_POST
taking
precedence over $_GET
) and stores them in the property $_CGIAPP_REQUEST
; it
returns a reference to that property. run()
uses that property to determine
the run mode now.
Enjoy!
When array_key_exists just doesn't work
I've been playing with parameter testing in my various Cgiapp classes, and one test that seemed pretty slick was the following:
if (!array_key_exists('some_string', $_REQUEST)) {
// some error
}
Seems pretty straight-forward: $_REQUEST
is an associative array, and I want
to test for the existence of a key in it. Sure, I could use isset()
, but it
seemed… ugly, and verbose, and a waste of keystrokes, particularly when I'm
using the param()
method:
if (!isset($_REQUEST[$this->param('some_param')])) {
// some error
}
However, I ran into a pitfall: when it comes to array_key_exists()
,
$_REQUEST
isn't exactly an array. I think what's going on is that $_REQUEST
is actually a superset of several other arrays — $_POST
, $_GET
, and
$_COOKIE
— and isset()
has some logic to descend amongst the various keys,
while array_key_exists()
can only work on a single level.
Whatever the explanation, I ended up reverting a bunch of code. :-(
MySQL Miscellanae
Inspired by a Slashdot book review of High Performance MySQL.
I've often suspected that I'm not a SQL guru… little things like being self
taught and having virtually no resources for learning it. This has been
confirmed to a large degree at work, where our DBA has taught me many tricks
about databases: indexing, when to use DISTINCT
, how and when to do JOIN
s,
and the magic of TEMPORARY TABLE
s. I now feel fairly competent, though far
from being an expert — I certainly don't know much about how to tune a server
for MySQL, or tuning MySQL for performance.
Last year around this time, we needed to replace our MySQL server, and I got handed the job of getting the data from the old one onto the new. At the time, I looked into replication, and from there discovered about binary copies of a data store. I started using this as a way to backup data, instead of periodic mysqldumps.
One thing I've often wondered since: would replication be a good way to do backups? It seems like it would, but I haven't investigated. One post on the aforementioned Slashdot article addressed this, with the following summary:
- Set up replication
- Do a locked table backup on the slave
Concise and to the point. I only wish I had a spare server on which to implement it!
PHP_SELF versus SCRIPT_NAME
I've standardized my PHP programming to use the environment variable
SCRIPT_NAME
when I want my script to refer to itself in links and form
actions. I've known that PHP_SELF
has the same information, but I was more
familiar with the name SCRIPT_NAME
from using it in perl, and liked the feel
of it more as it seems to describe the resource better (PHP_SELF
could stand
for the path to the PHP executable if I were to go by the name only).
However, I just noticed a post on the php.general newsgroup where somebody asked
what the difference was between them. Semantically, there isn't any; they should
contain the same information. However, historically and technically speaking,
there is. SCRIPT_NAME
is defined in the CGI 1.1 specification, and is thus a
standard. However, not all web servers actually implement it, and thus it
isn't necessarily portable. PHP_SELF
, on the other hand, is implemented
directly by PHP, and as long as you're programming in PHP, will always be
present.
Guess I have some grep and sed in my future as I change a bunch of scripts…