Notes: Savvy CFMeetup Presentation

These are notes for a presentation on Savvy, the content management system, by Joshua Cyr.

For setup, there is a cfm page that has numerous CFSETs that you have to set. After that, everything is basically good to go. It will create the database in the DSN you provide it, by simply running an install script by calling a cfm page.

First thing you’ll have to do when you login: Set up some templates for your site. In CFEclipse, he took a normal HTML page with content, and just started editing Savvy tags. He replaced the <title> with a header object, some menu navigation with a nav object, basic content with a content object. What about when you alter a template? There is an option to rebuild pages (or entire site) for when a template is changed.

He showed that an object can be shared. This way, anytime an object with that name appears on any page, changes to that object will be reflected on all of the pages.

Creating pages and directories, actual physical files and directories are indeed saved. This is handy for apps that do traffic analysis. Sometimes they sputter on pages that have a front controller for pages (index.cfm?page=MyPage).

When you create a page, you then can view each content area in the new page. Just click on it and you can edit that particular content area. The editing mechanism is pretty typical: A WYSIWYG editor, decent picture management. You can adjust settings so that the WYSIWYG editor will look exactly like you want it. Handling links is pretty simple: Can pull up a screen similar to picking a picture, except for pages. When you start typing a page name, it has auto-suggest to help. Note that the link management is very basic: It helps you create a hard link in the content, and nothing is done to warn you if you will break links when you change a page’s name or location (or delete it).

When it comes time to publish, you can publish an object at a time, or the whole page. Publishing can be scheduled, and expiration is available as well. Additionally, it supports workflow where the user will not have publishing rights, so instead he can request publishing, and then a person with that permission will do the publishing. Savvy does not have sophisticated workflow management, however. It keeps the process simplified. History of items is recorded and can be viewed. History by object/page or by user.

When managing users, you not only can supply exact permissions of what a user can do, but also can do groups that users belong to. Then perms are assigned based on their group.

Now, when you have CF in you template page, it doesn’t work like you’d expect, when a new page is created from a template, it will effectively paste in the results of your CF, not actually render the CF on the page. Thus, welcome to their custom code object. It effectively acts like a CFINCLUDE for your pages.

Savvy plays nice with other CF applications. He did not demo or speak on this any further, though.

Thanks, Joshua.

PrintJobMgr Uses 99% CPU

I couldn’t understand why everything on my new iMac started creeping really slow. The last straw was when iTunes started skipping.

I opened up the Activity Monitor in the Utilities folder, set it to view “All Processes”, and noticed that a process named “PrintJobMgr” was using a lot of processor time and took up over 600MB.

As it turns out, this has been discussed on Apple’s forums. It seems to be happening to people when there is a print job that never was printed, and thus is continually waiting in the print queue. I’m not sure how, but this is exactly what happened on my iMac, and deleting the print job in the queue fixed the problem.

I’m hoping Apple fixes that one soon.

Why That Batch For Loop Isn’t Working

Time for another fun foray into Windows batch scripts. Perhaps you've used the FOR /F command to loop through the contents of a file (for instance, perhaps some data that was redirected to a text file from a command). Grab a line, act on its values, and output some text and commands.

Let's set this up. First, we have a data file named SomeAccounts.txt:

Josh
Mary
Suzy
Amanda
Trisha
Ben

Then, we have ProcessAccounts.bat, which we want to just loop through the accounts in the text file, tell us what they are, and tell us the first letter of the account name (just to have something to do):

DOS:
  1. set file=SomeAccounts.txt
  2. FOR /F %%i IN (%file%) DO (
  3. set username=%%i
  4. echo My account, %username%, starts with %username:~0,1%.
  5. )

Except when you do this, you encounter a problem: All of the values from the FOR loop are the same! It's as if the for loop ran the proper number of times, but it just ran on the last record over and over again! See below:

My account, Ben, starts with B.
My account, Ben, starts with B.
My account, Ben, starts with B.
My account, Ben, starts with B.
My account, Ben, starts with B.
My account, Ben, starts with B.

What's actually happening is the FOR loop is indeed running over every line, and setting the variables as instructed, but the results of those variables being altered isn't echoed until the FOR loop is complete, so the last value of the variable is what displays. This wouldn't be a problem if you were just using your FOR parameter, in this case %%i, but any variables you set while in the FOR loop, like username, experience this "wait until you're out of the loop" phenomenon.

The fix is simple enough, if you know about it! But I've found the solution to be a bit elusive, which is the whole point of sharing it now.

The key is the setlocal EnableDelayedExpansion command. As explained at ss64.com, making this statement before your FOR loop will enable you to display variables as their value at the moment you're referencing them, or their "intermediate values" while in the middle of the FOR loop. In addition to calling the setlocal command, you then have to reference your variables with the exclamation point (!) rather than percent (%) to indicate that you want to use the intermediate value.

Your script will then look like this:

DOS:
  1. setlocal EnableDelayedExpansion
  2. set file=SomeAccounts.txt
  3. FOR /F %%i IN (%file%) DO (
  4. set username=%%i
  5. echo My account, !username!, starts with !username:~0,1!.
  6. )

It will now happily act as desired, outputting these results:

My account, Josh, starts with J.
My account, Mary, starts with M.
My account, Suzy, starts with S.
My account, Amanda, starts with A.
My account, Trisha, starts with T.
My account, Ben, starts with B.

Notes: Design Patterns

These are notes from the Design Patterns and ColdFusion presentation by Sean Corfield on 12/13/07.

Design patterns are basically common solutions to recurring problems. Using a pattern provides a common vocabulary between developers. If you say, "I'm using a Remote Facade", someone else will know what you're talking about without any further explanation.

What makes up a pattern? (a) A name, to provide a common vocabulary between developers. (b) A recurring problem; typically there are "forces", or circumstances in the coding situation, that will lead you to use the pattern. (c) The solution, or template for solving the problem. Note that a pattern doesn't have an exact, proper way to be executed. It is indeed just a guide, or template. (d) Consequences: Every pattern has its pros and cons.

Common Problems and Design Patterns

  1. Problem: Duplicate site content at top and bottom of site.
    Pattern Name: Composite View
    Solution: Include a header and footer that has this duplicated content.
  2. Problem: Need an instance of an object that is accessible everywhere in an application.
    Pattern Name: Singleton
    Solution: Create it at application startup and put it in application scope.
    Trade offs: Initialization is in one place (+). Easy access to objects app-wide (+). But now your code is very dependent on that application scope, which breaks encapsulation (-).
  3. Problem: Several components make up a particular functionality, but you don't want to expose all of that complexity to the calling code, especially in case I want to change how I implement it.
    Pattern Name: Facade
    Solution: Create a new component that has a nice, simple, high-level API. Client code calls it, and it calls all the complex components under the hood.
    Trade offs: App code no longer needs to no about all of the complex internals (+). However, there will be redundancy of methods between the API and the underlying code, which is more maintenance and more coding (-).
  4. Problem: I need some standardized code that runs on every request of the application, perhaps security checks.
    Pattern Name: Front Controller
    Solution: Make all requests go through a common piece of code, and have that code apply the logic before/after processing the actual request. i.e. index.cfm?page=myaction. Everything routes through index.cfm.
    Trade offs: Full control over every request; can easily add add'l functionality (+). All URLs look similar (+/-). The control page (index.cfm) can get complicated (-).

Recognize that patterns are NOT code. Any example code for a pattern is just that: An example. Design patterns can apply to any language and typically can be used in the design phase of an app. Some patterns are language-specific. Do patterns have an object-oriented bias? Well, yes. Most design patterns are focused on OO design. But design patterns in general do not have to be OO-specific. It just tends to be OO people who are considering design patterns.

Ruby Patterns for Consideration

  1. Active Record pattern for managing persistence of objects. An object knows how to save/get itself with a database.
  2. Dynamic finder methods. By virtue of the method name, the functionality can be figured out. This is done with a method that runs when the called method doesn't exist ("method_missing"). That method can than act on the method that was called based on its name. ColdFusion can do this with the onMissingMethod() method of a CFC.

Patterns and interfaces. Interfaces are not needed but are useful as a descriptive tool in explaining pattern implementations. ColdFusion 8 introduced <cfinterface>. Alternatively, you could use duck typing.

Design Patterns from Gang of Four

  • Creational Patterns
    • Abstract Factory, Builder, Factory Method, Prototype, Singleton
  • Structural Patterns
    • Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy
  • Behavioral Patterns
    • Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor

To learn patterns, you can observe frameworks, which often implement multiple patterns: Front Controller, MVC, Identity Maps, Context Objects, etc.

Thanks for the great presentation, Sean.

  Theme Brought to you by Directory Journal and Elegant Directory.