The one-word review for the 27″ iMac is: stellar.
I’ve had my iMac about a month. Here are the basic specs.
{ 2 comments }
From the monthly archives:
The one-word review for the 27″ iMac is: stellar.
I’ve had my iMac about a month. Here are the basic specs.
{ 2 comments }
I got a a hell-a laugh out of this. ‘Cause I’m on a Mac.
{ 0 comments }
The Registry design pattern gives us a way to overcome scoping complexities in your object-oriented programs. In this post I want to talk about how we use a Registry class in the MojoMVC.
In the MojoMVC, every request requires a Request object. There are times when other objects need that information. PHP has global variables by default, with local variables inside regular functions, and public, protected, and private methods inside classes. Since we don’t speak Kludge here, we need a another strategy for passing information around. The Registry pattern fills the bill.
We use the Registry class to take advantge the fact that classes have super global visibility—they can walk through walls like the super global variables ($_GET, $_POST, etc), functions, and constants. In other words, our Registry class can function as a super global delivery messenger as long as we give it some static setters and getters.
The Registry Class
1 class Registry extends Base {
2 static private $data = array();
3
4 private function __construct() {}
5
6 static public function get($key)
7 {
8 return self::$data[$key];
9 }
10
11 static public function set($key,$value)
12 {
13 self::$data[$key] = $value;
14 }
15 }
We can use it like this:
Registry::set(’string’, ‘this is the name’);
print Registry::get(’string’); // output: this is the name
class NextClass {
function __construct() {
print Registry::get(’string’);
}
}
$n = new NextClass; // output: this is the name
Now we have a class that walks through walls to deliver the values stored inside it. All we have to do is store the Request object in the Registry, like this:
You’re probably wondering where $this->r came from. That’s an interesting story, but it will have to wait until next time.
For more information on the Registry pattern, check out your friendly Google.
{ 0 comments }
I’m lazy when it comes to writing valid HTML. I know it’s the right thing to do, but I’ve developed some bad habits over the years. There are too many times when I forget quotes, alt tags, and ending tags. So I’ve decided to outsource my HTML generation to a machine: Textile.
Textile is a “human web text generator”. I like Textile because I can use simple formatting cues to generate any HTML you want. A simple example would be,
p. This is a paragraph. "A link to a URL":http://someurl
Textile will turn that text into this HTML:
<p>This is a paragraph. <a href="http://someurl">A link to a <spanclass="caps">URL</span></a></p>
In my CCSF courses I’ve developed a small PHP framework that I use as a teaching tool for my advanced PHP course. I call it MojoMVC. MojoMVC generates output of any kind by employing Decorator classes to format the output. The default format is HTML, but Decorators can be of any kind, including XML, PDF, images, and so on. All you have to do is write the class for the format you want. I created a HTMLDecorator class to have Textile ease my HTML woes.
MojoMVC Overview:
The render in ApplicationController looks like this:
1 class ApplicationController extends Base {
2 // snip //
3 function render() {
4 // Default is HTMLDecorator
5 $klass = $this->as.'Decorator';
6 // Decorators all have a render()
7 $decorator = new $klass;
8 // Pass the current instance to the decorator for rendering.
9 $decorator->render($this) ;
10 exit;
11 }
12 }
By the way, one of PHP’s Good Parts in visible in this method—the easy implementation of polymorphism in lines 5, 7, and 9.
After we define the render method, the next step is to create a Decorator that will take the current instance and render its output using Textile. Here’s how it works.
The MojoMVC HTMLDecorator
1 class HTMLDecorator
2 {
3
4 function render($klass)
5 { // $klass is instance of current controller
6 $textile = new Textile; // new Textile object
7 // Check to make sure we have the requested object
8 if (file_exists(VIEWS.$klass->r->controller.'/'.$klass->r->action.'.html'))
9 {
10 // If so, run the method requested
11 if (method_exists($klass->r->controller.'Controller', $klass->r->action))
12 {
13 $action = $klass->r->action;
14 $klass->$action();
15 }
16 // Buffer output so we can pass it to Textile
17 ob_start();
18 include (VIEWS.$klass->r->controller.'/'.$klass->r->action.'.html');
19 // Textileize the HTML
20 $klass->out = $textile->textileThis(ob_get_clean());
21 } else
22 {
23 include (VIEWS.$klass->r->controller.'/'.$klass->r->error404.'.html');
24 }
25 // Include the layout HTML file that displays the requested page.
26 if (file_exists(LAYOUTS.$klass->r->controller.'.html'))
27 {
28 include LAYOUTS.$klass->r->controller.'.html';
29 } elseif (file_exists(LAYOUTS.'default.html'))
30 {
31 include LAYOUTS.'default.html';
32 } else
33 {
34 print $klass->out;
35 }
36 }
37 }
Most of this code is all about error checking. Textileizing is a matter of saving the output (using ob_start and ob_get_clean), loading Textile, creating an instance, and running the text through the textileThis method.
To learn more about Textile, check out the Textile home page. Textile has been ported to Ruby, where it is known as RedCloth.
For an easy-to-digest introduction to the Decorator design pattern, check out the Head First Design Patterns sample chapter.
Happy hacking…
{ 0 comments }
Now that Twitter has been hacked again, and we’ve been cast back into the Dark Pre-Twitter Ages, one has the sense that we have reached the End of Innocence stage in our love affair with the social. We have to take a step back and think, how am I going to drive traffic to my site without the mighty Twitter to broadcast my bits of wit to the world? Let’s face it, running your mouth on Twitter is a helluva lot more fun than agonizing over the SEO for some product you want to inject into the Collective Unconscious.
Twitter is where it’s at, at least this is what the Know-It-Alls are proclaiming—the Kawasaki’s, the Scobleizers, the Ferriss’s and Godin’s. Don’t they all bray that you must use Twitter or you will die a miserable cringing death in a ditch as the journalist/pundits/prize-winning-hackers stand over your pathetic corpse and pronounce you an incorrigible moron? Pardon my indignation, but this is the message the authorities are sending: use Twitter or fail, dude.
Oh, they may be right, those pundits—when Twitter is actually up and working. But what if Twitter is being bombed into the Stone Age by some techno brutes who want to ruin our fun and profit. Then, the man/woman whose life hangs by a fragile Twitter thread will find themselves in the tank. Of course, there will be at least one contrarian anti-pundit shouting that those who Live by the Twitter, Die by the Twitter.
As Twitter hardens up—as it will no doubt do—will it still remain fun and open and a breath of fresh air? If we can judge by the other big social sites—Friendster and Myspace and Facebook—we’re in for some big changes. Those bad boys all evolved from innocent honeypots to crass social mining advertising operations. Twitter will go that way of all flesh once the investors start asking for some of their money back and “relevant” ads start to appear next to our brilliant bon mots. Once Twitter tries to mine that rushing stream of real time data flowing through it, they will choke off what makes Twitter cool: its wind-in-the-hair, driving-daddy’s-convertible, summer-vacation freedom from having to earn a living. Once the kid has to get a job and and pay the piper, look out.
Whoa! Hey, I gotta go now. Twitter is back up. I’ve got to push this blog post into the Stream. Later.
Happy hacking…
{ 0 comments }
I LOLed and LMAO as I read. Fake Steve is saying what we’re all thinking about the pinheads at ATT.
Happy hacking…
{ 0 comments }
Have you noticed that your Drupal app feels sluggish? Here’s a visual map of the wheel-spinning Drupal goes through to say “Hello, World”. It’s impressive and depressing at the same time. Click on the image to see the whole story.
{ 0 comments }
This blog usually gets about 7 visits a day, mostly from robots, or the occasional Internet Wanderer who accidentally falls into my domain. However, On Dec 1, I posted a few pictures of my bookshelves buckling under the weight of my O’Reilly books, and Tim O’Reilly himself posted an “LOL” retweet with a link to this site. As you can see from my Sitemeter stats, I came into Internet Existence for a brief moment.
I can only wonder what it’s like to sway the minds and hearts of a legion of followers. So I’m thinking, if Tim O’Reilly can get me 500 hits, what would a real celebrity get me? Hey Ashton Kutcher, I’m talking about you AplusK.
{ 0 comments }
At least part of it. If Tim actually has a plane. What I’m trying to say is that I’m a big consumer of those old-fashioned things called books. I love them. Here are pictures of my current collection of programming and computer science books. I also have an extensive collection of literature—fiction and poetry. Hey, that’s how I roll.
I still have my first O’Reilly book, Unix Power Tools. I keep most books for 2 to 3 years. Programming books have the life span of a mayfly. Relevant today, recycled tomorrow. Long live O’Reilly books.
{ 4 comments }