Formunculous

Customization Guide


One of the primary goals of Formunculous is to provide for a high level of customization to make sure the forms that it produces meet your needs. I have provided quite a bit of default style that is fairly robust, and a great deal of customization power within the builder itself. That doesn't mean that those defaults and tool can get forms and confirmation pages to look anywhere near how you want them to.

To that end, this guide will show the plethora of ways that you can customize func both globally and on a per form basis. This power is provided by the Django template system, a custom template loader built into func, and of course just plain old CSS.

Simple CSS Customization

I won't go into too much depth dealing with CSS customization since that is covered considerably better by CSS tutorials and sites, but I will cover how the CSS for func is organized and go over how I customized it to work for this site.

Func only has two CSS files, formunculous.css and apply.css. formunculous.css is only used for handling the styles in the builder and reviewing interface; whereas apply.css is for styling the user side of func—the forms and various confirmation and thank you pages. Both of these stylesheets are in the formunculous/media/css directory.

Hopefully those two files are fairly well documented, although I am sure not as much as what you may like, but that is why tools like Opera's Dragonfly exist, and you should be able to override anything in them using your own stylesheet. It is strongly recommended that you don't modify them directly however, since they will be updated with each release.

apply.css Customization

That being said, now we'll take a look at how I customized func for this site. This wasn't to bad considering that func is designed for a site with a white background. When I was designing, I thought it would be a serious pain, but there weren't too many pain points. Here is the CSS customizations for apply.css and the actual form views that are currently in use on the contact form

  input[type=text], input[type=file], input[type=password], textarea {
	  border: 1px solid #1853c8;
	  background-color: #5587ea;
	  padding-top: 5px;
	  font-size: 1.2em !important;
  }

  input[type=submit], input[type=button] {
	  border: none !important;
	  background: url('../img/button.png') no-repeat top left;
	  background-color: transparent !important;
	  color: #d5f6ff !important;
	  width: 106px;
	  height: 26px;
	  text-align: center;
	  font-weight: bold;
  }

  input:focus[type=text],input:focus[type=password], input:focus[type=file], input:focus[type=checkbox], textarea:focus {
	  background: url('../img/infocus.png') repeat-x top;
	  background-color: #5587ea;
  }
  
.apply_row_errors input {
	background-color: #782121;
}
  

That is all I had to do, I mostly just needed to customize the various input boxes and textareas. These customizations also apply to all the default form fields on this site, including the comments forms, so this is really just general customization with the exception of the error row that is func specific.

Do note the unfortunate !important flags in the rules. These had to be used due to some styles in the func CSS files taking precendence by default, and I will be looking at getting rid of these in a future release.

formunculous.css Customizations

Now we'll take a look at the customizations for this site done in formunculous.css. These are a bit more involved and formunculous specific, but all of them have to do with background color of this site. If you are using a light background on your site, these shouldn't be neccessary.

	#formunculous-apply-available-forms h3 {
	color: #b3dbaa !important;
}

.formunculous_tab_bar ul .here { 
	background-color: #2f6494 !important;
	border-bottom: none;
}

.formunculous_tab_bar ul .here a { 
	color: #b3dbaa;
}

#formunculous-review-search input[type="submit"] {
	background-color: #ccc !important;
	width: 20px;
	height: 27px;
	background-position: center center;
}

table.formunculous_table th {
	color: #808080;
}
table.formunculous_table .sort-reverse,
table.formunculous_table .sort {
	background-color: #f1f1f7;
}
  

That pretty much covers CSS for func. If you have any issues that come up let me now via the support section of the site, and I'll be happy to take a look at any problems you encounter.

Full Template Customization and Form Specific Customizations

One of the really killer features of Django is its template system. More specifically, its template inheritance model. Formunculous uses this along with a custom template loader to provide full customization of forms, and overall look and feel of the application.

Template Inheritance

Func's base templates are located in the formunculous/templates/formunculous directory. The base.html template simply inherits from "base.html" and provides a common place for the rest of the formunculous templates to inherit from. If your site doesn't use "base.html" as the base template, you will need to change it here, or create a "base.html" template that extends the baseline template you are using.

The rest of the formunculous templates are also located in this directory and can be easily overridden by declaring a directory to hold customized templates in your settings.py TEMPLATE_DIRS tuple. Then creating a formunculous directory in the specified directory, and using the same file name as the template you wish to override.

If you choose to override any of the templates at this global level, I strongly recommend copying the template over first, and when there is a new release of func, check for any differences that may have occurred with the default template. You may miss new features if you don't do this.

Here is a rundown of each of the templates in use, and their function:

All ajax_*.html files
Used on the admin section of formunculous, should generally not be customized.
apply.html
Responsible for rendering the user forms. This form can be customized both globally and on a per form basis (see per form template customizations below).
apply_history.html
For authenticated and multi-submission forms, this shows the user all the instances of the form that they have already filled out
base.html
Foundation template that all non-builder based templates inherit from.
All builder_*.html files
These inherit from the built-in admin template and generally should not be customized.
completed.html
This is the template shown after a form has been completed. This can be customized globally and on a per form basis.
confirm.html
This is shown on authenticated forms, and is used to confirm to the user that a form has been completed. This can be customized globally and on a per form basis.
denied.html
Simple access is denied template when auser performs an action they are not authorized for.
email_application.html
This is the e-mail template used for e-mail only forms that include the data and attachments.
index.html
Shows the currently available form definitions, and forms the user is authorized to review.
notify_reviewers_email.html
This is the e-mail template for notifying reviewers that a form has been completed.
All review_*.html files
Used to support the review portion of func. These can be customized, but are not public facing.
thankyou.html
This is the confirmation page for non-authenticated forms such as the contact page on this site. This can be customized globally and on a per form basis.

Per Form Definition Customization

When a form is requested func attempts to find the most specialized templates for rendering forms. It first attempts to grab the required template—either apply.html, confirm.html, thankyou.html, or complete.html—for the specific form definition that is requested. This way, if you want to override the default thank you page for just your contact form for example, you can do that by placing a thankyou.html template in a directory that has the same name as the slug for your form definition. After that it uses the global default template specified in a settings.py defined if it exists, and then looks in the Formunculous installation directory.

Lets take an example to hopefully make this clearer. Lets say we create a form called Customer Satisfaction Survey, and that we created a global default thank you page in our settings.py template_dir in /project/templates/formunculous/thankyou.html that applies to every form I create under this projects settings file.

Now we want to create a custom thank you page for the Customer Satisfaction Survey that just redirects the user to our home page after completion.

To do this we first need to take note of the slug field for the form definition. In this example, the automated slug field for this form definition becomes customer-satisfaction-survey. After we have that, all we need to do to create a custom thank you that applies only to this form definition is to create a folder called customer-satisfaction-survey and create a thankyou.html file in that directory. The full path being: /project/templates/formunculous/customer-satisfaction-survey/thankyou.html.

That's it, we just need to edit that file to do a redirect instead of displaying anything, and we're done. Using a simple javascript redirect, this would be something like:

<script type="text/javascript">
    window.location = '/';
</script>

After that, func will automatically use that template for the survey form definition, and users that complete it will be redirected to the home page of the site.