1 block.module block_custom_block_save(array $edit, $delta = NULL, $langcode = NULL)

Saves a user-created block in a config file.


array $edit: Associative array of fields to save. Array keys:

  • delta: The machine name for the block
  • info: The administrative title for the block.
  • description: The administrative description for the block.
  • title: The block title (optional, since layouts have their own title field)
  • body: Associative array of body value and format. Array keys:
    • value: Block contents.
    • format: Filter ID of the filter format for the body.
  • default_langcode: The source translation language code string.
  • langcode: If specified, the values for info, description, title, and body will be saved as a translation of the source language.

string|NULL $delta: Machine name of the block to save, comprised of lower-case letters, numbers, and underscores. Note: NULL values are still accepted when creating new nodes to maintain API contiguity.

$langcode: The language code for the block. If set, only the translation is saved.


core/modules/block/block.module, line 374
Provides the ability to create reusable custom blocks.


function block_custom_block_save(array $edit, $delta = NULL, $langcode = NULL) {
  $delta = $delta ? $delta : preg_replace('/[^a-z0-9_]+/', '_', strtolower($edit['info']));
  $block = block_custom_block_load($delta);
  if (!$block) {
    $block = array(
      'delta' => $delta,
      'info' => '',
      'title' => '',
      'description' => '',
      'body' => array('value' => '', 'format' => ''),
      'default_langcode' => LANGUAGE_NONE,

  // If langcode is NULL or the default (source) language code, save into the
  // main configuration array.
  if ($langcode === NULL || $langcode === $block['default_langcode']) {
    // Clean up any copies of the translation, in the event the source had
    // changed.
    if ($langcode && isset($block['translations'][$langcode])) {
    // Store the main block configuration.
    foreach (array('info', 'description', 'title', 'body', 'default_langcode') as $key) {
      if (isset($edit[$key])) {
        $block[$key] = $edit[$key];
  // Store the translation values.
  elseif ($langcode) {
    foreach (array('info', 'description', 'title', 'body') as $key) {
      $block['translations'][$langcode][$key] = $edit[$key];

  $config = config('block.custom.' . $delta);

  // Save each file as permanent, preventing it from being deleted. The same
  // process is used in Layout::save(), but that only applies to non-reusable
  // blocks (BlockText objects). If a block has been marked reusable, the files
  // are immediately marked as permanent.
  // File usages are not currently removed for custom blocks.
  // See https://github.com/backdrop/backdrop-issues/issues/2137.
  $fids = filter_parse_file_fids($edit['body']['value']);
  $files = file_load_multiple($fids);
  foreach ($files as $fid => $file) {
    if ((int) ($file && $file->status) !== FILE_STATUS_PERMANENT) {
      // This makes the file "self-referencing", so it will never be deleted.
      file_usage_add($file, 'file', 'file', $file->fid);

  // Reset the static cache on the block list so this block is picked up.