Tuesday, 6 September 2011

Fix TYPO3's powermail custom css option

Powermail is a great little plugin, one thing I absolutely hate about it though is the automatic html it generates.
The biggest problem is it generates the form elements using unique id's which change every time you create a new form. This is fine till you want to style the form with css. Look at the problem you get:
<div class="tx_powermail_pi1_fieldwrap_html tx_powermail_pi1_fieldwrap_html_text tx_powermail_pi1_fieldwrap_html_151 even" id="powermaildiv_uid151">
<label for="uid151">First Name<span class="powermail_mandatory">*</span></label>
<input type="text" required="required" tabindex="1" id="uid151" class="powermail_name powermail_text powermail_uid151 invalid" value="" name="tx_powermail_pi1[uid151]">
</div>
Essentially the only way to change the style of a form item is by using the unique id, so your style sheets break every time you want to copy the form. Now powermail has an option "Add CSS class" which I thought would solve the problem, however it only added the class to the child element (the input element in the above HTML), which to me was useless because I needed to style the parent div and label. The only way I could see of getting this working was using a powermail hook and overriding the code as follows:
Create a file called class.tx_powermailmods.php and place it in either a custom extension or just in typo3conf.
<?php
class tx_powermail_mods {
function PM_FieldWrapMarkerHook($uid, $xml, $type, $title, $markerArray, $piVarsFromSession, $pObj) {
$class = 'class="'; // start class tag
$class .= ($pObj->pi_getFFvalue(t3lib_div::xml2array($pObj->xml), 'mandatory') == 1 ? 'validate-one-required ' : ''); // add required class if needed
$class .= 'powermail_' . $pObj->formtitle; // add form title
$class .= ' powermail_' . $pObj->type; // add input type
$class .= ' powermail_uid' . $pObj->uid; // add input uid
$class .= ' powermail_subuid' . $pObj->uid . '_' . $i; // add input subuid
$class .= '" '; // close tag
$pObj->markerArray['###CLASS###'] = $class;
$pObj->markerArray['###CUSTOM_CLASS###'] = ($pObj->class_f != '' ? ' ' . $pObj->class_f : ''); // add manual class
}
}
?>
This removes the custom class from the class attributes of the form inputs and creates a new marker CUSTOM_CLASS which you can use in the template, but first you'll have to enable this hook. In localconf.php or the custom extensions ext_localconf.php put the following:
<?php
//If your using a custom extension called powermail_mods:
require_once(t3lib_extMgm::extPath('powermail_mods') . 'class.tx_powermailmods.php');
//Or if the file is sitting in typo3conf
//require_once(PATH_typo3conf . 'class.tx_powermailmods.php');
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['powermail']['PM_FieldWrapMarkerArrayHook'][] = 'tx_powermail_mods'; ?>
Now you just have to add in the new custom marker, you'll need to modify the template tmpl_fieldwrap.html which you'll find in the powermail/templates directory (typo3conf/ext/powermail/templates). Create a copy of this file and place is somewhere in fileadmin (fileadmin/templates for example). Now modify the powermail config in a template:
plugin.tx_powermail_pi1.template.fieldWrap = fileadmin/templates/tmpl_fieldwrap.html
Now you can modify the template using the new marker, which I've used like so:
<!-- ###POWERMAIL_FIELDWRAP_HTML_TEXT### begin -->
<div id="powermaildiv_uid###POWERMAIL_FIELD_UID###" class="tx_powermail_pi1_fieldwrap_html tx_powermail_pi1_fieldwrap_html_text tx_powermail_pi1_fieldwrap_html_###POWERMAIL_FIELD_UID### ###ALTERNATE### ###CUSTOM_CLASS###"###DIVJS###>
<label for="###LABEL_NAME###">###LABEL######DESCRIPTION######MANDATORY_SYMBOL###</label>
<input type="text" ###ONFOCUS######NAME######VALUE######CLASS######ID######SIZE######MAXLENGTH######READONLY######TABINDEX######ACCESSKEY######JS###/>
</div>
<!-- ###POWERMAIL_FIELDWRAP_HTML_TEXT### end -->
This allows you to define a custom class and reuse it across multiple forms. Much better.

1 comment:

  1. Hey Mr., This is a powerful solution. But I noticed this is for version 1.x. Can you possibly have a solution for version 2.x. Version Powermail 2.x as very limited means to configure. Also, any suggestions on how to add the country/region select to 2.0?

    ReplyDelete