Problem/Motivation

Currently core is inconsistent in either having or not having full stop at the end of options. It's a common internet standard to not have full stops at the end of checbox options. Appart from this reason, in terms of typography a full stops is about having the reader pause for a bit. In this instance we want people to scan, rather than pause at the end of every option - so it makes sense not to end this with a full stop.

Proposed resolution

Remove full stops from the end of option labels.

Remaining tasks

Contributor tasks needed
Task Novice task? Contributor instructions Complete?
Create a patch Instructions Done (#8)
Update handbook documentation to clarify the standard Instructions Done (#6)
Reroll the patch if it no longer applies. Novice Instructions
Manually test the patch Novice Instructions
Review patch to ensure that it fixes the issue, stays within scope, is properly documented, and follows coding standards Novice Instructions

Suggestions for reviewers

  • Use git diff --color-words with the patch applied locally to make it easier to review the changes.
  • Check to ensure each instance I changed is legitmately a form label.
  • We can skip labels that include periods if they're only used for test modules.
  • I recommend just getting in whatever's correct first so that core follows the correct patterns sooner rather than later. If we miss one, well, we fix it later.

User interface changes

Periods removed from the ends of some form labels.

API changes

None

Original report by @Bojhan

Hey,

Talking to merlinofchaos about #1182762: Remove full stop from the end of form titles. We found that currently core is inconsistent in either having or not having full stop at the end of options. It's a common internet standard to not have full stops at the end of checbox options. Appart from this reason, in terms of typography a full stops is about having the reader pause for a bit. In this instance we want people to scan, rather than pause at the end of every option - so it makes sense not to end this with a full stop

As example, I have fixed the first occurring we saw. I am sure, there are plenty more.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Bojhan’s picture

Status: Active » Needs review

Mr.Bot please check my first Drupal 8 patch.

Bojhan’s picture

I have asked @markboulton for feedback, because I am unsure about my arguments here.

yoroy’s picture

I did a quick review of Windows, OS X, Ubuntu and Google settings screenshots. None of these use periods at the end of labels for checkboxes and radio buttons. It would make sense to apply the same here.

kscheirer’s picture

Issue tags: -Usability

full-stop-1.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, full-stop-1.patch, failed testing.

xjm’s picture

Title: Remove fullstops at the end of checkbox options » Remove full stops at the end of checkbox options
Assigned: Unassigned » xjm
Issue summary: View changes
Status: Needs work » Active

Updated the HIG for this standard:
https://www.drupal.org/node/387532/revisions/view/1632236/7535385
https://www.drupal.org/node/387526/revisions/view/2094676/7535379

This was annoying me today so seeing how much work a patch might be.

xjm’s picture

Some instances:

[mandelbrot:drupal | Thu 15:33:46] $ grep -r "'#title' =>.*'.*\\.'" *
core/lib/Drupal/Core/Condition/ConditionPluginBase.php:      '#title' => $this->t('Negate the condition.'),
core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php:      '#title' => t('Display prefix and suffix.'),
core/lib/Drupal/Core/Menu/Form/MenuLinkDefaultForm.php:      '#title' => $this->t('This link is provided by the @name module. The title and path cannot be edited.', array('@name' => $this->getModuleName($provider))),
core/modules/comment/src/Plugin/views/field/Comment.php:      '#title' => t('Link field to the entity if there is no comment.'),
core/modules/comment/src/Plugin/views/field/Link.php:      '#title' => t('Link field to the entity if there is no comment.'),
core/modules/contact/contact.module:    '#title' => t('Enable the personal contact form by default for new users.'),
core/modules/contact/src/CategoryForm.php:      '#title' => $this->t('Make this the default category.'),
core/modules/contact/src/MessageForm.php:      '#title' => $this->t('Send yourself a copy.'),
core/modules/content_translation/content_translation.module:    '#title' => t('Users may translate this field.'),
core/modules/file/tests/file_test/src/Form/FileTestForm.php:      '#title' => t('Allowed extensions.'),
core/modules/forum/src/Plugin/Block/ForumBlockBase.php:        '#title' => t('Read the latest forum topics.')
core/modules/language/src/Form/NegotiationConfigureForm.php:        '#title' => $this->t('Customize %language_name language detection to differ from User interface text language detection settings.', array('%language_name' => $info['name'])),
core/modules/language/tests/language_test/src/Controller/LanguageTestController.php:        '#title' => t('Link to the current path with no langcode provided.'),
core/modules/language/tests/language_test/src/Controller/LanguageTestController.php:        '#title' => t('Link to a French version of the current path.'),
core/modules/language/tests/language_test/src/Controller/LanguageTestController.php:        '#title' => t('Link to an English version of the current path.'),
core/modules/node/src/NodeTypeForm.php:      '#title' => t('Display author and date information.'),
core/modules/shortcut/shortcut.module:        '#title' => '<span class="icon"></span><span class="text">'. $link_text .'</span>',
core/modules/system/src/Form/PerformanceForm.php:      '#title' => t('Compress cached pages.'),
core/modules/system/src/Form/PerformanceForm.php:      '#title' => t('Aggregate CSS files.'),
core/modules/system/src/Form/PerformanceForm.php:      '#title' => t('Aggregate JavaScript files.'),
core/modules/system/src/Form/RegionalForm.php:      '#title' => t('Users may set their own time zone.'),
core/modules/system/src/Form/RegionalForm.php:      '#title' => t('Remind users at login if their time zone is not set.'),
core/modules/system/src/Form/ThemeSettingsForm.php:        $form['theme_settings']['toggle_' . $name] = array('#type' => 'checkbox', '#title' => $title, '#default_value' => theme_get_setting('features.' . $name, $theme));
core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestValidationForm.php:      '#title' => $this->t('AJAX-enabled textfield.'),
core/modules/system/tests/modules/ajax_forms_test/src/Form/AjaxFormsTestValidationForm.php:      '#title' => $this->t('AJAX-enabled number field.'),
core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php:        '#title' => t('This checkbox defaults to unchecked.'),
core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php:        '#title' => t('This checkbox defaults to checked.'),
core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php:        '#title' => t('This textfield has a non-empty default value.'),
core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php:          '#title' => t('This checkbox defaults to unchecked.'),
core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php:          '#title' => t('This checkbox defaults to checked.'),
core/modules/system/tests/modules/form_test/src/Form/FormTestRebuildPreserveValuesForm.php:          '#title' => t('This textfield has a non-empty default value.'),
core/modules/telephone/src/Plugin/Field/FieldFormatter/TelephoneLinkFormatter.php:      '#title' => t('Title to replace basic numeric telephone number display.'),
core/modules/user/src/AccountSettingsForm.php:      '#title' => $this->t('Require email verification when a visitor creates an account.'),
core/modules/user/src/AccountSettingsForm.php:      '#title' => $this->t('Enable signatures.'),
core/modules/user/src/AccountSettingsForm.php:      '#title' => $this->t('Notify user when account is activated.'),
core/modules/user/src/AccountSettingsForm.php:      '#title' => $this->t('Notify user when account is blocked.'),
core/modules/user/src/AccountSettingsForm.php:      '#title' => $this->t('Notify user when account is canceled.'),
core/modules/user/src/Form/UserCancelForm.php:      '#title' => $this->t('Require email confirmation to cancel account.'),
core/modules/user/src/Form/UserCancelForm.php:      '#title' => $this->t('Notify user when account is canceled.'),
core/modules/user/src/Form/UserMultipleCancelConfirm.php:      '#title' => $this->t('Require email confirmation to cancel account.'),
core/modules/user/src/Form/UserMultipleCancelConfirm.php:      '#title' => $this->t('Notify user when account is canceled.'),
core/modules/views/src/Plugin/views/exposed_form/ExposedFormPluginBase.php:      '#title' => t('Include reset button (resets all applied exposed filters).'),
core/modules/views/src/Plugin/views/field/FieldPluginBase.php:        '#title' => t('Add a read-more link if output is trimmed.'),
core/modules/views/src/Plugin/views/relationship/GroupwiseMax.php:      '#title' => t('Generate subquery each time view is run.'),
core/modules/views/tests/modules/views_test_data/src/Plugin/views/filter/FilterTest.php:      '#title' => t('Controls whether the filter plugin should be active.'),

And then in schemata:

[mandelbrot:drupal | Thu 15:37:19] $ grep -r "label: .*\\." * | grep "yml"
core/modules/comment/config/schema/comment.views.schema.yml:      label: 'Link field to the entity if there is no comment.'
core/modules/comment/config/schema/comment.views.schema.yml:      label: 'Link field to the entity if there is no comment.'
core/modules/field/config/schema/field.schema.yml:          label: 'Display prefix and suffix.'
core/modules/field/config/schema/field.schema.yml:          label: 'Display prefix and suffix.'
core/modules/language/config/schema/language.schema.yml:      label: 'Language from the URL (Path prefix or domain).'
core/modules/system/config/schema/system.schema.yml:          label: 'Compress JavaScript files.'
core/modules/telephone/config/schema/telephone.schema.yml:          label: 'Title to replace basic numeric telephone number display.'
core/modules/user/config/schema/user.schema.yml:      label: 'Require email verification when a visitor creates an account.'
core/modules/user/config/schema/user.schema.yml:          label: 'Notify user when account is activated.'
core/modules/user/config/schema/user.schema.yml:      label: 'Enable signatures.'
core/modules/views/config/schema/views.cache.schema.yml:          label: 'The length of time raw query results should be cached.'
core/modules/views/config/schema/views.cache.schema.yml:          label: 'Length of time in seconds raw query results should be cached.'
core/modules/views/config/schema/views.cache.schema.yml:          label: 'The length of time rendered HTML output should be cached.'
core/modules/views/config/schema/views.cache.schema.yml:          label: 'Length of time in seconds rendered HTML output should be cached.'
core/modules/views/config/schema/views.data_types.schema.yml:          label: 'The text to display for the more link.'
core/modules/views/config/schema/views.data_types.schema.yml:      label: 'The text to display for the more link.'
core/modules/views/config/schema/views.data_types.schema.yml:      label: 'A string to identify the area instance in the admin UI.'
core/modules/views/config/schema/views.data_types.schema.yml:      label: 'Should the area be displayed on empty results.'
core/modules/views/config/schema/views.data_types.schema.yml:      label: 'A string to identify the handler instance in the admin UI.'
core/modules/views/config/schema/views.data_types.schema.yml:          label: 'Add a read-more link if output is trimmed.'
core/modules/views/config/schema/views.display.schema.yml:      label: 'The feed icon will be available only to the selected displays.'
xjm’s picture

Status: Active » Needs review
Issue tags: +Novice
FileSize
25.53 KB

I fixed all the legit, non-test-only instances above, including checking for all instances of the string (to find matching tests and such). Some things in my grep are false positives.

Wasn't sure about the following...

  1. [mandelbrot:drupal | Thu 16:16:42] $ grep -r "Language from the URL (Path prefix or domain)" *
    core/modules/language/config/schema/language.schema.yml:      label: 'Language from the URL (Path prefix or domain).'
    core/modules/language/src/Plugin/LanguageNegotiation/LanguageNegotiationUrl.php: *   description = @Translation("Language from the URL (Path prefix or domain)."),

    Huh. Descriptions get periods. Labels don't. Which is it? Need to check.

  2. [mandelbrot:drupal | Thu 16:17:03] $ grep -r "Compress JavaScript files" *
    core/modules/system/config/schema/system.schema.yml:          label: 'Compress JavaScript files.'

    Why doesn't this string appear in the codebase anywhere? ...Left alone for now. I think the schema is bugged but that's out of scope.

  3. [mandelbrot:drupal | Thu 16:22:22] $ grep -r "The length of time raw query results should be cached" *
    core/modules/views/config/schema/views.cache.schema.yml:          label: 'The length of time raw query results should be cached.'
    core/modules/views/src/Plugin/views/cache/Time.php:      '#description' => t('The length of time raw query results should be cached.'),
    [mandelbrot:drupal | Thu 16:23:34] $ grep -r "Length of time in seconds raw query results should be cached" *
    core/modules/views/config/schema/views.cache.schema.yml:          label: 'Length of time in seconds raw query results should be cached.'
    core/modules/views/src/Plugin/views/cache/Time.php:      '#description' => t('Length of time in seconds raw query results should be cached.'),
    [mandelbrot:drupal | Thu 16:25:09] $ grep -r "The length of time rendered HTML output should be cached" * 
    core/modules/views/config/schema/views.cache.schema.yml:          label: 'The length of time rendered HTML output should be cached.'
    core/modules/views/src/Plugin/views/cache/Time.php:      '#description' => t('The length of time rendered HTML output should be cached.'),
    [mandelbrot:drupal | Thu 16:25:29] $ grep -r "Length of time in seconds rendered HTML output should be cached" *
    core/modules/views/config/schema/views.cache.schema.yml:          label: 'Length of time in seconds rendered HTML output should be cached.'
    core/modules/views/src/Plugin/views/cache/Time.php:      '#description' => t('Length of time in seconds rendered HTML output should be cached.'),
    

    Appears to be the description for the field rather than the label... left alone.

  4. [mandelbrot:drupal | Thu 16:25:42] $ grep -r "The text to display for the more link" *
    core/modules/views/config/schema/views.data_types.schema.yml:          label: 'The text to display for the more link.'
    core/modules/views/config/schema/views.data_types.schema.yml:      label: 'The text to display for the more link.'
    core/modules/views/src/Plugin/views/display/DisplayPluginBase.php:          '#description' => t('The text to display for the more link.'),
    

    Ditto.

  5. [mandelbrot:drupal | Thu 16:26:34] $ grep -r "A string to identify the area instance in the admin UI" *
    core/modules/views/config/schema/views.data_types.schema.yml:      label: 'A string to identify the area instance in the admin UI.'
    [mandelbrot:drupal | Thu 16:27:42] $ grep -r "Should the area be displayed on empty results" *
    core/modules/views/config/schema/views.data_types.schema.yml:      label: 'Should the area be displayed on empty results.'
    [mandelbrot:drupal | Thu 16:28:33] $ grep -r "A string to identify the handler instance in the admin UI" *
    core/modules/views/config/schema/views.data_types.schema.yml:      label: 'A string to identify the handler instance in the admin UI.'
    

    Also missing from the codebase.

  6. [mandelbrot:drupal | Thu 16:29:50] $ grep -r "The feed icon will be available only to the selected displays" *
    core/modules/views/config/schema/views.display.schema.yml:      label: 'The feed icon will be available only to the selected displays.'
    core/modules/views/src/Plugin/views/display/Feed.php:          '#description' => t('The feed icon will be available only to the selected displays.'),

    Description and not a label again.

Protips for reviewers:

  • git diff --color-words
  • Check to ensure each instance I changed is legitmately a form label.
  • I don't care about making test-only forms conform to UI guidelines.
  • I recommend just getting in whatever's correct first so that core follows the correct patterns sooner rather than later. If we miss one, well, we fix it later.
xjm’s picture

Issue summary: View changes
xjm’s picture

Assigned: xjm » Unassigned
chx’s picture

Status: Needs review » Reviewed & tested by the community

We can debate whether we want or not want full stops until the cows come home and then some but the UX people have spoken and it's simplest to just accept it and go ahead.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 8: no-more-dots-1182850-7.patch, failed testing.

Status: Needs work » Needs review

xjm queued 8: no-more-dots-1182850-7.patch for re-testing.

xjm’s picture

The previous fail was totally a testbot issue, "too many connections".

That said though let's get an actual review in here. :)

xjm’s picture

Assigned: Unassigned » xjm
+++ b/core/modules/file/tests/file_test/src/Form/FileTestForm.php
@@ -47,7 +47,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     $form['extensions'] = array(
       '#type' => 'textfield',
-      '#title' => t('Allowed extensions.'),
+      '#title' => t('Allowed extensions'),
       '#default_value' => '',
     );

+++ b/core/modules/forum/src/Plugin/Block/ForumBlockBase.php
@@ -28,7 +28,7 @@ public function build() {
       $elements['forum_more'] = array(
         '#theme' => 'more_link',
         '#url' => 'forum',
-        '#title' => t('Read the latest forum topics.')
+        '#title' => t('Read the latest forum topics')
       );
     }

These two changes are out of scope... reverting them.

xjm’s picture

Status: Needs review » Needs work
xjm’s picture

Assigned: xjm » Unassigned
Status: Needs work » Needs review
FileSize
24.4 KB
1.13 KB
jmcintyre’s picture

I noticed that a file referenced in the patch is now missing:

error: core/modules/contact/src/CategoryForm.php: does not exist in index

I also found a few more checkbox labels in tests.

jmcintyre’s picture

xjm’s picture

Status: Needs review » Needs work

Thanks @jmcyntire! #19 is not a full patch, so we need to update it to include the rest of the changes.

Also, see my earlier comment:

I don't care about making test-only forms conform to UI guidelines.

That said the changes in #19 look fine too... we just need to apply them on top of the full patch. :)

Stefan Lehmann’s picture

Assigned: Unassigned » Stefan Lehmann
Stefan Lehmann’s picture

Merged the two patches and went through all the checkboxes again. God, there are a lot! Only found one more relevant full stop. :-)

(patch created during code sprint #Drupal8NZ)

Stefan Lehmann’s picture

Status: Needs work » Needs review
Issue tags: +#Drupal8nz
Stefan Lehmann’s picture

Assigned: Stefan Lehmann » Unassigned
Bojhan’s picture

Status: Needs review » Reviewed & tested by the community

Whoo

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed d76697c and pushed to 8.0.x. Thanks!

  • alexpott committed d76697c on 8.0.x
    Issue #1182850 by xjm, Stefan Lehmann, jmcintyre, Bojhan: Remove full...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.