Hi,

Here's the use case:
I have a content type with two fields: Start Year and End Year which I want them to be just integers and not going to use the Date field.

I want to create just one integer field and clone it so its settings can be cloned and use in the same content type.

I realized that Drupal doesn't come with this in the core. Is there a possibility for this module to achieve it?

Many thanks!!

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

joachim’s picture

Interesting idea.

Though the current UI doesn't clone fields, but instances.
And AFAIK you can't put a field twice on one bundle -- for starters, the $field['bundles'] data array isn't constructed in a way that would support it.

So to allow this we'd need a new tab for cloning the entire field. You'd need a form element to specify a new field name too.

As it says on the project page -- patches welcome :D

kenyangzj’s picture

Yes, I agreed. After some research, the "CLONE" function actually mean:
1. Create a new field with the same setting
2. Create an instance of this new field
3. Attach the new field instance to the bundle

I would love to contribute a patch when I have time to do it :p

Cheers!

Yuri’s picture

Very much interested in this too. I use nodes as being long multistep webforms, and reusing the same field is a must.

joachim’s picture

> I use nodes as being long multistep webforms,

Use webform. Nodes are not meant to be webforms...

> and reusing the same field is a must.

That's not doable. At best we can clone an entire field, but we can't make new instances of it.

wizonesolutions’s picture

+1 for being able to clone the configuration for a field but give it a new name. In my case, I have a few page template content types that are similar but which may diverge in the future. We don't want to share the fields so we have flexibility if/when this happens.

This is the meaning of "clone fields" to me, but right now maybe it should be called "bulk-attach fields."

wizonesolutions’s picture

Incidentally - what's the effort in making this patch, if you know? Trying to see if I can get it sponsored. To clone without attaching is a lot of new code needed or is there already code in place I could leverage/reuse?

wizonesolutions’s picture

Oh yeah, and for now a workaround is to export code with Bundle copy and then manually edit the code and change the field names. Make sure none of the new ones are longer than 32 characters to avoid import errors, and make sure the content type they'll be imported into is correct.

joachim’s picture

You can do this with drush BTW.

> Incidentally - what's the effort in making this patch, if you know? Trying to see if I can get it sponsored. To clone without attaching is a lot of new code needed or is there already code in place I could leverage/reuse?

You'd need:

- a new tab on the field
- a new admin form that asks for the new name
- a form submit handler that does the cloning. That's just a case of getting the field definition, changing the field name, saving that, then doing the same for the field instance definition.

bharata’s picture

Has any progress been made with this Field Clone functionality? Seems like a very natural and very awesome addition to "add new field" and "add existing field". Also a serious time saver.

Wish I were a coder..... ;-(

Any help or pointers welcom ;-)

mstrelan’s picture

If you want to do this via code (eg, via /devel/php) here are some pointers.

Load the existing field definition and field instance with field_info_field() and field_info_instance().

Example:

$field = field_info_field('field_my_field');
$instance = field_info_instance('node', 'field_my_field', 'my_node_type_eg_article');

Make modifications to the $field variable and call field_create_field(). Make sure you change the field name otherwise you won't be able to create the new field. Make modifications to the instance, probably just changing the field name to reflect the new field you created, and call field_create_instance().

Example:

$field['field_name'] = 'field_my_new_field';
$instance['field_name'] = 'field_my_new_field';
field_create_field($field);
field_create_instance($instance);

Please note these examples are untested.

benjamindamron’s picture

I can confirm #10 works like a charm

erikphanson’s picture

Issue summary: View changes

Did the ability to clone fields in the same content type make it into the module. Can't tell from the module description and this thread died out after some inconclusive patch talk? Would also be great to clone field groups in to the same content types.

joachim’s picture

Nope, this hasn't made it in yet

gbirch’s picture

For anyone looking at this issue (how to copy fields within a bundle), this module provides a very nice workaround.

Go to the "Export fields" sub-task on the Tools tab. Pick the fields and field groups you want to copy. Export the code. Edit the exported code in a text editor to change the field and group names using global search/replace. Tweak any other settings you want to tweak, but changing the field and group names is essential.

Now go to the "Import fields" sub-task, paste in your edited code, and import.

Worked like a charm for me and saved at least an hour of tedious, error-prone re-configuration. Kudos to joachim!

jryanj21’s picture

for #14 exporting code also export id's, and the id's are the same as the previous fields. Did that create a conflict for you?

gbirch’s picture

jryanj21: No, it did not. I believe that when you look at the import code, you'll find that it quite deliberately ignores the ids.

jryanj21’s picture

Thanks for the quick response gbirch. Yesterday I did this and it worked amazingly. I have a content type where I need 6 fields to show up again (up to 3 times) based upon if the user wants to submit an additional item. This saved a lot of time.

I'm also using conditional fields that uses dependencies on when these fields show up. No conflicts!

colan’s picture

Version: 7.x-1.x-dev » 8.x-1.x-dev

Moving to D8. (There's no code here anyway.)

I'm currently exploring #2717319: Provide better default configuration when re-using an existing field and the corresponding sandbox, but getting a solution in this module makes sense as well.

colan’s picture

Status: Active » Needs work
FileSize
5.26 KB

Here's what I've got so far. What still needs to be done:

  1. Implement FieldCloner->cloneFieldConfig() to set the new field name in the existing config, and then
  2. Create the new field with the new machine name.

The new instance can then be created.

Any feedback is welcome.

colan’s picture

Status: Needs work » Needs review
FileSize
18.72 KB
19.91 KB

The more I got into this, the less my plan above made sense. However, I eventually figured it out. Most of the work was already being done when cloning to different entity types; this just needed to be expanded to include the situation where we're cloning to different field names.

As expected, the form now has an additional field for entering the destination field ID, which defaults to the current field ID. However, this must be changed if cloning to the same bundle (which is now allowed). I've added documentation on the form explaining this.

As a bonus, I was able to redirect the browser back to the Manage Fields page after the cloning happens, which solves one of the @todos in the code.

colan’s picture

The form now checks for field names that are too long (leading to an Exception being thrown).

selwynpolit’s picture

colan Patch at #21 works great. Nice work!

selwynpolit’s picture

Status: Needs review » Reviewed & tested by the community
colan’s picture

joachim’s picture

Status: Reviewed & tested by the community » Fixed

Sorry for taking time to get to this patch. It looks a bit overwhelming to me as a maintainer, but I appreciate that it probably can't be broken down into smaller pieces and that a lot of the diff is churn caused by code moving around and changing its indentation. I don't have the time to run it through manual testing, so I'm trusting the reviews its had during its development and the final RTBC. Any other problems can come out from people testing the dev release ;)

Thanks @colan for all your work on this, and everyone else also who's commented and reviewed.

I particularly appreciate the attention to detail with form errors and the redirect!

joachim’s picture

Status: Fixed » Needs work

Urgh, except it doesn't apply any more.

colan’s picture

Here's a reroll.

Interdiff mostly failed:

colan@snake[Fri 17 16:29]% interdiff /tmp/field_tools-clone_fields_same_bundle-1350808-21.patch /tmp/field_tools-clone_fields_same_bundle-1350808-27.patch 
diff -u b/field_tools.services.yml b/field_tools.services.yml
--- b/field_tools.services.yml
+++ b/field_tools.services.yml
@@ -1,7 +1,7 @@
 services:
   field_tools.field_cloner:
     class: Drupal\field_tools\FieldCloner
-    arguments: ['@entity_type.manager', '@entity.query', '@module_handler', '@config.factory']
+    arguments: ['@entity_type.manager', '@module_handler', '@config.factory']
   field_tools.display_cloner:
     class: Drupal\field_tools\DisplayCloner
     arguments: ['@entity_type.manager', '@entity_field.manager', '@entity.query', '@module_handler']
2 out of 10 hunks FAILED -- saving rejects to file /tmp/interdiff-1.RD3jsh.rej
interdiff: Error applying patch1 to reconstructed file

git am --3way /tmp/field_tools-clone_fields_same_bundle-1350808-21.patch did most of the work, but it couldn't handle the missing service dependency, as one was removed. That part had to be done manually.

Works well in my tests. Would somebody else kindly try it?

star-szr’s picture

Rerolled again, only manual changes were t() to $this->t().

joelpittet’s picture

Status: Needs review » Needs work

This worked thanks for the patch, two things we had to do still to get it to work.

  1. In the browser: hack the disabled checkbox to be not disabled
  2. In the exported YAML, change the storage dependency in the cloned instance to the new field storage (or deleting the old field will delete the new instance)

🐑🐏