Crocoblock / suggestions

The suggestions for CrocoBlock project
191 stars 78 forks source link

JetEngine v3.5.0 Beta #7533

Closed MjHead closed 1 week ago

MjHead commented 1 month ago

Hi,

We are almost getting ready to release JetEngine v3.5.0 and we would like to ask you to help us test JetEngine v3.5.0 Beta. This is one of biggest JetEngine updates in last 2-3 years, so your feedback for this release even more important than usual!

You can download beta version from your Crocoblock account.

Please note that is a beta version, not stable release, so its not ready to use on production websites!

Custom Meta Storage

Feature Overview

This feature allows storing standard WP meta fields in a separate table instead of the standard postmeta table. Currently, this feature is only available for posts and is marked as Beta, as it needs to be tested on real client projects to understand whether we have everything covered. Later, it can be expanded to users and taxonomies. Only meta fields added via the CPT interface will be stored in the custom meta storage. As of now, we can't implement storing meta fields in a custom table for the Meta Boxes tool. The reason is that the new functionality is closely tied to the parent object - the CPT for which the fields are added, while meta fields from Meta Boxes can be added to any entity (CPT, user, etc.) and not just one but several entities simultaneously.

How It Works

In the General Settings section of the CPT settings, a toggle for Custom Meta Storage (Beta) has been added. When this toggle is enabled, a block with the name of the custom table that will be created for this CPT will appear, along with a warning stating that renaming columns will result in the deletion of their data.

image

When adding/updating a CPT, the plugin will attempt to create this table. If such a table already exists in the database (possibly the name matches a table from another plugin), an error will be returned.

All meta fields created for this CPT in this interface will be added as columns to the table.

image image

You can then use standard WP functions to work with meta fields:

JetEngine will automatically handle queries related to this CPT and the necessary fields through the custom meta storage.

Regarding the rest, the CPT continues to work as usual - it can have other meta fields added by other plugins, which will be stored in the standard postmeta table. Additionally, in WP_Query, you can combine fields from the custom table and standard meta fields within meta_query. But actually, it's better to avoid this, as in this case all gains in query speed will be lost.

Compatibility with WPML and Similar Plugins

In theory, posts with translations are the same posts from the same CPT, and translations of meta fields are also stored in the standard postmeta table. As I mentioned earlier, this functionality works at the level of the standard WP API, so if translation plugins use the same API - update_post_meta, get_post_meta, delete_post_meta - there should be no problems. But let's see how it will work in real life.

Important Note

When enabling Custom Meta Storage for a CPT with existing content, meta fields for already created posts are not automatically transferred. If you manually re-save an existing post in the editor afterward, the meta field values will be saved in the custom table. The old values will not be deleted from the postmeta table. But be awarded that, as this functionality is still in its early stages, and performing such operations on a client's database at this stage would be very risky.

JetEngine Components

Basic Logic

The Component allows a web developer creating a site for a client to add custom widgets supported by JetEngine to the site. The developer can use these widgets while working on the site, and the client can also add them to new pages, modifying only the parameters allowed by the developer in the component settings. Creating components is similar to creating standard listing items and is done in the same interface.

image

The Difference Between Components and Templates

A template has a fixed design and fixed content. With components, however, the web developer creating the component can make certain parts dynamic, so, for example, texts, images, or the color of specific elements can be changed. For the end user, editing these elements will look the same as configuring any static widget:

image

The Difference Between Components and Standard Listing Items

Listing items also have dynamic elements that can have different values for different items within a Listing Grid. However, the user cannot directly control the settings of each item; they can do so only through a global query that manages the data for the entire listing. In the case of components, the user can individually configure each control of every component.

Workflow for Creating and Using Components

Step 1. Create a Static Layout.

We’ll start with this to better understand the overall logic. Let's imagine a task: we need to create a Services block.

image

This is static information; we won't create a separate CPT or CCT for it. One Service Card = a Component, so you can add as many cards to the page as needed.

Let's create a new component.

image

Inside it, recreate the layout of one card from the task requirements.

image

If we use the component in this form, it will work like a regular template, displaying the same information wherever the user uses it. However, we need to make certain elements of it to be dynamic.

Step 2. Add Controls.

Identify which elements need to be dynamic:

image
  1. Service icon/image.
  2. Service title.
  3. Service description.
  4. Link to a dedicated service landing page.

Add these controls using the Component settings:

image image

Adding controls has the same principle regardless of where you create the component - whether in Elementor, Bricks, Block Editor, or Timber/Twig editor. Each editor has its own UI for editing controls, suitable for its capabilities. Additionally, regardless of the editor used to create the component, the component settings can be edited in a unified interface from the components list page.

image image

Step 3. Applying Controls to the Corresponding Elements.

You can assign control values to the corresponding element in several ways:

In the example, we built the initial layout with Elementor widgets, so here we will apply Dynamic Tags for all controls. In real life, you can use the tools most appropriate for the situation.

So, let's assign the corresponding Dynamic Tags to the relevant elements:

image image image image

In the same way, you can add style controls. Currently, only color controls are available. For Elementor and Bricks, style controls are added to the corresponding elements similarly to content controls through Dynamic Tags/Tokens. In the case of Timber/Twig and Block components, specify the styles directly in the component settings using custom CSS with CSS variables.

Example for Timber/Twig

image image image

Example for Block Editor

image image

Step 4. Adding Components to Pages

That's it. You can now use the component. It will be available to all editors/builders on your site under the name you gave to it.

image

In the page builders/editor UI, you will see the controls you set in the Component settings:

image

Conditional Rendering

You can use the controls for components in combination with the Dynamic Visibility module to render certain elements of the component depending on the selected control value or to hide elements if the control value is empty. For example, in the component we've created above, you can display a link to the Service landing page only if the user specifies a URL for the "Service Link" field in the settings.

image image

Timber/Twig Components

The greatest advantages of components appear in combination with the Timber/Twig editor because you get the cleanest HTML output and the fastest component rendering on the front end. Additionally, you have no layout limitations and can create the most creative components. Finally, you can use HTML and CSS from any external resources and just insert the corresponding controls where they are required.

Let's look at an example similar to the one above with Elementor. Here, I found a ready-made HTML + CSS component with elements that are not easy (or sometimes impossible) to reproduce in the editor/builder.

image

On hover, this component slightly changes its layout.

image

When using Timber/Twig components, I can simply copy the code from the example and insert the corresponding controls where they are required.

image

Here, we will go even further and add controls for color, using CSS variables in the component styles.

image

As a result, we get a highly versatile widget for Elementor, Block Editor, or Bricks.

image

In Timber/Twig components, conditional rendering of elements can also be used. Since you can write conditions directly in the HTML, we have broader possibilities for configuring different layout options:

image image

Component Context

The Context option for Component allows you to change the Current Object for the entire component. Let's see how to use it in practice, with an example involving Users.

Imagine we have a component with User information. It displays some user data using the classic Dynamic widgets:

image

I am not specifying the context in this case. By default, for users, I will always get information about the current user.

Next, I want to use the same component in different places:

If I just add this component to these places, I will get only the current user's data in all cases. But by changing the component's context, I can get the desired result:

Why couldn't we just set the context inside the component? Because then you wouldn't be able to use the same component in different places, as the context would be rigidly set for each widget.

Repeater field new storage type - meta field for each sub-field

The new Save as separate fields option has been added to the repeater field https://prnt.sc/W7RNlHly74VH.
When this option is enabled, the repeater fields will be saved in the database as separate fields https://prnt.sc/NFdh_kRksixQ. The field key will be formed from repeater-name and sub-field-name using _ => repeater-name_sub-field-name.

We decided against saving in the way ACF does (repeater_name_N_sub_field_name) because WordPress already has the capability to store multiple fields with the same keys and has its own API for retrieving these results. These are the functions get_post_meta, get_term_meta, get_user_meta. You just need to set the 3rd parameter $is_single to false, and the result will be an array of all values.

$res1 = get_post_meta( $post_id, 'repeater-name_sub-field-name', false );
$res2 = get_term_meta( $term_id, 'repeater-name_sub-field-name', false );
$res3 = get_user_meta( $user_id, 'repeater-name_sub-field-name', false );

This approach also makes it easier to work with queries and filters. Additionally, we have retained the option to save the repeater value as a serialized array in the database https://prnt.sc/86tiSqqAPghO, so that all values in the array can be quickly retrieved with a single query.

Note: This feature is currently available only for posts, terms, and users. It may also be implemented later for custom content types (CCT), but it will require adding an additional table in the database.

Merged Query Query Type

The new query type has been added: Merged Query

image image

Using this query type, we can combine the results of multiple queries into one and use this combined query to display the merged results in a single listing. Currently, only queries of the same type can be merged, i.e., posts with posts, terms with terms, etc.

Settings

Logic and Limitations

This is a query type designed for solving specific tasks and, due to this specificity, it has certain limitations:

Please leave your feedback and any found bugs or issues in the comments below

Joliamendi commented 1 month ago

Great update. But still we can't use query builder for elementor loop builder right?

MjHead commented 1 month ago

Great update. But still we can't use query builder for elementor loop builder right?

@Joliamendi I recommend use a Listing Grid widget when you need to output the data from the Query Builder. Not sure this integration will be added soon, because such integrations usually generates a lot of compatibility issues. We faced it on Bricks loop example. So we'll add such integration in the future only when we'll be confident that it's won't be broken by some unusual user case.

nicolasprigent commented 1 month ago

Components is something that I had in mind for quite some time (kind of similar thing than Master Properties in After Effect for the ones that need some comparison). That's such a great update, and seems really nicely executed !

nicolasprigent commented 1 month ago

I see so much potential in components, I'm so happy with this update. For example, combined with dynamic visibiliy, I could have all my elementor forms in just one component, and the component would have an option to switch between every avalaible forms. And I could then edit all the forms in one place!

Lonsdale201 commented 1 month ago

I like the component solution. Especially the different way you have approached it compared to the widget maker plugins. Simple, but great. My only gripe is that the style settings are limited. But actually that's an understandable thing. Fortunately, it carries over the style set within the component, so maybe it's not so much of a problem that you can't set typography in it.

Question is, when it will be released, will there be a way to import and export these components, with the built-in mode, as other jetengine specific stuff can be exported/imported?

Joliamendi commented 1 month ago

Great update. But still we can't use query builder for elementor loop builder right?

@Joliamendi I recommend use a Listing Grid widget when you need to output the data from the Query Builder. Not sure this integration will be added soon, because such integrations usually generates a lot of compatibility issues. We faced it on Bricks loop example. So we'll add such integration in the future only when we'll be confident that it's won't be broken by some unusual user case.

Yes you are right. But elementor Loop builder supports custom query (query id). Jet engine query builder, on the other hand, provides an id for each query. But when you put query id in elementor loop, it doesn't work.

Is this lack of query support an elementor problem or should it be developed in jet engine as you said?

MjHead commented 1 month ago

@Lonsdale201 at first stage we'll add compatibility with Skins import/export in JetEngine dashboard

Lonsdale201 commented 1 month ago

@Lonsdale201 at first stage we'll add compatibility with Skins import/export in JetEngine dashboard

Exactly what I mean, ty :)

Gio76 commented 1 month ago

I'm excited about the new Custom Meta Storage feature in this beta release. However, I have a question about the naming conventions for Meta Fields.

According to the notes for the Name ID, it **should contain only Latin letters, numbers, - or `` chars**_:

Screenshot 2024-05-24 at 22 57 28

In my case, I have 6 different Custom Post Types (CPTs), each with 70 Meta Fields, and all the ID naming was done using -. When I activate the Custom Meta Storage option, I see an error message indicating that I need to use _ instead of -:

Screenshot 2024-05-24 at 22 57 40

This poses a significant challenge for me because I have thousands of listings already entered. Updating all the names, dynamic visibility options, listings, single page listings, and the query builder would be a daunting task.

Moreover, changing a meta field name wipes all the previous data associated with it, which means I would have to re-enter all the actual listings.

Given this situation, I'm unsure where to start to make the necessary updates. Do you have any suggestions on how to handle this transition efficiently without losing data?

hvrddrive commented 1 month ago

This is awesome! Please please add support for Custom Content Type with the repeater separate storage option. This is exactly what I have been looking for especially since I use a ton of custom content types and advanced SQL queries. Would be such a game changer and would solve many issue I run into with repeaters! Totally okay with it making another database table. @MjHead

MjHead commented 1 month ago

@Gio76 I definitely don't recommend to enable Custom storage option, especially on such amount of data. Please note, that the Custom meta storage toggle is marked as Beta, and it keep this mark for some time even after JetEngine 3.5.0 stable release. We tested it on a large count of different setups, but any number of tests will cover 100% user cases, so as for now the best option will be use Custom meta storage only for a new projects

MjHead commented 1 month ago

@hvrddrive it will cause a lot of compatibility issues, so we'll take a deeper look into this only after make sure the functionality itself works as expected for cases which it could cover now

hello-floats commented 3 weeks ago

Exciting.

When enabling Custom Meta Storage for a CPT with existing content, meta fields for already created posts are not automatically transferred. If you manually re-save an existing post in the editor afterward, the meta field values will be saved in the custom table.

Does this mean if I have a directory (over 50,000 posts) using CCT and custom fields, I can simply use a custom function to re-save all posts, and all the fields would be copied to the Custom Meta Storage?

MjHead commented 2 weeks ago

@hello-floats Sorry for the delay. In theory - yes, but on practice - I don't recommend to do this on live website. As I said before - it's a new functionality, so some unexpected situations could appear. Ideally, if you have a staging website with full copy of content form the live one, you can try there.

tobisalami commented 1 week ago

@MjHead Hi... Thanks a lot for this update. It can be a bit manual to add the 'Select' control type settings of the Components as defined (One option per line. Split label and value with ::, for example - red::Red).

Can an option be added to fetch a Query Builder query or Glossary? In the case of the query builder query, we'll need to define the name and value field to be retrieved from the query. This will help to ensure that dynamic values can also be called within the components.

MjHead commented 1 week ago

@tobisalami at the moment only static options lists are allowed, but we'll take a look into this in the future