Thursday, November 05, 2009

Zend Framework Ctags for BBEdit

BBEdit version 9.3 was released yesterday. Many changes but, it includes extensively revised support for PHP.

Best of all specially formatted Ctags files can now be used to provide function signature auto-complete, similar to that from clippings.

As such I've knocked up a version for Zend Framework, which can grab it from the downloads page.

As it says there, this is a one afternoon, first draft so make sure you subscribe to the RSS for updates. Let me know if you have any issues.

(Know problems are a lack of reference back to source file and line number, but I'll get that fixed asap.)

Enjoy.

Wednesday, October 21, 2009

Frequent Bugs

Supposedly keeping a log of bugs helps you identify the most common ones. At the moment mine is forgetting to save my nib file before building my application.

("Why isn't this working?")

Tuesday, September 15, 2009

BBEdit Zend Framework Clippings Updated

I’ve just uploaded the latest version of the Zend Framwork Clipping set for BBEdit. As usual you can grab this from the downloads page.

Changes in this release

  1. Added the class to the clipping name to disambiguate duplicate method names. (Picture __construct 1000 times.)

    Since BBEdit doesn’t allow whitespace in autocomplete suggestions, I’ve used a double-star ** as the divider between method and class name. This I hope is clear enough visually, but please let me know what you think.

  2. Added parameter and return type hints to the clippings in line with the conventions of Ted’s original PHP clippings. (The return value is selected upon clipping insertion so a quick delete will get rid of it; its purpose is currently just as an aide memoir but I hope to leverage it further later.)

Barring any major issues, this will be the final Beta of the BBEdit Zend Framework Clippings. They are just missing clippings for the Zend_Search_Lucene and Zend_Soap namespaces, which require ad hoc work-arounds. After that they will follow the Zend Framework release schedule.

Thursday, August 20, 2009

Beta 1 of Zend Framework Clippings for BBEdit Released

Update: the BBEdit Zend Framework Clippings have been updated.

We've just uploaded the first beta of our new Zend Framework Clipping set for BBEdit.

You can grab it from the downloads page.

The set currently covers 99%+ of the Zend Framework's methods, but we're aiming for 100%. After that we'll be following Zend Framework releases. (Updates via the newsletter.)

As per usual, bugs via the contact page, questions/suggestions welcome on the discussion board.

Friday, August 14, 2009

Using Zend Framework's FlashMessenger Action Helper

We often want to provide users feedback from their actions. Zend Framework includes the FlashMessenger Action Helper for this purpose.
A gentle trickle of questions appear on the Zend Framework mailing lists concerning the exact usage of the FlashMessenger, so I'm going to go over the details here. Hopefully we'll get all those Zend Framework FlashMessenger questions answered.
We will also introduce the Noumenal PHP Library's FlashMessenger View Helper. This encapsulates retrieving flash messages and adds the option to send different levels of message (e.g. "notice", "warning", "error").
The Noumenal PHP Library is available on GitHub.

Overview of the FlashMessenger

Zend Framework's FlashMessenger Action Helper is meant to allow immediate feedback on the status of a user's actions: "Your profile was updated", "Your message was sent", "Your junk mail has been deleted".
Here's an example of the sort of thing from Google's Gmail:
Example of a FlashMessenger
style message from Google's Gmail
Basic usage of the FlashMessenger couldn't be simpler. In your action controller, you set messages via the addMessage() method:
$flashMessenger = $this->_helper->FlashMessenger;
$flashMessenger->addMessage('We did something in the last request');
or via its proxy, the FlashMessenger's direct():
$this->_helper->FlashMessenger('Message stored until needed');
( Action helpers can each define their own direct() as a short cut to their core functionality.)
Under normal circumstances you'd collect any messages when you want to display them:
//Collect array of messages for display.
$aMessages = $this->_helper->FlashMessenger->getMessages();
And that is all there is to it. Your user performs some action, e.g. sending their message; you redirect them somewhere sensible and let them know it was successful.
Note, however, the "Under normal circumstances". There are a couple of wiggles that can catch you out. We'll go over these as way of introduction to the Noumenal PHP Library's FlashMessenger View Helper, which handles these.

Messages are stored until the FlashMessenger is next instantiated

The FlashMessenger stores its messages in a Zend_Session namespace. The data in that namespace is collected each time the FlashMessenger is instantiated (i.e. in the constructor). The data in the namespace is also cleared (via unset()) at the same time. This can cause problems for people when they wish to add an extra action in between setting the messages and retrieving them. If on the extra request they accidently instantiate the FlashMessenger whilst not wanting to collect the messages then they find that they are not there when they do want them later.
The rule here is simple. Contrary to the bad example in the documentation, which assigns the FlashMessenger to an instance variable in the controller's init(), do not get a reference to the FlashMessenger until you actually need it.

There's also a getCurrentMessages() Method

Sometimes we want to send users a message not for the next request but for the current one. The obvious example of this is a failed form validation. Here we output the form with error messages and ask the user to resubmit. Zend_Form has Decorators specifically for displaying form and element level errors, but beyond this it's good on the consistency front to send a message via the normal messaging channel to let the users know that there was a problem.
Calling the regular getMessages() method here won't work. This only returns messages which were stored in the appropriate ZendSession namespace when the FlashMessenger was instantiated. Since any messages added this request were not in the ZendSession namespace at that time (because the FlashMessenger was instantiated in order to add the messages) they won't be returned by getMessages().
For just this use-case, the FlashMessenger also provides a getCurrentMessages() method (and a related family of current methods) which returns those messages set on the current request.

The Noumenal PHP Library's FlashMessenger View Helper

The FlashMessenger View Helper encapsulates the message retrieval side of our interactions with the Zend Framework's FlashMessenger Action Helper. It checks for messages from both previous requests and the current request, so it satisfies our use-case from above. It also interprets key-value pairs, rather than a simple strings, passed to the FlashMessenger as specifying a message-level.
Setting up the View Helper
The first thing to do is to add the call to echo the FlashMessenger View Helper to your layout script, say above the main content:
<html>
<head></head>
<body>
    <div id="hd">
        <!-- Header -->
    </div>

    <div id="bd">
        <div>
            <!-- Main Content -->
            <?php echo $this->flashMessenger(); ?>
            <?php echo $this->layout()->content; ?>
        </div>
        <div>
            <!-- Sidebar -->        
        </div>
    </div>

    <div id="ft">
        <!-- Footer -->
    </div>
</body>
</html>
Since the layout script is rendered so late in the dispatch process, putting the call the the FlashMessenger View Helper here eliminates most of the risk that you'll accidently instantiate the FlashMessenger Action Helper when you don't mean to. (Of course this is still possible but if you're going out of your way to instantiate it then we can assume that you'll know to handle any messages that still need to be displayed.)
Adding Messages (with levels) to the FlashMessenger
Adding messages to the FlashMessenger proceeds via the HelperBroker unchanged. Add simple string messages as you normally would:
$this->_helper->FlashMessenger('Your message was sent.');
If you want to specify a message-level pass a key-value pair instead:
$this->_helper->FlashMessenger(
    array('error' => 'There was a problem with your form submission.') 
);
By default, the FlashMessenger View Helper will render the message within a p tag with a class attribute of the message-level key.
Advanced Options to the FlashMessenger View Helper
You can specify the default message-level by passing a string value as the first parameter to flashMessenger(). The default message-level is 'warning'. To change this to 'notice', in your layout do:
<?php echo $this->flashMessenger('notice'); ?>
This applies to simple string messages only. If key-value pairs are passed to the FlashMessenger, any message-level key will override the default value set here.
Finally, you can override the default message template by passing a format specifier string (suitable for the printf family of functions) as the second parameter. The default template is <p class="%s">%s</p> (where the message-level and message fill the respective placeholders).
As an example, if you regularly expected multiple flash messages, you could render messages as an unordered list by doing this in your layout:
<ul>
    <?php echo $this->flashMessenger('notice', '<li class="%s">%s</li>');?>
</ul>
Here we have also set the default message-level to 'notice'.
The FlashMessenger View Helper is part of the Noumenal PHP Library and is available on GitHub.

Introducing the Noumenal PHP Library

We just added the first version of the Noumenal PHP Library to the downloads page.

This is a collection of PHP classes built on top of Zend Framework. The Zend Framework team aim for an 80% solution. The Noumenal PHP Library is the next 10%.

It's released under a new BSD licence.

At the moment there's not much in the Noumenal PHP Library, just a FlashMessenger View Helper to begin with. We've got a big backlog of code to include but it takes time to get our private code massaged for an open-source release.

Download a copy, try it out and keep up to date via the newsletter.

Bugs via the contact page, questions welcome on the discussion board.

Saturday, August 08, 2009

Towards a One-Step Build (part1)

Number 2 on the Joel Test is “Can you make a build in one step?” At Noumenal the answer to this (on this date, but not for much longer) is still “No”.

The necessary explanation that accompanies all such “No” answers is, in this case, “we’ve been building small-to-medium web applications that didn’t force us into automated builds, and we didn’t know any better”.

Well now we’re building enterprise grade multi-platform, multi-language, high-availability, n-tier architecture, distributed applications, integrated via asynchronous messaging services and exposing open-standards web service APIs. We damn-well need a one-step build now.

In moving from here to there, step 1 is easy: Write down exactly what you do for each of the steps of your current build.

That’s it. Nothing more to it.

Each of the steps are themselves really easy. (They must be otherwise you’d already have another way of doing it.) Scripting each step individually will be easy too — once you know what they are. All that then will remain is a script to run each of the mini-scripts in order.

Sounds simple doesn’t it.

Tuesday, July 07, 2009

12 on The Joel Test

I started Noumenal 3 and a half years ago now. In that time I've learnt to program and written some software, some of which has actually been good. My greatest achievement by far is that, one year after the birth of my first child, I'm still business. (Just before his birth, I'd guess, not many thought that likely.)

Starting out, just surviving was always going to be a lot harder than my natural arrogance would allow: I was a philosophy PhD and despite my focus on the more technical areas, philosophy is the archetypal liberal art and liberal arts majors don't know anything about developing software. Thankfully for me I knew nothing of this.

More thankfully though, I'm stubborn, as much as that may not be good for my mental health. I have learnt the hard way about the need for specifications and testing and iterative development, and all the rest of it.

As much of an achievement as still being in business is, it is but a platform for success rather than success itself. (My long term goals were slightly more ambitious than merely not going bankrupt.) As such I've decide to apply the famous Joel Test, 12 yes or no questions to help you determine how good your software development process is.

For those of you who may not be familiar, the 12 points of The Joel Test are:

  1. Do you use source control?
  2. Can you make a build in one step?
  3. Do you make daily builds?
  4. Do you have a bug database?
  5. Do you fix bugs before writing new code?
  6. Do you have an up-to-date schedule?
  7. Do you have a spec?
  8. Do programmers have quiet working conditions?
  9. Do you use the best tools money can buy?
  10. Do you have testers?
  11. Do new candidates write code during their interview?
  12. Do you do hallway usability testing?
(I'll be discussing these in reference to their application at Noumenal in future posts but you can read Joel's original discussion for more details now.)

A quick count says I'm currently running at 4 (which could pretty easily be bumped to 6) but 4 (or even 6) isn't good enough. As Joel says, companies like Microsoft run at 12 full-time.

Goals should be SMART: specific, measurable, achievable, realistic and time-boxed. Here's my goal: I will be at 12 on The Joel Test by 6th July 2010, the day my boy is two.

Friday, June 12, 2009

Noumenal Web Site (Re)development

After much time, and many delays, the Noumenal web site is finally beginning the process of taking shape. We at least now have a sitemap for the forthcoming v1.0: (Generated using http://writemaps.com/.)

Friday, May 15, 2009

Pure Demonstratives and Logically Proper Names

My ten month old hasn’t yet grasped pointing: “Look over there”, arm outstretched, hand clenched, index finger extended; he looks at the finger rather than anything else.

Observing this brings to mind remarks of Wittgenstein’s to the effect that even our most basic demonstratives are already embedded within what we might model as a representational schema:

Are “there” and “this” also taught ostensively?—Imagine how one might perhaps teach their use. One will point to places and things—-but in this case the pointing occurs in the use of the words too and not merely in learning the use. [P.I. 9]

I’ve always taken this kind of remark (i.e. it and many others like it) as telling against the possibility of a pure demonstrative, of a spoken “This” or of a “That” which successfully picks out an otherwise unknown something, without in so doing imposing preconceptions upon it.

From the logical point of view they would tell against the possibility of a purely designative occurrence of a name—one which in a subject-predicate sentence of the form “S is P” would allow all of the intensional content to reside with the predication.

Here, rehearsing Russell, we might draw the distinction between names as they commonly appear, which may be laden with predicative content—Ivan the Terrible, say—and logically proper names which, being purely designative, may not.

With this stipulation in place, note that whilst we all agree that names as they commonly appear are not logically proper names so defined, the claim at stake is the much stronger one that names howsoever they appear are never logically proper names. That is, that there are no such things as logically proper names. (This would not be worth remarking if the contrary were not, still, so commonly held.)