11

The configuration export feature of Drupal 8 would seem to be a very useful feature. However, I'm not sure I completely understand how it works.

For example, if I do a single export, choose "Content type" then select one of my content types, I would expect that export to contain a full description of that content type. But it doesn't contain any information about the fields in that content type. So if you wanted to export a content type configuration for use on another site, it doesn't seem possible to do that.

I'm not sure I understand the use of being to do Single exports if they don't contain all the required data for an entity. Am I missing something?

1

2 Answers 2

10

UPDATE

You might also try Drupal Console's drupal config:export:content:type command.

It's description says:

The config:export:content:type command Export a specific content type and their fields.


Content types and Fields are 2 separate configuration in Drupal 8, so if you want to export content type with fields you have to export all it's fields configurations too.

Features module might be helpful for grouping configurations, it's not stable yet, I haven't tried it but I think it might worth trying.

2
  • 1
    Thanks for the answer. I guess I'm surprised that the Content type export contains no info. about the fields at all, so if you wanted to do it singly you'd have to export each field manually.
    – James
    Feb 12, 2016 at 12:21
  • I thinks this works like that because if you change settings for 1 field you need to update 1 yml file specific for that field, not whole content type configuration. So there is less risk of conflicts and gives more flexibility.
    – otarza
    Feb 12, 2016 at 12:31
0

I've written a Python script (below) which exports a group of configuration items using drush. It may be useful in your case (it has been in my case). Usage:

export_config_group.py -s something -m foobar

This executes drush config-list, gets all the items whose name contains the term something, then saves them to modules/custom/foobar/config/install.

The script also adjusts the yml as follows:

  • removes the default_config_hash entry when it exists;
  • removes the uuid entry when it exists.

The script depends on ruamel.yaml to load and dump the configuration. Make sure you pip install it in advance.

import os
import argparse
import subprocess
import ruamel.yaml

MODULES_ROOT = "/var/www/html/dm/web/modules/custom"


def main():
    search_term, module, keep_uuid = parse_arguments()
    module_config_path = os.path.join(MODULES_ROOT, module, 'config/install')
    items = run_process(['drush', 'config-list']).splitlines()

    for item in items:
        if search_term in item:
            print "Config item:", item

            yml = run_process(['drush', 'config-get', item])
            new_yml = adjust_yml(yml, keep_uuid)
            full_path = os.path.join(module_config_path, item + '.yml')

            with open(full_path, 'w') as f:
                f.write(new_yml)


def parse_arguments():
    ap = argparse.ArgumentParser(description="Export config group.")
    ap.add_argument("-s", "--search", required=True, help="Search term")
    ap.add_argument("-m", "--module", required=True, help="Destination module")
    ap.add_argument("-u", "--uuid", help="Keep UUID",
                    action='store_true', default=False)
    args = ap.parse_args()
    return args.search, args.module, args.uuid


def run_process(params):
    process = subprocess.Popen(params, stdout=subprocess.PIPE)
    stdout, _ = process.communicate()
    return stdout


def adjust_yml(yml, keep_uuid):
    loader = ruamel.yaml.RoundTripLoader
    config = ruamel.yaml.load(yml, loader, preserve_quotes=True)

    remove_core_config_hash(config)

    if not keep_uuid:
        remove_uuid(config)

    dumper = Dumper = ruamel.yaml.RoundTripDumper
    return ruamel.yaml.dump(config, Dumper=dumper, indent=2, block_seq_indent=2)


def remove_core_config_hash(config):
    if '_core' in config:
        if 'default_config_hash' in config['_core']:
            config['_core'].pop('default_config_hash')

            # Also remove '_core' node if empty
            if not config['_core']:
                config.pop('_core')


def remove_uuid(config):
    if 'uuid' in config:
        config.pop('uuid')

if __name__ == "__main__":
    main()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.