Carbon-fields: Option to save complex fields as one postmeta field

Created on 28 Jun 2016  路  12Comments  路  Source: htmlburger/carbon-fields

When using complex fields excessively, they soon generate a vast number of postmeta UPDATE-queries when saved in the backend. This makes saving slow and consumes a lot of resources. On the other hand retrieving sub-fields of complex fields is rarely needing. Mostly all data has to be selected and looped through.
One approach is to save all data in a serialized way in one postmeta field per complex field either by adding a saving-type-option ("one field" vs. "per sub field") to the complex type or adding a new field type.

(Remark: We use complex fields for storing page content modules. E.g. 30 modules 谩 10 fields each create 300 field operations.)

Most helpful comment

@m1r0 Hi there, is there any progress being made with this? I'm looking for an alternative to ACF and one of the main reasons is that I really don't like how they save every subfield in a separate row.

All 12 comments

It might be beneficial if the saved data is stored in the same way it is retrieved by carbon_get_post_meta() so there is no restructuring on every retrieval.

Hi @georgknabl,

You've got a good point there, but this is a core decision.

We might consider changing the complex structure and optimize the field as a whole in a future major version.

You can look into DataStore mechanism of saving complex values if you need a quicker solution:
https://github.com/htmlburger/carbon-fields/tree/master/core/Datastore

Also any contributions related to this issue are welcomed. Thanks.

I'm already working on an implementation to support that feature but realized I have to change Complex_Field.php in the core. I will file a pull request once this is ready.

That feature is not solely solvable in Datastore since the subfields are saved recursively. In my solution I might use the same datastore and restructure data on save and load to/from a field level. This might not be the structurally best approach, but given your planned refactoring it seems appropriate. The alternative might only be a deeper structured approach and this is not my decision to make.

I will let you know as soon as I'm done.

I hope you like the improvement and accept my pull request. :-)

@m1r0 Could you give me some information on when this will be integrated?
I'm currently facing a problem with many post meta fields, which would be solved by this.

@en-davidh Its hard to say, because its something that we want to solve on a more abstract level. I mean not only the Complex Field is facing this problem, the Map field also generates multiple meta keys and we don't know what fields we will have in the future ( gallery field? ). So we prefer to invest time in something that will be more future proof than a quick solution. Hope you understand.

P.S. You can try @georgknabl's implementation

Hey @georgknabl, thanks for the implementation, it looks neat! I think some people will find it useful until we decide what our approach will be.

For now we are thinking of a more global solution for this problem. This may require changing some fields but we hope it will be for the better.

@m1r0: Sadly, since now we have to stay on the fork for quite some time. But I'm looking forward to it.
If I may add a suggestions concerning that issue: It makes generating generic field data difficult in some cases if you have to specify an output format (e.g. "map" in carbon_get_post_meta($id, $name, 'map');) because the calling function has to know the format. That information is not always available. Here is my suggestion to fix this: The format information (default, complex, map etc.) is already available in the field definition so there is no need to specify it in the output function. This function should lookup the definition and output a specified format for each type. Pretty much as ACF does that in https://www.advancedcustomfields.com/resources/google-map/ where the output is an array with lat and lng.

@georgknabl Great suggestion (as always!), it makes great sense for the output format to be defined inside the field. We will definitely prioritize fixing this issue, so thanks for pointing it out.

The issue has been documented here.

@m1r0 Hi there, is there any progress being made with this? I'm looking for an alternative to ACF and one of the main reasons is that I really don't like how they save every subfield in a separate row.

At this time, there are no plans to implement this in core so I'll be closing this ticket.

Note that you can still achieve this using a custom Datastore (which extends Post_Meta_Datastore, for example) and assigning it to the desired fields using ->set_datastore().
Here's our Serialized_Theme_Options_Datastore example from the documentation which you can adapt to your needs:
https://carbonfields.net/docs/guides-serialized-datastore/?crb_version=2-0-0

I've also been on the hunt for a way to store post meta in a single field. It makes calling and using that data much easier (especially outside the loop). I couldn't seem easily get carbon post meta outside the loop and wanted a way for this data to be available and easily accessible even if Carbon Fields were disabled.

Using the Serialized_Theme_Options_Datastore, I created Serialized_Post_Meta_Datastore. I really appreciate someone who knows Carbon Fields well taking a look and letting me know whether this seems robust enough. It seems to be working fine, but I don't want to find that something is amiss after I implement it across a number of sites. Thanks!

Was this page helpful?
0 / 5 - 0 ratings