Puma Upload Errors
November 2nd, 2006Having problems uploading files through Puma’s resource uploader?
Check to make sure that both your PHP upload_max_filesize and MySQL max_allowed_packet variables are set large enough to accomodate the file.
Notes on using Sphinx with Puma
October 24th, 2006Make sure that the directory that houses your index files (/path/to/sphinx/var/data) is writable by the user that PHP runs as. The index files themselves must be, also.
The Puma domain model
October 16th, 2006Having an understanding of the Puma domain models will make it much easier to write your own plugins. Not that Puma is a particurly difficult to understand application, or that CMSs in general have obscure domain models, but just that every one is so different you’re not likely to want to waste your time translating SQL into understanding.
In case you’ve forgotten your UML, here’s a brief reminder of UML syntax:
- Class names go on the top line of the box (like Page, User, etc).
- Abstract class names are written in italics and represent classes that shouldn’t be directly instantiated.
- Attributes go in the middle of the box (date, time, etc). The name comes first, then the type.
- Methods go in the bottom box (authorized, etc).
- Static methods are underlined and don’t need to be called on an instance.
- Types followed by types in angle brackets (List) are generics. List means “A list whose elements are of type Page”.
That’s the brief rundown. You don’t need to be a UML expert to see what’s going on up there.
Gross anatomy
A Puma website is a single tree of Page objects and a set of Users. The pages are versioned; each page has at least one Version object associated with it that contains the contents of the page for a particular version of the page. Each User has a permission level which is compared with a given page’s permissions to determine whether that user can edit or view the page. There’s a special user that corresponds to an anonymous user of the website; it’s named Anonymous appropriately enough.
Most pages in a Puma website are HtmlPages, whose versions contain raw HTML. Other subtypes of Page are useful for other purposes—HiddenPages, for example, shouldn’t be listed on any public-facing portion of the website, so you can hide administrative pages like Copyright beneath a HiddenPage.
Cradle to Grave
October 16th, 2006This article provides a gross overview of the Puma request handling timeline, which is useful if you’re poking around in the Puma internals trying to debug or add something.
- Initialization. The first order of business is to make the PHP environment sane and load preferences. This takes place in init.inc. Puma runs with all error reporting turned on, and it’s a matter of development policy that all warnings be fixed. We immediately fix any magic quoting that PHP may have inflicted on the request variables to avoid quoting and unquoting headaches later. Puma installs PEAR error handlers so no PEAR functions fail silently.
With the PHP environment set up for early error reporting, execution continues. - Loading and initializing components. Next, the dispatcher is loaded, along with Smarty, and any files that reside in the model/ directory. That means if you add a new model, you don’t need to explicitly require it. A new Smarty object and Dispatcher object are created, but no request processing is done.
- Populate the dispatch table. Puma’s dispatcher is responsible for mapping requests into actions, which happens by matching
PATH_INFOwith the dispatcher’s table of registered controllers and their handlers. Puma’s dispatch table is created automatically by the dispatcher when it autoloads the controller classes in thecontroller/directory. If you create a new controller and place it in thecontroller/directory, the dispatcher will find it and register its handlers without any special action on your part. See the articles on the dispatcher for more information. - Dispatch the request. Puma calls the dispatcher with
PATH_INFO. The dispatcher determines which handler to run. The handler performs whatever action is necessary. The dispatcher stashes any information which may be useful in rendering the resulting View in the global Smarty object. If the browser needs to be redirected (for example, after a login step, or after submitting a page edit), the handler accomplishes this by calling the redirect method of the dispatcher object. Unless the handler redirects or aborts abnormally, control eventually returns from the dispatch process. Puma determines which template to render by looking in the Smarty variable stash for a variable called “template” which should have been set by the handler. Typically, if the request was for/page/view/231, the handlerPageController:view()will set this variable to “page.view”. Puma looks for a GET variable called “format,” which it appends to the template name if it’s found—for example,/page/view/231?format=xmlresults in a final template name of “page.view.xml” while/page/view/231results in a final template name of “page.view.html”. Otherwise, Puma assumes the format is HTML. Puma hands off to Smarty to render the template. - Augmented Smarty template search paths. Puma uses an extended Smarty (aptly called MySmarty) which looks in multiple locations for a template before giving up. This way, you can override the ugly Puma default templates on an as-needed basis simply by putting your templates in the site/template directory. MySmarty always prefers your templates to the default Puma templates, so you don’t have to do anything special to tell Puma you’ve overridden a template.
That’s it! Once Smarty renders the output, the rest is history.
Welcome to the PumaCMS world
October 15th, 2006PumaCMS is a wikilike content management system developed over the course of several years for Creole West Productions. Why didn’t we just use something else? Basically, everything I ran across when evaluating other CMSs was way too bloated, and everything I ran across when evaluating other wikis just didn’t fit the bill. We just wanted a CMS that worked and was exceedingly easy to customize. Since the CMS would form the foundation of several of Creole West Productions’ core websites and products, it was reasonable to build a new CMS from scratch.
Recently, Creole West Productions has decided to release Puma to the rest of the world. We thought it was useful, and maybe someone else out there will too. Having spent most of its life as internal software, there’s not much documentation on how to use it and how to make it work for you. This blog aims to fix that situation with a series of articles about how to customize Puma for your own nefarious purposes, as well as the nitty-gritty details of administering a Puma website, and documenting some of the more important internal features of Puma along the way.
This blog is also a commentary on the nature of Puma and the design patterns that make it tick. It’s an case study in rapid development touching on REST, MVC, object mappers, artificial intelligence (yes, there’s some of that in Puma), and a million other little gems of interest to developers.
I hope you enjoy the content!