Results tagged “web application”

A couple of weeks ago I commented upon Apple's decision to not support Flash on any of their mobile devices:

I would prefer to say "Flash is a hack," but I think Flash is too elegant to risk maligning it with such a word. Make no mistake though, as ubiquitous and well implemented that Flash is, it is just a shim, which evolved to address a major short coming on the web, mainly that the underlying specifications and browser creators could not adopt or drive adoption fast enough the technology to make animation and richer application development possible.

Today, Steve Jobs posted a letter detailing this same decision (a letter worth reading in full):

Flash was created during the PC era - for PCs and mice. Flash is a successful business for Adobe, and we can understand why they want to push it beyond PCs. But the mobile era is about low power devices, touch interfaces and open web standards - all areas where Flash falls short.

New open standards created in the mobile era, such as HTML5, will win on mobile devices (and PCs too). Perhaps Adobe should focus more on creating great HTML5 tools for the future, and less on criticizing Apple for leaving the past behind.

I echo my sentiment again:

In just a few short years, when the gap Flash helped bridge is finally closed by well implemented and broadly adopted web standards, and the world of application development is expanded to include not just Objective-C and Flash programmers, but the entire world of HTML/CSS and Javascript programmers, hopefully a number of us will look back at this moment and say, "I can't believe I cared so much about this."

I know for many people, especially Adobe, the decision not to support Flash is an incredibly sensitive subject, but speaking as a web developer, I applaud them for taking a principaled stand in support of open web standards. The alternative, the reluctant support of an older and more obsolete technology to placate a dwindling group of laggards, can only saddle the entire web development industry with the burden of supporting a platform that is increasingly harder and more costly for us to support.

Need I remind web developers of the ire they feel when a client requires them to support Internet Explorer 6 and what it does to the products we build for them? Need I remind you of the hack after hack after hack we must implement and re-implement just to appease the CEO of a company who is too old and too lazy to upgrade their frack'n browser already?

Flash is the mobile and open web's IE6 and I am glad that a company with the market muscle to actually make a difference is taking a stand for what proponents of the open web have been saying for years.

Update:

Kottke chimes in:

Jobs sort of circles around the main issue which is, from my own perspective as heavy web user and web developer: though Flash may have been necessary in the past to provide functionality in the browser that wasn't possible using JS, HTML, and CSS, that is no longer the case. Those open web technologies have matured (or will in the near future) and can do most or even all of what is possible with Flash. For 95% of all cases, Flash is, or will soon be, obsolete because there is a better way to do it that's more accessible, more open, and more "web-like".

The coolest thing I know about right now is jQTouch, a jQuery framework for implementing mobile web apps. I first saw this at SXSW when its creator showed it off to a crowd that had just finished watching a demo of how to build iPhone apps in Objective-C. Which each step of his demo, the crowd in the room literally cheered as they saw how jaw-droppingly simple building slick iPhone apps just became.

Here is a recently released demo of some of the amazing things the relatively young jQTouch is capable of, which in this case is a fully HTML, CSS and Javascript powered version of the iPhone's iCal application.

So what makes this so smooth and seamless? Mainly that CSS3 is hardware accelerated on the iPhone making CSS and Javascript powered transitions and animations super smooth - just as smooth as any native application in fact.

So while you perhaps marvel at how amazing jQTouch is, let me bring this back to something that makes this framework so relevant in light of the recent hullabaloo associated with Apple's changes to its SDK Agreement which essentially forbids the use of flash enabled apps on the iPhone and iPad.

Flash is a Shim

I would prefer to say "Flash is a hack," but I think Flash is too elegant to risk maligning it with such a word. Make no mistake though, as ubiquitous and well implemented that Flash is, it is just a shim, which evolved to address a major short coming on the web, mainly that the underlying specifications and browser creators could not adopt or drive adoption fast enough the technology to make animation and richer application development possible.

Amazingly, Apple is poised to unwedge this shim that we have all become so unwittingly dependent upon. By refusing to put Flash on the iPhone and iPad they are going to force the market and technology developers who want to play in that market to learn and embrace the bleeding edge in web standards. They are going to do in just a few short years, what even the largest and most well intentioned companies like Google, in all of their open-sourcey-goodness, could never do: force market adoption of the technologies that will render Flash obsolete.

And thank god. The web has too many crutches like Flash, which solve a problem just well enough that they stifle developer communities from addressing problems at a lower level.

So while some express their ire at Apple for not supporting Flash, like my wife who just wants to play a damn Flash-powered movie on Hulu on her iPad, I applaud Apple for the courage it took to make what it must have known would be the unpopular decision it did. Because in just a few short years, when the gap Flash helped bridge is finally closed by well implemented and broadly adopted web standards, and the world of application development is expanded to include not just Objective-C and Flash programmers, but the entire world of HTML/CSS and Javascript programmers, hopefully a number of us will look back at this moment and say, "I can't believe I cared so much about this."

I recently added the following chapter to Movable Type's Open Source Operations Manual and wanted to publish here for review by the community and feedback.

About Publish Queue

The Movable Type Publish Queue is an essential component to any large scale Movable Type powered web site because it plays a crucial role in publishing performance optimization. There are a number of benefits to using the publish queue, they are:

  • It eliminates redundant, duplicated and unnecessary publication of files.
  • It offloads publishing to stand alone process which can be throttled and scaled independently from the Movable Type web application itself.
  • It speeds up the commenting experience by reducing the number of files that an end user must wait to be published prior to being able to navigate the web site again.

How it Works

It might be best to describe how the publish queue works by examining a scenario in which it would be utilized: republishing the necessary files in response to a comment.

Adding Jobs to the Queue

When a comment comes in to Movable Type multiple files are often in need of being updated, not only because the comment needs to be published to the entry's permalink page, but also because multiple other pages which display a comment count associated with the comment's entry may need to be updated.

Each of those pages (assuming they are configured to be published via the publish queue) will then be added to the "publish queue." When this happens, a publishing "job" is created and added to the database for each page that need to be published. There is one row in the database for each individual job in the system.

Now let's assume for a moment that shortly after receiving the first comment, a second one is published by a different visitor to your web site. This action also results in pages needing to be republished. However this time, before those pages are added to the queue as jobs the system checks to see if a job corresponding to each page is already on the queue. If there is, then the job is discarded because its work would be unnecessarily duplicated otherwise. If the job is not already on the queue, then it is added. This ensures that no unnecessary work is performed by the system.

In addition, each page that is added to the publish queue is given a priority which dictates the order in which the corresponding job will be processed. The higher the priority, the sooner the system will work on the job. Movable Type assigns priority based upon the following criteria:

Page/Template TypePriority
Preferred Page and Entry archives10
Index templates with a filename beginning with "index" or "default"9
Feed index templates9
All other index templates 8
Non-preferred Page and Entry archives5
Daily archives4
Weekly archives3
Monthly archives2
Any Category archive1
Any Author archive1
Yearly archives1

And that is how jobs are added to the queue. There is a separate process that exists that is then responsible for publishing.

Creating Publish Queue Workers

One or more publish queue "workers" can be created to process jobs on the queue. The number of workers needed by a system is based largely upon two variables:

  • The capacity of any one worker to process jobs on the queue.
  • The volume of jobs being added to the queue over time.

A worker is created by running the "run-periodic-tasks" script that comes with every copy of Movable Type. This script can be run in three modes:

  • daemon mode - in this mode the script never quits; instead it constantly monitors the job queue for work to be done and nearly the instance a job is made available for work, the script will begin work on it.

  • run-once - in this mode the script is run via the command line and will quit only after there is no more work on the queue to be done.

  • scheduled task - in this mode the script is executed in the "run-once" mode periodically according to a schedule defined by cron or a similar service.

Processing Jobs on the Queue

Each worker will monitor the queue for jobs. When one becomes available it is pulled off the queue to be worked on. Once it is "off the queue" no other workers can claim it. This makes sure that no two workers are trying to work on the same job at the same time.

In the event that something goes wrong during the publishing process and the file is not published, then the system will notice saying something skin to, "uh-oh, look at this job that was claimed on the queue, but was never successfully finished," and then free up the job for a worker to pick up and try again on. If the task is retried more than 5 times, then the job is marked as failed and left on the queue. In this state it is possible for a similar job to be placed on the queue, and if the problem that was resulting in the published failure is not transient, then that job is likely to fail again.

An important thing to note is that if a job is pulled off the queue by a worker to be worked on, then it remains possible at that point in time for that same page to be added to the queue again in response to the receipt of another comment. The rational being that by the time the page is finished being rebuilt it is most likely out of date, and so needs to be published again.

What Powers It?

The Publish Queue is powered by a stand alone job/queue management library called "The Schwartz." The Schwartz is actually a more generic and abstract job management system capable of processing any number of tasks via a similar queuing mechanism. For the time being, Movable Type only utilizes the Schwartz for publishing, but in the future may use this framework for sending emails or other non-critical system tasks.

Publish Queue Tools

Publish Queue Manager screenshot
There is one tool in particular that is recommended for most systems that utilize the Publish Queue, aptly named the Publish Queue Manager.

This tool provides a user interface within Movable Type that allows administrators to monitor and inspect jobs on the queue. Each job can be deleted, or have its priority changed.

For more information, visit the plugin's web site at the following URL:

http://www.majordojo.com/projects/movable-type/publish-queue-manager/

Additional Reading

To learn more about the Publish Queue, consider reading the following resources:

By the way, a new version of the Movable Type Operations Manual is now available.

The first challenge developers of the Social Web are presented with is the lack of concrete, readily available, off-the-shelf solutions to integrate with. That is because the technology that defines this era of innovation can be reduced to nothing more than a set of building blocks that embody a philosophy of how applications should be built rather than a specific hardware or software solution in and of itself.

Being successful in the application of these building blocks therefore relies equally upon a firm understanding of the technologies at hand, and experience in pulling together the right components and implementing them in a way that makes sense to the average user.

Using Contact Forms

The following describes how to accomplish the most common tasks with the Contact Form Plugin.

How to create a contact form

To create a contact form navigate to "Contact Forms" from the main "Manage" menu of Movable Type. From there click the link "Create Contact Form." A dialog/wizard will pop-up leading you through the process of creating a form. Here is a brief explanation of each of the fields you will be asked to fill out:

  • Form Title - the name of the contact form.

  • From - the email address from which all correspondence regarding an inquiry will be sent, mainly the autoresponse sent to visitors, and responses sent in reply to an inquiry from with the application.

  • Reply To - the email address to which users will be directed to reply to. This will be transmitted as a "Reply-To" header in the email. This can be different from the from who the email is actually from. For example, the email may be from "Support", replies should be directed to "Jim."

  • Notification List - a list of email addresses that should be notified whenever a new inquiry is received via a contact form.

  • Status - allowable values are "open" and "closed." This is used to easily turn on and off a contact form. When a status is set to closed, a message can be displayed on any page that embeds the form to indicate its status using the <mt:IsContactFormOpen> tag.

  • Require Authentication - If authentication is required, then visitors will not be able to submit inquires without first authenticating in some way.

  • Auto-Reply Text - This is the text that will be sent in an email to any user who submits an inquiry via the form. It is a way to further personalize your correspondence with visitors.

  • Confirmation Text - This is the text that will be displayed to your visitor on your web site immediately following their submitting an inquiry.

  • Fields - This is the list of fields your contact form will have. You can add and remove fields to your heart's content. The "Subject" and "Body" fields are required and cannot be removed, as are the name and email fields for unauthenticated users.

Adding, Removing and Arranging Contact Form Fields

One can easily customize their contact form by adding, removing and even ordering the fields on the screen using a simple drag-and-drop interface. To edit a form's fields, edit the form and scroll to the bottom of the page. There you will see a list of the form's fields. On the left hand side of each field is a small drag handle which can be used to drag and drop the field up and down the list.

Click on the red minus icon to delete a field.

To add a field, click "Add Field" and a small form will become visible prompting your for the field's name or label, the type of field it is (text, textarea, radio button, pull-down menu, etc) and any additional options the field may support. When you are done defining the field's properties, click the "Add" button and your new field will be added to the list of fields associated with the form. You can then drag and drop the field to place it in the position you desire.

When you are finished, save the form and your fields will be updated, added or removed accordingly.

You may need to republish pages and templates that utilize the form in order for your changes to be reflected properly.

How to embed a contact form on your web site

There are two primary ways in which a form can be placed on a web site:

  • Adding the Form's HTML directly to a page or entry

  • Inserting the form via a template tag used within a template on your web site.

Adding a Form via HTML Directly

Some people may want to add a contact form directly to a page manually without having to worry about editing a template. To do do so, visit the "Manage Contact Forms" screen found via the "Manage" menu. A link can be found associated with each form listed there entitled "Show HTML." Click the link corresponding to the form you want to embed.

A dialog will then appear showing the contact form's HTML. Copy this HTML to your clipboard. Then edit the entry, page or template you want to add the contact form to and paste your clipboard's content into place.

Save and republish the page/entry/template and you are done.

One down-side of this approach is that any changes made to the form subsequent to pasting into the page will not be reflected. You will be required to repaste the form's content into each of the respective pages whenever the form is modified.

To avoid this inconvenience, consider inserting the form via a template tag discussed below.

Adding a Form via a Template Tag

The following template tag can be used to render a contact form on your website:

<$mt:ContactForm id="$id"$>

When a template is rendered, the tag above will be replaced with the complete HTML associated with contact form with the given ID. The HTML and structure of the form itself is derived from the Global or Local System Template conveniently entitled "Contact Form."

How to customize the HTML of a contact form

The best way and recommended way for that matter to customize your contact forms' HTML is via the System Template entitled "Contact Form." If you are using a theme that supports the contact form plugin explicitly then you will find a blog-level system template with this name to edit. Otherwise, you can find a global system template with this name.

The default contact form template illustrates the best way to structure the template. That is to say that the template consists of three primary components in this sequence:

  • a header - which includes the form tag and hidden form elements that makes the form work.
  • a loop that iterates over and displays each field according to its type
  • a footer - which includes the form's buttons

The header and footer should hardly be messed with. What it is most essential in customizing the form's look and feel is the loop that is responsible for rendering a pull down menu, or a text box, or textarea, etc.

For more information, consult the template tag reference found later in this document.

How to track incoming inquiries

To monitor incoming inquiries, or contact form submission, navigate to the "Manage Inquiries" screen via the "Manage" menu in Movable Type's main navigation.

From there you can see all recent inquiries and their status (read, unread, etc). You can click on an inquiry to read it, and from there reply to directly to the inquiry, flag it, or delete it.

How to reply to an inquiry from within Movable Type

To reply to an inquiry, click on the inquiry's subject to read the inquiry in the bottom pane. In that pane you will find a "reply" button. Clicking it will open a small dialog into which you can type your response. When you are done, click the "Send" button and the person who submitted the inquiry will be sent your response via email.

How to flag an inquiry

To flag or unflag an inquiry, click on the inquiry's subject to view the inquiry in the bottom pane. In that pane you will find a "flag" or "unflag" button depending on the inquiry's current status. Clicking that button will then toggle the inquiry's flagged state.

How to export a list of inquiries in CSV format

Users may wish to export a list of all of the inquiries submitted via a contact form. This can be useful for people harvesting a list of email addresses of people who have opted in for a newsletter for example. To export a list of replies TODO

Let me help you make the most of Movable Type.

Performance Optimization

Movable Type is without a doubt one of the most powerful tools that helps people build robust, scalable and secure web sites. When it is working, you rarely have to worry about your site going down, whether your ads are being served, software upgrades to patch a security vulnerability, or publishing times. But when things are not configured optimally, then your experience and your readers' experience can be impacted.

If you are having problems with Movable Type, if your content is publishing slowly, or if the application appears sluggish then I can help. I have been helping the largest Movable Type sites on the planet scale to meet remarkable demands for years.

Premium Upgrades

Upgrading from Movable Type 3.x? Migrating from Drupal, WordPress, Expression Engine or even TypePad? Worried your migration will result in lost content, or that your Google Rank will suffer? Need to carry over your design from your existing platform to Movable Type? Then I can help.

My premium upgrade packages can be tailored to your needs and range from a simple software upgrade all the way to a full service migration program where I make sure your site, not matter how small or large, is upgraded to Movable Type 4 as painlessly as possible with minimal impact on your editors, authors and readers.

Installation

Need help with installing Movable Type? I can get you up and running just about anywhere with no hassle or trouble. Just $150.

Training

I am the architect and author of virtually all of Movable Type's documentation online, and I continue to provide services to Six Apart in order to expand their efficacy. In addition, I have provided training services to some of Six Apart's largest customers and can instruct individuals and teams on a variety of topics. Training services can be provided on-site or off according to each client's needs and schedule.

Courses

User Training - This 1 day course will provide authors, editors and administrators with the basics of using and administering their Movable Type CMS. 
Subjects include: site administration, content creation, pages, user administration and permissioning, the basics of site modification and customization, an overview of 3rd party plugins, and a comprehensive review of the entire application and what it can and cannot do.

Designer Training - This 1 or 2 day course provides designers with the tools and knowledge they need to become adept at designing and customizing web sites powered by Movable Type. Students finishing this course will have a strong foundation of knowledge in Movable Type's templating language, template module caching, template sets and theme creation, commonly used third party plugins, and site/publishing optimization.

Developer Training - This 1 or 2 day course teaches any developer how to build plugins to extend the core Movable Type application. Subjects include the Movable Type Registry, working with Movable Type objects, building custom data types, callbacks and events, working with jQuery and Movable Type's Javascript, creating new screens in the Movable Type application, and much, much more.

Operations Training - This 1 day course teaches system administrators on how to host and operate Movable Type. Students leaving the course will have strong understanding of how to optimize Movable Type, the Movable Type Publish Queue, and how to build out Movable Type clusters and network architectures that scale.

Movable Type and Perl for PHP Developers - this 1 day course is designed for PHP developers wishing to learn the basics of Perl, but most importantly how to apply their knowledge of PHP to developing web sites in Movable Type.

Learning Perl - this 5 day course can take virtually any person with a very basic understanding of scripting/programming and teach them the basics of the Perl programming language. This course is ideal for companies wishing to teach engineering, QA and operations teams the basics of the language and to prepare them for other courses designed to teach them the basic of developing custom applications and plugins for Movable Type.

Custom Package - Clients are also free to build a custom curriculum based upon their specific needs.

Full course outlines available upon request.

Without a doubt the most common support request I receive from users of my many Movable Type plugins is around installation. If you are having difficulty or getting frustrated the first and most important thing to realize is that it is not your fault. Not in the slightest. The problem lies in having poor documentation which exists because plugin authors, like me, take plugin installation for granted. As a result our instructions, while well intentioned, are sometimes not sufficient for all users.

So permit me to try to explain how to install a Movable Type plugin once and for all and in a way that I hope will be useful and understandable by the largest possible number of people.

Before You Begin

First off, these instructions assume that you are installing a plugin that adheres to the documented best practices for plugin packaging. To determine if the plugin you are installing adheres to this standard you will need to unzip the plugin on your local computer, which should create a new folder containing all of the files needed to run the plugin. Look inside this folder, if it contains another folder called plugins then you are in luck. If not, then this guide will be of little use to you. I would encourage you to contact the plugin author and ask them to please repackage their plugin according to the documented standard, or point them to me so I can help them.

Your $MT_HOME and $MT_STATIC Directories

You are clearly on the right track. Now, another thing you need to know is that these instructions make frequent reference to your "$MT_HOME" and "$MT_STATIC" directories. The location of these directories will be different for virtually everyone; what is important is knowing where these directories are for you.

The $MT_HOME directory is a cgi-bin directory where you have the Movable Type application installed. Let's look at this common example: suppose you have installed Movable Type into the following directory:

/var/www/cgi-bin/mt

We know that this is the right directory because if you view its contents you will find within it a file called mt.cgi like so:

/var/www/cgi-bin/mt/mt.cgi

This is your $MT_HOME directory.

Now, your $MT_STATIC directory is where you will find Movable Type's static files. Like with Movable Type itself, you may1 need to place the plugin's static files outside of your $MT_HOME directory into a "web accessible" directory. You will know this is the case for you if you access Movable Type from a URL like:

http://foo.com/cgi-bin/mt/mt.cgi

And your images are served from a URL like:

http://foo.com/mt-static/images/movable-type-logo.gif

Alternatively, your system may be configured such that static files can be served directly from your cgi-bin directory like so:

http://foo.com/cgi-bin/mt/mt-static/images/movable-type-logo.gif

Knowing how your system is configured to serve static files is essential to a successful plugin installation. To find your $MT_STATIC directory, find on your system a file called mt.js. Let's suppose that your system tells you that mt.js can be found in:

/var/www/htdocs/mt-static/mt.js

Then your $MT_STATIC directory is:

/var/www/htdocs/mt-static/

If your system finds more than one copy of mt.js you will need to do some sleuthing to figure out which one of these directories is in use by Movable Type. Hint: consult your mt-config.cgi file; in it might be a configuration parameter that will indicate the proper path to the directory in question.

Now, let's proceed with your installation.

Installing via the Command Line (Unix)

If you are at all familiar with using the command line, then this is without a doubt, the quickest and most straightforward solution to plugin installation:

prompt> unzip SomePlugin-1.3.zip
prompt> cp -a SomePlugin-1.3/* $MT_HOME/

This will copy all of your files into the appropriate directories, including the plugin's cgi scripts, and Perl library files and sometimes even its PHP files needed to support dynamic publishing2.

And optionally, if the plugin has an mt-static folder and your system requires you to install static files into a different directory than your $MT_HOME:

prompt> cp -a SomePlugin-1.3/mt-static/* $MT_STATIC/

Installing via the Command Line (Mac OS X)

Installing a plugin on a Mac is almost identical to installing on in Unix. The only difference really is the cp command used since cp -a is not supported. So the command sequence becomes:

prompt> unzip SomePlugin-1.3.zip
prompt> cp -pR SomePlugin-1.3/* $MT_HOME/

This will copy all of your files into the appropriate directories, including the plugin's cgi scripts, and Perl library files and sometimes even its PHP files needed to support dynamic publishing2.

And optionally, if the plugin has an mt-static folder and your system requires you to install static files into a different directory than your $MT_HOME:

prompt> cp -pR SomePlugin-1.3/mt-static/* $MT_STATIC/

Installing via FTP

If you are installing the plugin via FTP, then the instructions are similar as to the above, but you will be installing the plugin by dragging and dropping files around. Whee! Of course, your exact instructions may vary depending upon the FTP software you use, but the general gist is the same no matter what. Let's take a look:

  1. Unzip the plugin's zip file to your desktop.

  2. Start your FTP client and connect to your web server.

  3. In your FTP client navigate to your $MT_HOME directory.

  4. Select all of the files found in the folder created when you unzipped the plugin's archive and drag and drop them directly into your $MT_HOME directory in your FTP client. Wait for all of the files to be copies.

  5. In your FTP client navigate to your $MT_STATIC directory.

  6. Select all of the files found in the mt-static folder found in the folder created when you unzipped the plugin's archive and drag and drop them directly into your $MT_STATIC directory in your FTP client. Wait for all of the files to be copies.

And you are finished. Granted, textual instructions like that can sometimes not be very intuitive, so check out the screencast below which demonstrates the instructions above more precisely:


Movable Type Plugin Installation Demo from Byrne Reese on Vimeo.

And that's it. Hopefully this will answer the questions most people have about installing Movable Type plugins. If you have trouble installing one, drop me a note and I will try to help.

1 - You may or may not need to perform this extra step, which depends exclusively upon how your web server has been setup. As for me, I prefer to configure my web server such that I can serve images and javascript file (static files) from my cgi-bin directory.

2 - Some plugins come with a set of PHP files that are used by Movable Type's dynamic publishing system. These files should get installed into your `MT_HOME/php` directory, and *not* into your mt-static directory. But if you follow the instructions in this document, you shouldn't have to worry about this.

What has always drawn me to Movable Type is its flexibility. Most of the time we, that is Six Apart: my employer and creator of Movable Type, talk and think about MT's flexibility in terms of the web sites it is capable of producing and the vast array of plugins one can build on top of the platform.

Today Mark released [a plugin that] provides a user interface to Movable Type that is virtually identical to that of WordPress.

But there is another axis of customization that is rarely exploited that is perhaps one of the most remarkable ways in which one can bend and twist Movable Type to one's will: the ability to completely re-skin the core user/administrative interface of the application. The first time this feature was fully utilized was when we released the iPhone interface for Movable Type. The fact that it took Brad Choate less then 8 hours1 to actually port the entire interface to a completely different look and feel is amazing to me.

Of course, one might chalk his efficiency up to fact that he also happens to be Movable Type's lead engineer, and arguably the single most experienced and knowledgeable Movable Type hacker on the planet --- thereby making this feat less compelling.

Enter Mark Carey.

Today Mark released the second plugin capable of re-skinning Movable Type. This plugin however provides a user interface to Movable Type that is virtually identical to that of WordPress.

wpui-dashboard.png

To quote Mark, "Yes, the above image is Movable Type, not Wordpress. ;)"

From what he tells me, it only took him about 10-12 hours to achieve.

Remarkable.

For the engineers out there: think for a moment back when you last embarked on a redesign of a product you worked on. How long did it take you? I am willing to bet that no matter how long it took, it took longer then you thought it would.

It is just amazing to me to think that someone can turn around a total redesign of the Movable Type application in such a short period of time.

But what does this mean for Movable Type users? I guess it depends on who you ask, as there are some MT users that cannot imagine using anything but MT4's new look and feel. On the other hand, I have spoken with some users, WordPress converts in particular, for which MT4's user interface was a very drastic change for them.

For those users, and other users thinking about making the switch from WordPress to Movable Type, this plugin allows them to experience MT via a more familiar user interface. Users can then transition to MT's default design when they feel more comfortable doing so.

I just like the fact that Movable Type really is whatever you want it to be. It doesn't seek to constrain you to a single way of doing things. It is not encumbered by NIH mentality and seek to embrace the best the web has to offer, from OpenID to Pingback. Movable Type, in its form, function and design seeks to free you from constraints and make anything possible.

God, I really do love this product.

1 This does not account for the time to actually design the user interface, and come up with the HTML and CSS coding standard to use.

My friend Jim Ramsey just recently wrote an essay for A List Apart entitled Designing for Flow.

In web design, when we think about flow we usually think about “task flows” or “flow charts” but there’s another type of flow that we should keep in mind. It’s that feeling of complete absorption when you’re engaged in something you love to do without being disrupted by anxiety or boredom caused by tasks that are confusing, repetitive or overly taxing.

Reading his article through made me reminisce about one of the best TV shows ever made, and one scene in particular.

Jim is the lead designer of Movable Type, both the application and our movabletype.com website.

Recently I received a comment on a post about modperlite alleging that modphp, an Apache module mod_perlite is modeled after, is falling out of favor with hosting providers. That is quite an allegation - one that I initially shrugged off because it seemed preposterous to me. I mean just consider for a moment all of the incredibly popular applications including WordPress, Drupal, PostNuke, phpBB, Mediawiki and many more too numerous to list here let alone count that all rely on PHP exclusively.

Not wanting to completely discount this comment I decided to consult a close acquaintance of mine that works with one of the most popular hosting providers on the Internet. In working with him on a number of projects I have come to respect him on a number of levels, but especially for his knowledge of operations and system architecture. He spends a great deal of his time every day trying to maintain systems running software he didn't write or install on machines run by users he has little or no control over. He is an expert in cleaning up after others. So I asked him if he had an opinion about this statement.

What I learned through our email dialog was enlightening, and I wanted to share it with a larger audience. He permitted me to republish parts of our correspondence, but asked to remain anonymous. (Editorial note: I have taken some of his text and elaborated as best that I could in order to provide a more complete overview of this issue.)

This is a rather multifaceted issue, but to summarize I'd venture that mass virtual hosting on the whole is trending away from mod_php/mod_perl.

He proceeded to back this claim up:

  • Real file I/O is impossible or insecure - it is difficult to harden a mod_perl/mod_php application because these Apache modules only run in the permissions context of the web server's user. Software that helps resolve this issue, like suPHP, which allows a script to run in the permissions context of the script's owner, negate the performance benefits of the underlying mod_perl/mod_php module.

  • One of the more viable solutions to this permissions dilemma, an Apache module called mpm_perchild, died on the vine years ago. "This was the Apache 2+ intended answer for the security problem and was supposed to (correctly, IMO, given Apache's architecture) have each request thread out based on file ownership, sort of a rolled in suexec."

  • "There is growing adoption of code frameworks (rails, django, catalyst, etc etc) that just don't play with mod_php/perl. Building an effective cgi/fastcgi architecture covers bases better."

  • "There is a growing adoption of very powerful web servers like lighttpd and nginx whose only interface is cgi/fastcgi. To many developers today Apache really is an anachronism."

  • "Another side effect of cgi/fastcgi that I neglected to mention is that it is much more apparent which users' code/processes are monopolizing resources" thereby making it easier for hosting providers to monitor, enforce resource utilization policies and recover from systems under load.

Then y friend also responded to this comment:

@saj - really? You think mod_php is falling out of favor? That is quite a statement... one that I can't imagine is true. PHP is one of the most ubiquitous web scripting languages, second only to Perl. A cannot imagine hosts degrading their support for this language.

With this response:

I think this is the most important misconception to dispel. In an Apache vhosted setup, modphp *is* degraded support. Settings like safemode are generally implemented and users don't have access to edit their own php.ini, relying on .htaccess hackery to eke out the limited php settings customization available.

He concluded, "there is a ton more to the issue and these points really don't do it full justice."

Now lets be real, I don't think my friend is saying that hosting providers will drop support for PHP, not in the foreseeable future, but if hosting providers tend not to prefer mod_perl and mod_php based applications what will this mean for all us developing on top of these languages and deployment platforms?

And ask yourself, when you write a web based application, are you thinking about the company that is going to be hosting your application for your customers/users? And what are you doing for them to make their lives easier?

How to Fix CGI

Over the many years of their coexistence, the terms CGI and Perl have become virtually synonymous. This perception that CGI and Perl are one and the same has contributed to some small degree to the perception that Perl is outdated and an inappropriate language for web programming - unlike its more modern counterparts like Ruby or PHP.

I of course know this to be a complete fallacy. First of all, the company I work for is a devout Perl shop and our products, all written in Perl, are collectively some of the largest and most scalable on the Internet. Few other companies in fact present more widely attended seminars and tutorials about scaling for the Web then ours do at conferences like eTech and OSCON.

But perhaps the more significant fallacy is that CGI and Perl are synonymous. In actuality, they technically have very little to do with one another, and there is technically no reason one should be hampered by the other, despite all evidence to the contrary.

A little history and background

CGI stands for "Common Gateway Interface" and was invented to allow any script, written in any scripting language, to also act as a web based application. In the early days of the Internet this was incredibly helpful to the first Web programmers (a.k.a. system administrators) proficient in sh, bash, csh, tcsh and perl because it allowed them to quickly deploy simple web based automation tools based on scripts and libraries they had already written. Cool.

But the inherent flexibility of language agnosticism is also CGI's greatest liability, and also by association, Perl's as well. You see, CGI is based upon the principle that when the web server receives a request, it does not know what scripting language will interpret that request. Therefore, it defers processing directly to the operative system, and so must do something geeks call "forking and exec'ing" - or in other words, the web server must start up an entirely new process on your server to handle the request. This may not sound like a big deal, but it sometimes can be as each forked process holds the entire Perl interpreter in memory. And that is a big deal. First it can consume a lot of your server's memory, and depending upon the size of your application, it can be slow to initialize. It works - and works well by virtue of working, but it by no means ideal.

More modern languages have been designed to avoid this. Let's take PHP for instance. PHP is a language that was designed for web programming exclusively. Therefore its architects made a critical (perhaps even obvious) decision early on: if the web server is going to handle a lot of PHP scripts, why bother forking a process to determine what scripting language will handle the request (this is expensive) - why not just load the PHP interpreter into memory once and interpret the request within the web server (which is much cheaper)?

So when it comes to CGI vs PHP, it is not really about Perl vs. PHP at all. It is really about understanding two solutions to two different problems - one operating under the assumption that every request will be processed by the same interpreter and the other designed to execute any script via the web.

The solution as it stands today

In the Perl world, there are actually two Apache modules that attempt to do what PHP does inherently: load the Perl interpreter into memory so that you no longer have to spawn a new process each and every time your web server receives a CGI request. Those two modules are mod_perl and mod_fastcgi.

However, these two modules have a critical flaw: they are incredibly complex because they attempt to solve a huge problem set having to do creating a persistent and stateful execution context. The result are two modules that are not only too heavy weight for the average user but also incredibly difficult to install - even for myself.

How to actually fix the problem

The more I have thought of this problem, the more I have come to believe that there is little standing in Perl's way to have all of the benefits that PHP has gained from being a language designed exclusively for the Web.

In theory, one should be able to take the source code of mod_php (the Apache module that dispatches web requests to a PHP interpreter) and swap out the component responsible for dispatching a request to PHP for one that dispatches the request to Perl. In theory it should just work (more or less). The result would be an Apache module that would be easy to install, and be much more efficient in handling and processing requests online.

Granted, this solution would not be stateful and persistent the way mod_perl and mod_fastcgi are, but that is not a problem this solution is engineered to solve.

Introducing mod_perlite

All of this is a really long-winded setup for what is a very quick conclusion.

I shared this hypothesis with an engineer at work, Aaron Stone, who shares a passion for Perl with me, but who also has a passion for operations. He took on this challenge and devoted part of his 20% time to testing this hypothesis.

The output of his work is called mod_perlite. It is largely derivative of PHP and is capable of processing Perl scripts quickly and efficiently. The next step of the project is to make it compatible with the CGI protocol, which can be done by gutting parts mod_cgi and dropping them into mod_perlite.

So far our results are promising, and it is possible that with a little hacking we may have just made Perl faster on the web and easier to deploy for everyone.

If you are interested in helping or participating in this project please let me know -- we could certainly use the help.

In Jason Santa Maria's talk today at An Event Apart he outlined the latest thinking in design fundamentals for expressing your brand and identity through web design. However when his slide came up entitled "Sweat the Small Stuff" and he explained simply that the details really do matter, I couldn't help but think about how increasingly more and more people are experiencing websites through someone's lens like a feed reader, aggregator or even Facebook, in which a designer's carefully crafted details, which collectively go not only to supporting your brand, but also the usability of your content, gets completely lost, or in some cases even perverted.

Curious to see how majordojo is experienced by most people, I did a quick survey of how my very simple design is seen via today's most popular feed readers:

Majordojo through Bloglines
majordojo as seen in Bloglines

Majordojo through Google
majordojo as seen in Google Reader

Majordojo through Sage
majordojo as seen through Sage

Majordojo through Newsgator
majordojo as seen in Newsgator

So if design matters, which it does of course, then why can't these readers respect the design I choose from my content. Granted, from a pure usability point of view I think I could make a pretty compelling argument that it is in the user's best interest to make all content, regardless of its source, completely uniform. But what if you look at this from a less myopic point of view? How can we appease the need for usability, but also respect the designer's intent from the source web site?

And can this possibly be solved by technology?

Well, maybe. We already have a mechanism to define how a site should appear when printed via a web browser, or when accessed via a mobile device... why not use the same mechanism to help instruct readers in rendering my content within the context of their application?

Granted, the reader should be allowed to apply constraints to my content for aesthetic, usability and security reasons... but why can't some of a designer's carefully chosen fonts, colors, imagery, and detail bleed through? Why can't there be a middle ground that respects usability and design intent equally? Or is that even possible?

Mint: a review

Mint Logo

About five years ago I abandoned the last of my brick-and-mortar financial institutions so that I could manage my money exclusively online. I left Bank of America in favor of eTrade because I believed that as a modern Internet company eTrade stood a much better chance of developing the kind of banking application I would not only value, but also have a modern and savvy user interface. So I switched everything over and bought Quicken, with a rare enthusiasm and excitement for I believed that this would be the new dawn of a new me, a me that actually had his finances ordered and up to date at all times.

Imagine my surprise when I booted up Quicken only to find that it was incompatible with eTrade Bank. Believe it or not, that was in 2003. Three years later when my wife and I began to contemplate buying a new home and I had a renewed interest in trying to gain greater insight into how my wife and I spend money. So I decided to check back with Quicken and see if they had yet added support for eTrade Bank. They had not.

"Shock" does not even begin to describe the feeling I had. I had chosen eTrade because I believed that a company that existed almost exclusively online would work best with products like Quicken that wished to synchronize users' data with financial institutions over the Internet. Seems like a reasonable conclusion to reach, right? Um, yeah.

So in an effort to get a handle on my family's finances I turned to the oldest personal financial application around: Excel. I imported what I could from eTrade and then began the process of manually categorizing all of my income and expenditures over the past three months. It was excruciating and. mind-numbing. But it was also very error prone because my categorization scheme kept adapting and changing as I began to understand my own expenses more and more. During the whole process I kept asking myself, "can't Quicken do this for me? Don't they have enough people's data to know how people generally categorize a payment to Amazon or Grand Lake Theater?"

In the end I toiled over that spreadsheet for about 3-4 hours knowing full well that if I ever needed to update my finances I would need to do it all over again. Talk about poking yourself in the eye with a stick.

I had resigned myself to never finding a tool that would work for me. But just the other day, I stumbled upon a newly released product that in an almost clairvoyant fashion did exactly what I was trying to achieve in Excel in a little under 5 minutes. Plus it gave me the simple, easy to understand personal finance analytics I wanted out of Quicken, and it did it all for free.

So, yes, I am a fan of Mint. I will admit. But it is not perfect. It does a lot of things right, which I talk about below, but there are many things I would like to see it do differently.

Turning Personal Finance into a Game

debt-equity.png

A number of notable product design folk talk about the use of game mechanics within the tools we use to help fuel our use of and addiction to them. These same game mechanics can also be used to turn otherwise mundane or even anxiety-ridden tasks into ones that are actually and quite possibly fun. The "game" Mint offers lies in encouraging the user to take actions in their personal life in order to manipulate Mint in respondiing in a favorable and desired way. One very simple example of how Mint does this already is with the widget that shows a user's ratio of equity to debt. This is an incredibly reductionist view of your finances, granted, but that is the beauty because it is easy for me to understand how to move the bar left and right. Another good example is the "how do you compare" feature which actually pits me against others users in the system. This I love because it taps into my competitive nature. I hate know for example that I pay more then most others for gas, especially consider how little my wife and I drive.

compare.png

Mint is only scratching the surface here. The truth is that Mint has lots of fertile ground to help provide additional feedback to the user to help encourage them to develop discipline around their finances, and I hope that Mint begins to define its more of its features with game mechanics specifically in mind. I just love the idea of an application I use enticing me to be better about finances - either overtly or subconsciously. I don't care, because the end result is a real value to me no matter what.

The Brilliance Behind the Product

Omniture and then Google showed the world that advertising can be actually be perceived as valuable by users when that advertising is actually relevant to the content of the page and provides some kind of value to the user. It is my belief that search remains the only context for advertising where the ad serves a purpose and value relatively equal to the content itself. Sure, content targeted advertising on blogs can be relevant, but they are still widely recognized as "ads" in the most pejorative sense of the word, and not immediately perceived as a value.

save-money.png

Mint may very well have discovered the next form of ad unit that provides what consumers will widely perceive as truly valuable. Just click on the "Ways to Save" and you are immediately taken to a page that shows me products and services that will potentially save me money. For example, Mint knows what credit cards I have and their interest rate, so it can present me with credit cards to transfer my balance that will save me on interest payments. Mint also knows who my cell phone provider and can present me with alternative cell phone providers that can save me money on my monthly payment. I honestly hope that one day Mint will also:

  • Help me find a better longer term mortgage. What I hope Mint does not do is help me lower my monthly payment. That is a crock. I want Mint to help me build equity in my home, not help others leach equity from it.
  • Offer vacation packages for me based upon the cities it sees me spend money. For example, Mint should know that I visit Los Angeles from time to time, and should be able to offer ways to save on my next trip there.
  • Help me find a better place to save my money by recommending CDs or Mutual Funds based upon how much of my equity is liquid on average.

A Few Recommendations for Mint

  • Make Community More Apparent - The "How do you Compare" feature is awesome, but I think there is greater potential to inform how users can more actively contribute to the system and one another. It would be great to actually show information about each transaction on how others have categorized an item. I am certain their must be something at work on the backend taking into account how others are training the system, but surfacing that information I think will help encourage that behavior in users even more.

  • Allow for Category Suggestions - I actually like the constraints you place around categories. While I think a compelling argument can be made to allow people to create their own ontology, I think it is wiser to constrain users, lest they over complicate something that Mint is trying to keep simple. But man, I sure would like a few changes made... perhaps you could let users suggest categories? For example, I would love a category for Home Business (both income and expense). Oh, and I want a "Delivery" option under Food because one thing I am dying to know about myself is how often I "order out."

  • Encourage me to Categorize - I think categorization is one of the most important activities a user can engage in. There should be some kind of statistic on the dashboard widget that shows how many uncategorized items I may have. When I click it I should be taken to a "to do list" of sorts that shows all of the uncategorized transactions in my account. As I assign each to a category, my to do list gets smaller and smaller. Ultimately I should categorize very infrequently because over time I should be training the system to do it for me.

  • "Labels?" Come on, they're tags. - I wish a more conventional method for applying labels, or let's be honest with one another, tags to my transactions. I would be more diligent about tagging my transactions if the process was more fluid and less cumbersome. Go for a tagging interaction model like Flickr or Vox.

  • Spending Trends Improvements - The pie chart is nice, but it is not 66%-of-the-screen-nice. Some of the stats I am really interested in are the less prominent stats, like who are my "favorite" merchants, especially over time. I also want to gain a better understanding of income as well and the ebb and flow of income to expense. Let me blow up spending charts... I want to see more than the top 3 places I spend money within any given category.

Clean Sweep is a plugin that assists administrators in finding and fixing broken inbound links to their website. It was build to support two use cases:

  • to help users get a clean start with their blog by allowing them to completely restructure their permalink URL structure and have a system that can automatically adapt by redirecting stale and inbound links to the proper destination

  • to help users in the process of migrating to Movable Type who are forced to modify their web site's URL and permalink structure

Both of these use cases have to do with preserving a site's page rank in light of a major redesign.

Features and Benefits

  • Manage redirects in your blog using an easy to use user interface.
  • Help maintain good SEO and page rank by keeping links fresh.
  • No need to hack Apache configuration files until you are sure your redirects are correct.

Download

Screenshots

Dashboard Widget

Clean Sweep Dashboard Widget

Create a Redirect

Clean Sweep Map 404 to Destination

View a List of All 404s

Clean Sweep 404 Listing

View a List of Recommended Rewrite Rules

apache-rewrite.png

Installation Instructions

  1. Unpack the Clean Sweep archive.
  2. Copy the contents of CleanSweep-1.1x/plugins to: /path/to/mt/plugins/ and copy the contents of CleanSweep-1.1x/mt-static to: /path/to/your/mt-static/.
  3. Create a page in Movable Type called "URL Not Found". Give it a basename of "404". Place whatever personalized message you want that will be displayed to your visitors when Clean Sweep is unsuccessful in mapping the request to the correct page or destination.
  4. Publish the page and remember the complete URL to this page on your published blog.
  5. Navigate to the Plugin Settings area for Clean Sweep.
  6. Enter in the full URL to your "URL Not Found" page you created in step #3. Copy that URL into the "404 URL" configuration parameter for Clean Sweep.
  7. In your plugin settings area for Clean Sweep, make note of the Apache configuration directive that Clean Sweep asks that you place in your httpd.conf or in an .htaccess file.
  8. Add the Apache configuration directive to your web server. This may be placed in your httpd.conf file or in an .htaccess file located in the DocumentRoot for your blog.
  9. Restart Apache

How it Works

Once properly configured, Clean Sweep will track all inbound links that result in a 404. Administrators can monitor the list of 404s on their web site through a dedicated listing screen in the application found under the Manage > 404s menu, or through a convenient dashboard widget.

If Clean Sweep can determine what file to serve in place of a request that resulted in a 404 it will. If all else fails the plugin will serve a custom 404 page you design.

Clean Sweep will also provide you with a list of Apache mod_rewrite rules that you can add to your web server's configuration settings to permanently redirect users to the proper resource, thereby bypassing the Clean Sweep plugin from that point forward for those specific set of links.

The Redirection Decision Making Process

The following is how Clean Sweep determines what files to serve in place of a requested file that could not be found on the file system:

  1. Check to see if a redirect has been setup by a user for the specific file being requested. If one exists, redirect the client to that file.

  2. Is the target resource using the entry id as a URL This is a prevalent URL pattern for older MT installations. This will:

    Map: http://www.majordojo.com/archives/000675.php To: http://www.majordojo.com/2005/07/goodbye-bookque.php

  3. Is the target resource using underscore when it should be using hyphens? Many users have switched to using hyphens for purported SEO benefits. This will attempt to look for a file in the system of the same name, but using '-' instead of '_'. This will:

    Map: http://www.majordojo.com/2005/07/goodbye_bookque.php To: http://www.majordojo.com/2005/07/goodbye-bookque.php

  4. Is their a target resource with the same basename somewhere? If a user switches their primary mapping to use a date based URL as opposed to a category based URL, then this rule will apply. This will:

    Map: http://www.majordojo.com/personal-projects/goodbye-bookque.php To: http://www.majordojo.com/2005/07/goodbye-bookque.php

  5. Let me know and I will add it!

  6. If all else fails, serve up the users configured custom 404 URL.

Reporting Bugs

During the length of the beta please use the comment form at the bottom of the page to report any bugs with Clean Sweep.

License

Clean Sweep is licensed under the GPL (v2).

Copyright

Donated to the Movable Type Open Source Project. Copyright 2007-2008 Six Apart Ltd.

"When I login, it doesn't do anything. It just dumps me back to the front door and the login box is still there. I can see the account that was created, and I entered the right login credentials..."

This is the most common problem reported, and the easiest to fix. The PHP_Users relies on cookies for determining whether someone is logged in or not. When you login, a cookie is set that tells the PMI on all subsequent pages that you are logged in. However, if that cookie fails to be set, then no page in the application will detect your proper login state.

The problem lies in the fact that cookies require that two decimals are present in any cookie domain. And when you think about it, it makes total sense. Look at it this way: if I set a cookie on someone's computer with a cookie domain of ".yahoo.com" that means whenever I visit a page in that domain, my browser will transmit that cookie data to the server. But what if a website set a cookie of ".com"? All of a sudden my personal data would be transmitted to virtually every site on the web. That is why two decimals are required. It is all about security.

Ok, what does this have to do with you? Well chances are you are running PMI off of your "localhost." You need to add an alias to your machine that is akin to "pmi.localhost" that way your cookie domains can support 2 decimals (because localhost by itself cannot). So add the alias, and make sure in pmi.conf that the $COOKIE_DOMAIN variable is set properly.

Note: The PMI is no longer being developed and is not supported. If you would interested in picking up the mantle of this project and developing upon it once again, please contact Byrne Reese.

The Project Management Interface (PMI) is a web based application written in PHP to help companies manage project and release information for their intranet.

Background

I have worked at many companies over the past few years and one thing that most of them have lacked is good project management tools. When I became a project manager after being an engineer, I could no longer stand it. So I built a tool that I could use to help manage project home pages, documentation, and team information. This is what I built.

Features

Project Dashboards

PMI automatically generates dashboards for all of your projects and releases. These dashboards can be used to easily communicate vital project information to team members.

Bugzilla Integration

Tie PMI into an instance of Bugzilla and you instantly have access to bug counts, bug reports, and personalized lists of bugs for each team member.

Watch Lists

Utilize watch lists to get notified via email when projects, and/or documentation changes.

"My PMI"

Use a the "My PMI" dashboard to get a snapshot of the projects you belong to, and of the projects, releases, and categories you have subscribed to.

Turn-key Heirarchical Directory

The PMI comes with a heirarchical directory used to store documentation associated with the various projects and releases. Documents can be associated with multiple categories anywhere within the tree so facilitate another's ability to find the relevant documentation.

Listed below is one person's experience installing Testitool, along with the other majordojo applications. A good read if you are experiencing problems yourself, and helpful because it covers the installation of Apache, MySQL, and PHP.

Setting up Testitool -- one user's experiences

Read the documentation at www.majordojo.com before this document, and always trust that source way more than anything you read herein.

ENVIRONMENT/CONTEXT NOTES

  • This install was performed on RedHat Linux 7.0 and 7.3 boxes.
  • Although PMI isn't a dependency, its integration with Bugzilla and its document - storage features were compelling enough to make me want to install it, too, so these notes refer to three majordojo applications:
    • php_users (0.9a6)
    • testitool (1.0-b4)
    • PMI (1.0-b1)
  • I haven't yet done any Bugzilla integration.

OVERVIEW OF THE INSTALLATION STEPS

Install the following:

  • Apache 1.3.x (I used .26)
  • PHP 4.2.2
  • MySql 3.23.51 (I installed server, client, shared rpms)
  • mcrypt (libmcrypt-2.5.2)

Then install the three majordojo tools. Some detail follows.

INSTALL APACHE

This section contains mental breadcrumbs which may or may not be wise to duplicate in your environment, but which worked for me.

Installed Apache from source. Quick APACI config. Added option for shared object support:

./configure --prefix=/usr/local/apache --enable-module=so make make install

INSTALL MYSQL

Installed MySQL 3.23.51.*

*Why did I use an rpm for MySQL? (See below.)

Compiler Advisory: Several of our users have reported random crashes and table corruption with MySQL binaries compiled with gcc 2.96 on the x86 Linux platform. Although we were unable to duplicate the problems ourselves or understand their exact cause, we suspect with a great degree of confidence that the problem was compiler related. Replacing the faulty binary with our binary always eliminated the problem. We recommend that MySQL be compiled with gcc 2.95 if you have to compile your own binary at all. It is also acceptable to compile it with gcc 2.91 - builds with these compilers have been tested extensively. We would suggest, however, that you stay away from gcc 3.0 series until we have had some time to do some more extensive testing. The best solution in terms of stability and performance for most users is to use our binary instead of compiling their own. Please visit http://www.mysql.com/ to obtain an Official MySQL binary.

rpm -ivh MySQL-3.23.51-1.i386.rpm
rpm -ivh MySQL-client-3.23.51-1.i386.rpm
rpm -ivh MySQL-shared-3.23.51-1.i386.rpm

INSTALL MCRYPT

Set up mcrypt if you want encrypted cookies: Get source from ftp://mcrypt.hellug.gr/pub/crypto/mcrypt/libmcrypt. I built with

./configure --disable-posix-threads
make
make check
make install

INSTALL PHP

./configure --with-mysql --with-apxs=/usr/local/apache/bin/apxs \
            --with-mcrypt
make
make install
cp php.ini-dist /usr/local/lib/php/php.ini

Modify /usr/local/apache/conf/httpd.conf to add the following line:

AddType application/X-httpd-php .php

SETUP MYSQL DATABASE

Set the MySQL root user password:

mysqladmin -u root password '*******'
mysqladmin -u root -h [hostname] password '******'

Log into mysql with:

shell> mysql -u root -p

(enter the root password that you just set when prompted).

Our needs aren't huge, so I decided to lump everything into one database.

mysql> CREATE DATABASE testplans;
mysql> USE mysql;

Delete the anonymous default mysql user for security purposes:

DELETE FROM user where user="";

Add a SQL user (or several) for the majordojo applications (I defined one user for all three applications):

mysqladmin -u testitool@[myhostname] password '**********'
mysqladmin -u testitool@localhost password '**********'

Grant privileges and set passwords:

mysql> GRANT ALL PRIVILEGES ON testplans TO testitool@"mazu-stacy.mazunetworks.com" 
mysql> IDENTIFIED BY 'xxxxxxx' WITH GRANT OPTION;

mysql> GRANT ALL PRIVILEGES ON testplans TO testitool@"localhost" 
mysql> IDENTIFIED BY 'xxxxxxx' WITH GRANT OPTION;

(Afterwards, you can access this database from the shell with:

shell> mysql -u testitool -p testplans

INSTALL MAJORDOJO APPLICATIONS

Create a directory in which to untar the majordojo tools (e.g., /usr/local/majordojo).

Untar each of the application tarballs into it.

You'll be happier if you remember to create more simply-named symlinks for each tool within that directory.

ln -s php_users-0.9a6/ php_users
ln -s pmi-1.0-rc2/ pmi
ln -s testitool-1.0-b4/ testitool

Read all of the majordojo install/readme docs. Twice.

I populated databases with:

mysql -u testitool -p testplans < /usr/local/majordojo/pmi/schemas/mysql
mysql -u testitool -p testplans < /usr/local/majordojo/testitool/schema/mysql
mysql -u testitool -p testplans < /usr/local/majordojo/php_user/schema/mysql

If you want the sample data, also load the mysql sample data:

mysql -u testitool -p testplans < \
    /usr/local/majordojo/testitool/schema/mysql.test_data

At this point, you should be able to log into testplans as testitool and see this:

mysql> show tables;

+-------------------------+
| Tables_in_testplans     |
+-------------------------+
| Profiles                |
| ProjectTeamMembers      |
| Projects                |
| Releases                |
| Users                   |
| categories              |
| category_watch          |
| document_categories_map |
| documents               |
| events                  |
| execution_instance      |
| logged_bugs             |
| login_tokens            |
| project_watch           |
| projects                |
| release_milestones      |
| test_cases              |
| test_notes              |
| test_plans              |
| tests                   |
+-------------------------+

13 rows in set (0.00 sec)

MODIFY APACHE'S HTTPD.CONF

I'm going to blather about Apache's httpd.conf first because some of the majordojo configuration settings fall out of how you decide to slice your web server.

I added a Virtual Host using localhost -- however, the server name must have two components in order for cookies to work (machine.domain), thus, my server name became testitool.localhost. You probably won't even have to think about this, assuming that you're using a real server name. (Thanks to Byrne for helping me past this part.)

So the added pieces of my httpd.conf look like this:

NameVirtualHost 127.0.0.1
<VirtualHost 127.0.0.1>
   ServerAdmin root@localhost
   ServerName  testitool.localhost
   DocumentRoot /usr/local/majordojo/testitool/htdocs
   ErrorLog /usr/local/majordojo/logs/error_log
   CustomLog /usr/local/majordojo/logs/access_log common
</VirtualHost>

Alias /projects/ "/usr/local/majordojo/pmi/htdocs/"
Alias /users/ "/usr/local/majordojo/php_users/htdocs/"
Alias /testitool/ "/usr/local/majordojo/testitool/htdocs/"

<IfModule mod_dir.c>
   DirectoryIndex index.phtml index.html index.php
</IfModule>

<IfModule mod_php4.c>
   AddType application/x-httpd-php .php
   AddType application/x-httpd-php .phtml
   php_value include_path ".:/usr/local/majordojo/php_users/:/usr/local/majordojo/testitool/:/usr/local/majordojo/testitool/fragments/:/usr/local/majordojo/pmi-1.0-b1/"
</IfModule>

Note: the testitool Alias for testitool isn't strictly necessary since the DocumentRoot of the default-ported Virtual host points to it, but I added it as a convenience so that I could get there from [server]/testitool/, too.

MODIFY TESTITOOL.CONF

Set to the correct database values for you:

< $TESTITOOLDB = "testplans"; < $TESTITOOLDBUSER = "testitool"; < $TESTITOOL_DBPASS = "XXXXXX";

If you're not using Bugzilla, leave:

$BUGZILLA_INTEGRATION = 0;

MODIFY USERS.CONF

< $USERSBASEURL = "http://localhost/users"; became

$USERSBASEURL = "http://testitool.localhost/users";

< $COOKIEDOMAIN = ".localhost.localdomain"; # $SERVERNAME; became

$COOKIEDOMAIN = ".testitool.localhost"; # $SERVERNAME;

< $COOKIE_KEY = "my key";

stayed the same.

Set the three database settings as appropriate.

MODIFY PMI.CONF

I'm going to bow out of the document path settings in this section, actually, because I haven't really used this product much. Set the three database settings as appropriate.

If you're not using Bugzilla, leave:

$BUGZILLA_INTEGRATION = 0;

Restart Apache and point a browser at your new management system. Log in with the default user (see user/pass in the Users table in the php_users database).

TROUBLESHOOTING SECTION

MySQL and PHP have awesome troubleshooting sections on their web sites.

After you have PHP running happily and have checked the MySQL tables, there's not a heck of a lot else that can go wrong without the reason being apparent from error messages.

More misc. tips anyway:

Load a test php page in your environment.

Use the "create a new user" link in loginbox.php and go through the steps of enabling the new user. Confirm that they show up in the User table.

Double-check your ServerName in all of your .conf files and your Virtual Host section in httpd.conf.

Double-check that your $COOKIE_DOMAIN begins with a dot.

Confirm that your php_include value in httpd.conf includes everything that it should (see example above) and that it appears all on one line.

Make sure that you can log into the database(s) with the expected usernames directly from mysql, and that data appear in the tables that you expect them to be in (e.g. Users).

Try renaming the mcrypt cookie name in users.conf if you're having cookie problems.

Read all of the majordojo READMEs and INSTALL docs again. (Did you make the php.ini change, for example?)

Six Apart often speaks of how its technology and contributions to open source help many of the most popular Internet applications scale to unprecedented levels. One of these tools is memcached, yet as important and ubiquitous as it is, it surprisingly lacks the documentation necessary to help beginners in realizing its power and ease of use. Memcached is not for priests and gurus, despite how technical its homepage may appear. Memcache is a tool that can be easily installed and used by almost any developer on almost any platform.

This guide was written in an attempt to give developers out there an introduction to this incredibly powerful tool, and hopefully equip them with enough information to actually get started in building applications on the Internet that are faster and more reliable.

I, like many of my engineering colleagues, think of advertising as nothing more than a nuisance because most online advertising is just that. Why? Because it is completely uninnovative. When companies need to increase their advertising revenue, rarely do they bring to bear creative ways to establish more value in the inventory they have, they simply find more ways to introduce more of the same advertising across an already crowded site.

Rarely do companies treat their inventory as a product, in the way that they treat their application as a product. Case in point: MySpace - a horribly ad ridden product.

But then there are companies like Pandora that are approaching advertising with a new perspective. They do not think of a rectangle on the page as an ad, they think of the whole page as an ad. And in this format, which maybe considered to be by some to be more invasive is actually not. The ads do not pop out at you. They do not autoplay video. They do not interrupt or disrupt the user's experience, they simply frame the experience. And as a result, the ads feel more integrated, and the page as a whole looks more coordinated. Granted, it turns the page into a billboard, but in this context, I think it works.

But what is also interesting is that Pandora in this implementation has solved another problem - a problem that is likely to plague a lot of Web 2.0 Ajax-heavy applications: how to manufacture inventory for a product, that if successful in its design will produce very few page turns per visitor. Pandora then responds to the "moral equivalent" to a page turn. If a user pauses the music player, or chooses a different channel, then a new ad is rotated into view.

Here is Pandora with a standard ad in place - in this case, just a house ad for Pandora.

pandora-ad1.png

Here is the same page after a T-Mobile ad has been rotated in:

pandora-ad2.png

2  


Recent Comments

  • I actually don't subscribe to pandora because I wouldn't get to see the ads. They are amazing. john - I have a dual monitor setup and have seen one ad that appeared to span almost the full width of both monitors - each...

  • great article! BTW - note that (For us wide-screen junkies) pandora ads span a huge width... brilliant! as screens get bigger, there's more inventory! ...

  • Its funny you should ask. There are other approaches I like, but not many. I sincerely appreciate LiveJournal's model of advertising. We at Six Apart made a very difficult choice in regards to how to deploy advertising t...

  • I, too, like Pandora as a brand experience that makes sense for advertisers. That said, it's a common model that is executed all over the web to varying degrees of success. And it doesn't surprise me one bit that you l...

Close