I have recently spent some time writing a module that extends CCK to do just this.
I do not know if drupal 7.x implements any such features, but I am working in 6.x and need this functionality in 6.x.
I wish to contribute and maintain this module upstream.
The module is under the GPL v2 license.
This module focuses on doing two major things:
1) Add the ability to insert HTML DOM attributes that are currently not available in drupal.
While I believe these few features should be in core, I am only going to extend this functionality and allow the Drupal developers to decide if they want this type of thing integrated or not.
2) Add the ability to set ARIA field attributes on CCK form fields. This is necessary step in providing website developers with the ability to make their websites accessible.
I have not seen any module that does these exact things.
The request form mentions "You must submit a finished, working module or theme for review along with your application", but I do not see any such place to upload it here.
Considering that you have "More information, the better." mentioned here, I will past the README.txt followed by the *.module code inline immediately below this line just to play things safe.
; $Id$
CONTENTS OF THIS FILE
---------------------
* Introduction
* Installation
* Versioning System
* Project Plans
INTRODUCTION
------------
Current Maintainer: Kevin Day
The need for Web Accessibility is ever increasing. Drupal needs to be capabable
of providing an accessible interface as well as accessible content. The
purpose of this module is to provide the ability to make CCK fields accessible
without breaking existing designs.
This project will attempt to provide what is needed to assist a drupal site
developer in following the WCAG 2.0 and the upcoming ARIA 1.0 Web Accessibility
Standards. This in itself does not make a website accessible, this module
only provides the means to do so.
INSTALLATION
------------
This module does not directly modify the database and relies on CCK to perform
database interactions. Therefore, no installation needs to be performed.
Simply enable/disable this module as needed.
VERSIONING SYSTEM
-----------------
I, Kevin Day, use version numbers to communicate the status of a given project.
Communicating to the end-user whether a project version is stable, unstable, a
bugfix release, or a feature release should take no more effort than looking at
the number itself. Described here is a short explanation of the versioning
system I use for all of the projects I own (modified with consideration to
Drupal's versioning system).
A version number is broken up into 3 parts: Major.Micro-Dev:
Major Version Number:
A Major version number represent features and redesigns of a project and API
breakage is assumed. Backwords compatibility is not expected, but nor is it
denied.
Micro Version Number:
The Micro version number represent bug fixes and security fixes. Micro
bugfixes should _never_ break API with the exception being serious security
issues.
-Dev tag:
The -dev tag will be appended to any version that is under development. Drupal
uses the scheme Major.x-dev, with Major being the only actual number. This
practice will be followed such that version 1.0 development will be: 1.x-dev
and a version 1.0 bugfix might be: 1.1.
PROJECT PLANS
-------------
The original project plans consist of three major versions. Each of the major
versions will represent a milestone of features added.
The first phase, version 1.0, will consist of the bare minimal set of features
for accessibility support. These are the HTML DOM attributes that are not
currently provided in drupal 6.x but are needed as failsafes for when
proper attributes (such as aria-label) are not available.
An additional reason behind keeping the first release simple and small will
give me, Kevin Day, time to get familiar with how drupal project management
works.
The first phase will not have any features such as aria-label added and will
be provided and maintained as a bugfix/security fix release until version 3.0.
The second phase, version 2.0, will consist of the core features of the ARIA.
These will be the most commonly used and most easily implemented set of ARIA
attributes.
The third phase, version 3.0, will consist of all of the remaining features
of the ARIA. By this release it is hoped that the ARIA 1.0 will not longer
be a draft but instead an official release. Expect API changes between 2.0
and 3.0 to reflect changes between the ARIA 1.0 draft and the ARIA 1.0 release.
Aside from the official milestone objectives, I expect a few additional
problems/issues to occur. These are left open to be handled with and planned
for when the time comes to deal with them.
Of the potential problems that can happen I am expecting the following:
1) API changes due to evolution in drupal (such as Drupal 6.x to 7.x).
2) API changes to ignorance on my part in different aspects of the project.
3) API changes due to CCK API Changes.
4) API changes due to WCAG and ARIA changes.
5) At some point, and probable with version 3.0, the number of available
options will overwhelm the administration of CCK fields. It is expected
that once I, Kevin Day, learn more advanced Drupal programming I will have
to create a separate accessibility administration page to cope with all of
the modifications needed to provide CCK fields with the ability to be made
accessible.
6) At this time, this projects goal is only to focus on CCK Form Fields. CCK is
not just about the form fields, but also about the presentation of the form
field data. It is very easy to predict that users will eventually want this
module to also provide the ability to make the presented CCK fields also
capable of providing accessible data. At this time I, Kevin Day, do not
know if this will be allowed to be supported in this specific project or if
another project will have to be created. Doing this will also make the
issue mentioned in #5 more likely to happen.
<?php
// $Id$
// Under the GPL v2 license
// Written by Kevin Day
/**
* Implementation of hook_help().
* TODO: implement advanced_help support for this
*/
function cck_accessibility_help($path, $arg){
switch ($path) {
case 'admin/help#cck_accessibility':
$message = t("In accordance to: <a href='@wai-aria1'>WAI-ARIA 1.0</a> and <a href='@wcag2'>WCAG 2.0</a> this module assists in making form fields produced by cck modules accessible.", array('@wai-aria1' => 'http://www.w3.org/TR/wai-aria/', '@wcag2' => 'http://www.w3.org/TR/WCAG20/'));
$message .= "<br>\n";
$message .= "<br>\n";
$message .= t("This module is broken up into two parts: Field Attributes and Aria Accessibility:");
$message .= "<ul>\n";
$message .= "<li>";
$message .= t("Field Attributes provide the standard html functionality that is used for accessibility support.");
$message .= "</li>\n";
$message .= "<li>";
$message .= t("Field Attributes added here are present because they are not available in drupal when this module was created.");
$message .= "</li>\n";
$message .= "<li>";
$message .= t("Aria Accessibility provides the standard WAI-ARIA fields that are explicitly provided for accessible devices to process.");
$message .= "</li>\n";
$message .= "</ul>\n";
return t($message);
}
}
/**
* Implementation of hook_field_settings_alter().
*/
function cck_accessibility_field_settings_alter(&$form, $op, $field){
switch ($op) {
case 'form':
$form['field_attributes'] = array(
'#type' => 'fieldset',
'#title' => t("Field Attributes"),
'#description' => t("Provides the standard html functionality that is used for accessibility support."),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['field_attributes']['field_attributes_field_editable'] = array(
'#type' => 'checkboxes',
'#title' => t("Field Editability"),
'#description' =>
t("This directly affects interactivity and is therefore considered needed for accessibility.") .
"<br>\n" .
t("See: <a href='@w3form_disabled'>http://www.w3.org/TR/html401/interact/forms.html#adef-disabled</a>", array('@w3form_disabled' => 'http://www.w3.org/TR/html401/interact/forms.html#adef-disabled')) .
"<br>\n" .
t("See: <a href='@w3form_readonly'>http://www.w3.org/TR/html401/interact/forms.html#adef-readonly</a>", array('@w3form_readonly' => 'http://www.w3.org/TR/html401/interact/forms.html#adef-readonly')),
'#default_value' => isset($field['field_attributes_field_editable']) ? $field['field_attributes_field_editable'] : array('', ''),
'#options' => array(
'disabled' => t("Disable the field"),
'readonly' => t("Make the field readonly"),
),
);
$form['field_attributes']['field_attributes_tooltip'] = array(
'#type' => 'textfield',
'#title' => t("Tooltip"),
'#description' =>
t("Provide a tooltip (aka: title attribute).") .
"<br>\n" .
t("There is a practice where the title attribute gets set as the same as the field label such that a screen reader will properly identify the field.") .
"<br>\n" .
t("See: <a href='@aria_names'>http://www.w3.org/TR/wai-aria/roles#namecalculation</a>", array('@aria_names' => 'http://www.w3.org/TR/wai-aria/roles#namecalculation')),
'#default_value' => isset($field['field_attributes_tooltip']) ? $field['field_attributes_tooltip'] : '',
);
$form['field_attributes']['field_attributes_alt'] = array(
'#type' => 'textfield',
'#title' => t("Alternate Text"),
'#description' =>
t("Provide alternate text (aka: alt attribute).") .
"<br>\n" .
t("This is normally a short description of the field and is similar to aria-label.") .
"<br>\n" .
t("See: <a href='@wcag_text'>http://www.w3.org/TR/WCAG20/#text-equiv</a>", array('@wcag_text' => 'http://www.w3.org/TR/WCAG20/#text-equiv')),
'#default_value' => isset($field['field_attributes_alt']) ? $field['field_attributes_alt'] : '',
);
break;
case 'save':
$form = array_merge($form, array('field_attributes_field_editable', 'field_attributes_tooltip', 'field_attributes_alt'));
break;
}
}
/**
* Implementation of hook_form_alter().
*/
function cck_accessibility_form_alter(&$form, $form_state, $form_id){
// individual form fields for content types all have a form id that end in _node_form
// because one cannot know what the name of the content type is, just make sure that the form id end in _node_form
if (isset($form['#node']) && isset($form['type']['#value']) && $form_id == $form['type']['#value'] .'_node_form') {
if (!isset($form['#after_build'])) {
$form['#after_build'] = array();
}
$form['#after_build'][] = 'cck_accessibility_after_build';
}
}
/**
* Implementation of callback_after_build()
*/
function cck_accessibility_after_build(&$form, &$form_state){
// avoid recursive calls with callbacks by using a private function
cck_accessibility_modify_node_form_fields($form, $form_state, $form);
return $form;
}
/**
* This is handles changing form fields for node_form
* This is outside of the hook_form_alter() because it needs to be called recursively
* The $outmost parameter is expected to be the outmost form variable
* $outmost was added so that the outer data does not get lost during recursion
*/
function cck_accessibility_modify_node_form_fields(&$form, &$form_state, &$outmost){
$children = element_children($form);
if (!empty($children)){
foreach ($children as $key) {
// $form[$key][0]['value'] will contain the actual cck field settings
if (is_array($form[$key])){
// and then it turns out certain modules, such as 'date' do not use the [0] location, so this too must be handled
if (array_key_exists(0, $form[$key]) && is_array($form[$key][0])){
if (array_key_exists('value', $form[$key][0]) && is_array($form[$key][0]['value'])){
cck_accessibility_modify_node_form_field($form[$key][0], $form_state, $key, $outmost['#field_info']);
}
}
// $key != '0' is passed here because all of the key='0' elements should already have been processed by the preceding if statement
else if (array_key_exists('value', $form[$key]) && is_array($form[$key]['value']) && $key != '0'){
cck_accessibility_modify_node_form_field($form[$key], $form_state, $key, $outmost['#field_info']);
}
}
// recursion is needed to get to all cck fields
cck_accessibility_modify_node_form_fields($form[$key], $form_state, $outmost);
}
}
}
/**
* This is called by cck_accessibility_modify_node_form_fields()
*
* The objective of this function is to alter/modify field settings to reflect custom changes provided by the hook_field_settings_alter() function
* Normally this would be straightforward, but how CCK stores its data is a confusing mess
*
* To properly element properties, one must edit $field['value']
* To properly change element attributes, one must edit $field['value']['attributes']
* Some of the CCK field settings are store in: $info[$name] (aka: $form['#field_info']['#field_info'])
*/
function cck_accessibility_modify_node_form_field(&$field, &$state, $name, &$info){
// call this now so that it does not need to be called for every single if case below
if (!isset($field['value']['#attributes'])) {
$field['value']['#attributes'] = array();
}
// Shorten a long field
$editable = $info[$name]['field_attributes_field_editable'];
// Disabled Attribute
if (is_array($editable) && array_key_exists('disabled', $editable) && $editable['disabled'] != '0'){
$field['value']['#attributes']['disabled'] = 'disabled';
} else {
if (isset($field['value']['#attributes']['disabled'])) {
unset($field['value']['#attributes']['disabled']);
}
}
// Readonly Attribute
if (is_array($editable) && array_key_exists('readonly', $editable) && $editable['readonly'] != '0'){
$field['value']['#attributes']['readonly'] = 'readonly';
} else {
if (isset($field['value']['#attributes']['readonly'])) {
unset($field['value']['#attributes']['readonly']);
}
}
// Tooltip Attribute (aka: Title Attribute)
if (!empty($info[$name]['field_attributes_tooltip'])){
$field['value']['#attributes']['title'] = $info[$name]['field_attributes_tooltip'];
} else {
if (isset($field['value']['#attributes']['title'])) {
unset($field['value']['#attributes']['title']);
}
}
// Alternate Attribute (aka: Alt Attribute)
if (!empty($info[$name]['field_attributes_alt'])){
$field['value']['#attributes']['alt'] = $info[$name]['field_attributes_alt'];
} else {
if (isset($field['value']['#attributes']['alt'])) {
unset($field['value']['#attributes']['alt']);
}
}
}
?>
| Comment | File | Size | Author |
|---|---|---|---|
| #6 | cck_accessibility.tgz | 11.1 KB | thekevinday |
| #4 | cck_accessibility.tgz | 11.1 KB | thekevinday |
| #2 | cck_accessibility.tgz | 10.19 KB | thekevinday |
| #1 | cck_accessibility.tgz | 10.05 KB | thekevinday |
Comments
Comment #1
thekevinday commentedComment #2
thekevinday commentedI have since made bug fixes.
However, the end result is even cleaner and better documented code so I thought it would be better to show the newer code.
Comment #3
avpadernoHello, and thanks for applying for a CVS account. I am adding the review tags, and some volunteers will review your code, pointing out what needs to be changed.
Comment #4
thekevinday commentedThank you.
In the amount of time that has passed, I have made bug fixes and learned a few more things about how CCK works.
Here is what I call the latest.
Comment #5
wadmiraal commentedHi,
Careful, in your .info file:
Assists in making cck fields accessibile => accessible :-)
Otherwise, this module works as advertised. The code seems clean. Respects almost all Drupal coding standards (I only saw the if/else -> http://drupal.org/coding-standards#controlstruct).
Dont' know if we can set this to "reviewed & tested" ? Or do you need more than one review (because it does say "by the community". I'm hardly the "community" :-) ) ?
Comment #6
thekevinday commentedThis fixes the typo and applies the if-else style changes.
This also contains 1 bugfix, removing a warning message when adding a new CCK field under certain circumstances.
Comment #7
sreynen commentedI don't believe these need more than one review, and #5 gave it a positive review, so I'm marking this as RTBC.
Comment #8
avpadernoThank you for your contribution! I am going to update your account.
These are some recommended readings to help with excellent maintainership:
You can find more contributors chatting on the IRC #drupal-contribute channel. So, come hang out and stay involved.
Thank you, also, for your patience with the review process.
Anyone is welcome to participate in the review process. Please consider reviewing other projects that are pending review. I encourage you to learn more about that process and join the group of reviewers.
I thank all the dedicated reviewers as well.
Comment #11
avpaderno