Feedback on idea for module handling text in code (perhaps including translations)

I’m on Drupal 7. Anyone know if this is “solved” in Drupal 8?

I often need to add text to forms to explain why this form should be used, how it works and other stuff. This information doesn’t belong to any specific field and is usually placed at the top of the form.

I have a few tens of these texts and they are added in code inside hook_form_alter or render_alter etc.

This irks me in several ways:

* The text is not editable for users. This isn’t always desirable, but sometimes it is.
* It feels like the 90s when you mixed code and content.
* The text bits are spread all over the code.

I would like to create a system where most, if not all text from custom code is handled by some sort of repository. I thought about putting all text in variables, but having too many variables isn’t a good solution.

I want to get feedback on a possible solution to this. It is unrefined and unsophisticated, but it will solve my problem.

Inside each custom module you create an inc file, perhaps module_name.text.inc or something. This file would be included in the module_name.module file and might look something like this:

function you_decide_the_name($key) {
  $text = array(
    'form_name_introduction' => t('This is the introduction used in the form with name name.'),
    'custom_text_a' => t('Some text that is inserted somewhere using "#markup" in some render array'),
  );

  return isset($text[$key])
    ? $text[$key]
    : '';
}

This is the easiest way for a one-off solution. Perhaps we should throw an exception or something more noisy if the text key doesn’t exist.

It could be made a bit more drupalistic though. Instead of creating functions yourself imagine implementing a hook instead.

function MODULE_NAME_code_content($key) {
  $text = array(
    'form_name_introduction' => t('This is the introduction used in the form with name name.'),
    'custom_text_a' => t('Some text that is inserted somewhere using "#markup" in some render array'),
  );

  return isset($text[$key])
    ? $text[$key]
    : '';
}

A contrib module “code_content” will invoke all hook_code_content on… init(?) and provide a unified set of functions to retrieve/edit and perhaps translate the code content. Instead of including each individual file, the code_content module could create an array of all modules implementing hook_code_content keyed by module name. After invoking, the resulting array may look like this:

$code_content_across_modules = array(
  'module_name_a' => array(
    'form_name_introduction' => t('bla bla'),
    'custom_text_a' => t('yak yak'),
  );
);

In your form alter hook, you could do something like this:

function MODULE_NAME_form_alter(&$form, &$form_state) {
  $form['introduction'] = array(
    '#markup' => code_content('module_name_a', 'form_name_introduction'),
  );
}

This will solve the issue of collecting all code text in one place (actually several places, one for each module implementing this hook.)

The git diffs would look a lot nicer. Why should you see diffs inside code when all you did was change a word in some text? Investigating commits makes it easier to see if the commit changed logic or text. For me this would be great DX.

Now for the editing part. The code_content module could provide an admin interface showing all code_content text grouped by modules in tabs or whatever.

If you need more control, each code_content item could include required permissions for editing that particular item.

$code_content_across_modules = array(
  'module_name_a' => array(
    'form_name_introduction' => array(
      'text' => t('bla bla'),
      'edit_permission' => array(
        'custom permission',
      ),
    ),
    'custom_text_a' => array(
      'text' => t('yak yak'),
      'edit_permission' => array(
        'edit article content'
      ),
    ),
  ),
);

You could go bananas now and introduce not only permissions for editing but for reading as well. Some times you want to show text in a form only for certain roles. This is not a big use case for me right now, but I can easily see this implemented in the code_content module anyway.

This module could also show you which text items that aren’t translated (big use case for me) and provide a link to the string translation page for convenience.

Or, if you want to go crazy (I’m tempted), do something like this:

$code_content_across_modules = array(
  'module_name_a' => array(
    'form_name_introduction' => array(
      'text' => array(
        LANGUAGE_NONE => 'bla bla',
        'fr' => 'Bleaux Bleaux',
        'de' => 'Blach Blach',
        'sv' => 'Blork Blark',
      ),
      'edit_permission' => array(
        'custom permission',
      ),
    ),
  ),
);

and let translations be handled in code as well. This would require mechanisms to import translations etc. It might be hard, but something I would really, really like to see. When editing code_content items in the interface, the translations needs to be updated of course. I would think of it as a huge win if the client could edit and translate several texts at once in one large form. The string translation interface requires lots of clicking when all you want is translate newly created text from (often) a newly added module.

Perhaps we need to implement ctools exportables so all this is portable in code(!).

I got this idea and ran with it before I could come up with different solutions to the initial problem of handling text in code. I would very much like thoughts on the problem in general and alternative solutions in particular.

I would very much like to start working on this module. If anyone wants to join me, they are very welcome. I would like to get some input though before I commit a lot of time to this. Maybe I’m thinking about this the wrong way, or duplicating efforts done elsewhere.

How do you handle text in code?

How would you like a module like this?

Drupal version: 


Source: https://www.drupal.org/taxonomy/term/2/feed