diff --git a/admin/langimport.php b/admin/langimport.php
index adee53d4356..38df128f645 100755
--- a/admin/langimport.php
+++ b/admin/langimport.php
@@ -297,7 +297,7 @@ $url = new moodle_url('/admin/langimport.php', array('mode' => DELETION_OF_SELEC
echo html_writer::start_tag('td', array('valign' => 'top'));
echo html_writer::start_tag('form', array('id' => 'uninstallform', 'action' => $url->out(), 'method' => 'post'));
echo html_writer::start_tag('fieldset');
-echo html_writer::tag('label', get_string('installedlangs','admin'), array('for' => 'uninstalllang'));
+echo html_writer::label(get_string('installedlangs','admin'), 'uninstalllang');
echo html_writer::empty_tag('br');
echo html_writer::select($installedlangs, 'uninstalllang', '', false, array('size' => 15));
echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
@@ -325,7 +325,7 @@ if (!empty($options)) {
$url = new moodle_url('/admin/langimport.php', array('mode' => INSTALLATION_OF_SELECTED_LANG));
echo html_writer::start_tag('form', array('id' => 'installform', 'action' => $url->out(), 'method' => 'post'));
echo html_writer::start_tag('fieldset');
- echo html_writer::tag('label', get_string('availablelangs','install'), array('for' => 'pack'));
+ echo html_writer::label(get_string('availablelangs','install'), 'pack');
echo html_writer::empty_tag('br');
echo html_writer::select($options, 'pack[]', '', false, array('size' => 15, 'multiple' => 'multiple'));
echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
diff --git a/blog/locallib.php b/blog/locallib.php
index 94d703af817..da01dc5eac9 100644
--- a/blog/locallib.php
+++ b/blog/locallib.php
@@ -165,7 +165,7 @@ class blog_entry {
if ($this->uniquehash && $this->content) {
if ($externalblog = $DB->get_record('blog_external', array('id' => $this->content))) {
$urlparts = parse_url($externalblog->url);
- $topiccell->text .= $OUTPUT->container(get_string('retrievedfrom', 'blog') .': '. html_writer::link($urlparts['scheme'].'://'.$urlparts['host'], $externalblog->name), 'externalblog');
+ $topiccell->text .= $OUTPUT->container(get_string('retrievedfrom', 'blog').get_string('labelsep', 'langconfig').html_writer::link($urlparts['scheme'].'://'.$urlparts['host'], $externalblog->name), 'externalblog');
}
}
diff --git a/grade/export/lib.php b/grade/export/lib.php
index 351929a817a..5759485cbc8 100755
--- a/grade/export/lib.php
+++ b/grade/export/lib.php
@@ -156,7 +156,7 @@ abstract class grade_export {
*/
public function format_column_name($grade_item, $feedback=false) {
if ($grade_item->itemtype == 'mod') {
- $name = get_string('modulename', $grade_item->itemmodule).': '.$grade_item->get_name();
+ $name = get_string('modulename', $grade_item->itemmodule).get_string('labelsep', 'langconfig').$grade_item->get_name();
} else {
$name = $grade_item->get_name();
}
diff --git a/lang/en/langconfig.php b/lang/en/langconfig.php
index 9f890a4e1a3..7905f6696dc 100644
--- a/lang/en/langconfig.php
+++ b/lang/en/langconfig.php
@@ -29,6 +29,7 @@ $string['decsep'] = '.';
$string['firstdayofweek'] = '0';
$string['iso6391'] = 'en';
$string['iso6392'] = 'eng';
+$string['labelsep'] = ': ';
$string['listsep'] = ',';
$string['locale'] = 'en_AU.UTF-8';
$string['localewin'] = 'English_Australia.1252';
diff --git a/lib/outputcomponents.php b/lib/outputcomponents.php
index deb3a6b85e8..f4626f82140 100644
--- a/lib/outputcomponents.php
+++ b/lib/outputcomponents.php
@@ -743,7 +743,7 @@ class single_select implements renderable {
}
/**
- * Set's select lable
+ * Sets select's label
* @param string $label
* @return void
*/
@@ -851,7 +851,7 @@ class url_select implements renderable {
}
/**
- * Set's select lable
+ * Sets select's label
* @param string $label
* @return void
*/
@@ -1521,6 +1521,50 @@ class html_writer {
return $output;
}
+ /**
+ * Renders form element label
+ *
+ * By default, the label is suffixed with a label separator defined in the
+ * current language pack (colon by default in the English lang pack).
+ * Adding the colon can be explicitly disabled if needed. Label separators
+ * are put outside the label tag itself so they are not read by
+ * screenreaders (accessibility).
+ *
+ * Parameter $for explicitly associates the label with a form control. When
+ * set, the value of this attribute must be the same as the value of
+ * the id attribute of the form control in the same document. When null,
+ * the label being defined is associated with the control inside the label
+ * element.
+ *
+ * @param string $text content of the label tag
+ * @param string|null $for id of the element this label is associated with, null for no association
+ * @param bool $colonize add label separator (colon) to the label text, if it is not there yet
+ * @param array $attributes to be inserted in the tab, for example array('accesskey' => 'a')
+ * @return string HTML of the label element
+ */
+ public static function label($text, $for, $colonize=true, array $attributes=array()) {
+ if (!is_null($for)) {
+ $attributes = array_merge($attributes, array('for' => $for));
+ }
+ $text = trim($text);
+ $label = self::tag('label', $text, $attributes);
+
+ if ($colonize) {
+ // the $text may end with the colon already, though it is bad string definition style
+ $colon = get_string('labelsep', 'langconfig');
+ if (!empty($colon)) {
+ $trimmed = trim($colon);
+ if ((substr($text, -strlen($trimmed)) == $trimmed) or (substr($text, -1) == ':')) {
+ //debugging('The label text should not end with colon or other label separator,
+ // please fix the string definition.', DEBUG_DEVELOPER);
+ } else {
+ $label .= $colon;
+ }
+ }
+ }
+
+ return $label;
+ }
}
// ==== JS writer and helper classes, will be probably moved elsewhere ======
diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php
index 0b81912b4d6..89b7c7f392a 100644
--- a/lib/outputrenderers.php
+++ b/lib/outputrenderers.php
@@ -1091,7 +1091,7 @@ class core_renderer extends renderer_base {
}
if ($select->label) {
- $output .= html_writer::tag('label', $select->label, array('for'=>$select->attributes['id']));
+ $output .= html_writer::label($select->label, $select->attributes['id']);
}
if ($select->helpicon instanceof help_icon) {
@@ -1162,7 +1162,7 @@ class core_renderer extends renderer_base {
$output = '';
if ($select->label) {
- $output .= html_writer::tag('label', $select->label, array('for'=>$select->attributes['id']));
+ $output .= html_writer::label($select->label, $select->attributes['id']);
}
if ($select->helpicon instanceof help_icon) {
@@ -1369,9 +1369,9 @@ class core_renderer extends renderer_base {
$popuplink = new moodle_url("$url&popup=1");
$action = new popup_action('click', $popuplink, 'ratings', array('height' => 400, 'width' => 600));
- $ratinghtml .= $aggregatelabel.': '.$this->action_link($nonpopuplink, $aggregatehtml, $action);
+ $ratinghtml .= $aggregatelabel.get_string('labelsep', 'langconfig').$this->action_link($nonpopuplink, $aggregatehtml, $action);
} else {
- $ratinghtml .= "{$aggregatelabel}: $aggregatehtml";
+ $ratinghtml .= $aggregatelabel.get_string('labelsep', 'langconfig').$aggregatehtml;
}
}
diff --git a/mod/choice/lib.php b/mod/choice/lib.php
index dfe746358e2..1cc93ea9fa5 100644
--- a/mod/choice/lib.php
+++ b/mod/choice/lib.php
@@ -546,7 +546,7 @@ function choice_show_results($choice, $course, $cm, $allresponses, $forcepublish
echo ''.get_string('selectall', 'quiz').' / ';
echo ''.get_string('selectnone', 'quiz').' ';
echo ' ';
- echo html_writer::tag('label', get_string('withselected', 'quiz'), array('for'=>'menuaction'));
+ echo html_writer::label(get_string('withselected', 'quiz'), 'menuaction');
echo html_writer::select(array('delete' => get_string('delete')), 'action', '', array(''=>get_string('moveselectedcoursesto')), array('id'=>'menuaction'));
$PAGE->requires->js_init_call('M.util.init_select_autosubmit', array('attemptsform', 'menuaction', ''));
echo '