WordPress - 以编程方式在页面中插入 Elementor 小部件

Vpp*_*Man 2 wordpress elementor wordpress-plugin-creation

我在我的 WordPress 网站上安装了 Elementor Pro,我正在编写一个自定义插件,该插件将执行一些操作并以编程方式创建一个新页面。我能够创建页面,但问题是,我想以编程方式在这个新页面中插入一个 Elementor 小部件。

我已经联系了 Elementor 支持,看看他们是否对我有任何意见。但他们的回答是:

尽管我很想为您提供帮助,但自定义代码/片段或任何指导超出了我们的支持范围,因为我们仅提供对 Elementor 现有功能的支持。

那么无论如何我可以通过代码实现这一点,我的意思是将特定的 Elementor Widget 插入页面?

Akh*_*ran 5

这不会是最好的解决方案,但我会解释我是如何找到解决方法的。

对我而言,我尝试监控 WordPress 网站的数据库,以查看使用 Elementor 创建新页面时发生的所有更改。我监控的表是:wp_postswp_postmeta。请注意wp_,如果您在安装 WordPress 时选择了不同的前缀,则前缀可能与您的情况不同。

创建页面时,wp_posts表中会插入一个post_type值为的新行page。记下那个post_id值(为了解释起见,让post_idbe 123)。

此页面的元数据将存储在wp_postmeta表中,这是 Elementor 存储与每个页面或帖子相关的数据的地方。使用 phpMyAdmin,我访问了该表并搜索了具有post_id = 123(这里123是页面的 ID)的记录。您可以像这样使用phpMyAdmin的搜索选项卡(选择wp_postmeta表格后):

在此处输入图片说明

或者,可以在phpMyAdmin的SQL 选项卡中运行这样的查询:

SELECT * FROM `wp_postmeta` WHERE `post_id` = 123
Run Code Online (Sandbox Code Playgroud)

现在您将看到附加到我们页面的所有元数据(带有 ID 123)。

在此处输入图片说明

就我而言,我之前已经在 Elementor 中为此页面 (ID 123)添加了一个小部件。因此,正如您在上图中所看到的,它附加了一些元数据。

_wp_page_template = page-fullwidth.php是因为我Full Width为我的页面的模板属性选择了:

在此处输入图片说明

似乎需要这两个值才能理解页面是使用 Elementor 创建的:

_elementor_edit_mode = builder
_elementor_template_type = wp-page
Run Code Online (Sandbox Code Playgroud)

所以我们绝对需要那个。然后对于 Elementor 版本值:

_elementor_version = 2.9.14
_elementor_pro_version = 2.10.3
Run Code Online (Sandbox Code Playgroud)

您可以使用常量:(ELEMENTOR_VERSION如果您有免费版本的 Elementor 插件)和ELEMENTOR_PRO_VERSION(如果您有专业版插件)。如果您安装了 Elementor 插件的相应版本(免费或专业版),则这些常量已经定义。

然后是重要的部分,Widget 的数据和布局相关的数据似乎存储在 :_elementor_data_elementor_controls_usagemetakeys 中。

的值_elementor_data似乎是一个 JSON 字符串。所以你可以使用任何在线 JSON 解析器来查看它有什么。在我的案例中的价值是这样的:

[{"id":"2e0569b","elType":"section","settings":[],"elements":[{"id":"e2a6dbb","elType":"column","settings":{"_column_size":100,"_inline_size":null},"elements":[{"id":"441552a","elType":"widget","settings":{"tag_ids":"21"},"elements":[],"widgetType":"listings_grid_new"}],"isInner":false}],"isInner":false}]
Run Code Online (Sandbox Code Playgroud)

解析后,它看起来像这样:

[
  {
    "id": "2e0569b",
    "elType": "section",
    "settings": [],
    "elements": [
      {
        "id": "e2a6dbb",
        "elType": "column",
        "settings": {
          "_column_size": 100,
          "_inline_size": null
        },
        "elements": [
          {
            "id": "441552a",
            "elType": "widget",
            "settings": {
              "tag_ids": "21"
            },
            "elements": [],
            "widgetType": "listings_grid_new"
          }
        ],
        "isInner": false
      }
    ],
    "isInner": false
  }
]
Run Code Online (Sandbox Code Playgroud)

由于我之前将该 Widget 添加到我的页面,并将 Tag ID 输入框的值设置为21(通过 Elementor Editor),我知道我必须传递新值来替换该21.

然后是元_elementor_controls_usage密钥。它的价值是这样的:

a:3:{s:17:"listings_grid_new";a:3:{s:5:"count";i:1;s:15:"control_percent";i:1;s:8:"controls";a:1:{s:7:"content";a:1:{s:13:"section_query";a:2:{s:7:"loc_ids";i:1;s:7:"tag_ids";i:1;}}}}s:6:"column";a:3:{s:5:"count";i:1;s:15:"control_percent";i:0;s:8:"controls";a:1:{s:6:"layout";a:1:{s:6:"layout";a:1:{s:12:"_inline_size";i:1;}}}}s:7:"section";a:3:{s:5:"count";i:1;s:15:"control_percent";i:0;s:8:"controls";a:0:{}}}
Run Code Online (Sandbox Code Playgroud)

是序列化数据。您可以使用任何在线工具来反序列化该数据。这是我的反序列化后的样子:

array (
  'listings_grid_new' => 
  array (
    'count' => 1,
    'control_percent' => 1,
    'controls' => 
    array (
      'content' => 
      array (
        'section_query' => 
        array (
          'loc_ids' => 1,
          'tag_ids' => 1,
        ),
      ),
    ),
  ),
  'column' => 
  array (
    'count' => 1,
    'control_percent' => 0,
    'controls' => 
    array (
      'layout' => 
      array (
        'layout' => 
        array (
          '_inline_size' => 1,
        ),
      ),
    ),
  ),
  'section' => 
  array (
    'count' => 1,
    'control_percent' => 0,
    'controls' => 
    array (
    ),
  ),
)
Run Code Online (Sandbox Code Playgroud)

它看起来基本上是布局相关的数据。所以我想不要对这个值做任何编辑,直接使用它。


让我们做最后的事情

为了创建页面,我使用了wp_insert_post()方法,它page_id在插入后返回新的。创建页面后,我使用了update_post_meta()方法,传递了它page_id并附加了元数据。

我的最终代码如下所示:

//-- set the new page arguments
$new_page_args = array(
    'post_type'     => 'page',              //-- this is of type 'page'
    'post_title'    => 'My Dynamic Page',   //-- title of the page              
    'post_status'   => 'publish'            //-- publish the page
);

//-- insert the page
$new_page_id = wp_insert_post( $new_page_args );

if( is_wp_error( $new_page_id ) )
{
    echo 'Unable to create the page!';        
    die;
}

if( defined( 'ELEMENTOR_VERSION' ) )    //-- if FREE version of Elementor plugin is installed
{
    update_post_meta( $new_page_id, '_elementor_version', ELEMENTOR_VERSION );
}

if( defined( 'ELEMENTOR_PRO_VERSION' ) )    //-- if PRO version of Elementor plugin is installed
{
    update_post_meta( $new_page_id, '_elementor_pro_version', ELEMENTOR_PRO_VERSION );
}

update_post_meta( $new_page_id, '_wp_page_template', 'page-fullwidth.php' );    //-- for using full width template

//-- for Elementor
update_post_meta( $new_page_id, '_elementor_edit_mode', 'builder' );
update_post_meta( $new_page_id, '_elementor_template_type', 'wp-page' );

//-- Elementor layout
update_post_meta( $new_page_id, '_elementor_controls_usage', 'a:3:{s:17:"listings_grid_new";a:3:{s:5:"count";i:1;s:15:"control_percent";i:1;s:8:"controls";a:1:{s:7:"content";a:1:{s:13:"section_query";a:2:{s:7:"loc_ids";i:1;s:7:"tag_ids";i:1;}}}}s:6:"column";a:3:{s:5:"count";i:1;s:15:"control_percent";i:0;s:8:"controls";a:1:{s:6:"layout";a:1:{s:6:"layout";a:1:{s:12:"_inline_size";i:1;}}}}s:7:"section";a:3:{s:5:"count";i:1;s:15:"control_percent";i:0;s:8:"controls";a:0:{}}}' );

$tag_id = '56'; //-- new value
//-- Elementor data ( I have injected the new $tag_id value in the string )
update_post_meta( $new_page_id, '_elementor_data', '[{"id":"2e0569b","elType":"section","settings":[],"elements":[{"id":"e2a6dbb","elType":"column","settings":{"_column_size":100,"_inline_size":null},"elements":[{"id":"441552a","elType":"widget","settings":{"tag_ids":"'. $tag_id .'"},"elements":[],"widgetType":"listings_grid_new"}],"isInner":false}],"isInner":false}]' );
Run Code Online (Sandbox Code Playgroud)

请记住,这不是完美的解决方案。但我解释了我是如何找到解决这个问题的方法的。

也许其他人会发布更好的解决方案。;)