3

我在我的 WordPress 网站上安装了 Elementor Pro,我正在编写一个自定义插件,它会做一些事情并以编程方式创建一个新页面。我能够创建页面,但问题是,我想以编程方式在这个新页面中插入一个 Elementor Widget。

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

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

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

4

1 回答 1

7

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

对我来说,我尝试监视我的 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的Searchwp_postmeta选项卡(选择表格后),如下所示:

在此处输入图像描述

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

SELECT * FROM `wp_postmeta` WHERE `post_id` = 123

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

在此处输入图像描述

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

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

在此处输入图像描述

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

_elementor_edit_mode = builder
_elementor_template_type = wp-page

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

_elementor_version = 2.9.14
_elementor_pro_version = 2.10.3

您可以使用常量:(ELEMENTOR_VERSION如果您有 Elementor 插件的免费版本)和ELEMENTOR_PRO_VERSION(如果您有 Pro 版插件)。如果您安装了 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}]

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

[
  {
    "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
  }
]

由于我之前将该 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:{}}}

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

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 (
    ),
  ),
)

它看起来基本上是布局相关数据。所以我想不做任何编辑这个值,并按原样使用它。


让我们做最后一件事

为了创建页面,我使用了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}]' );

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

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

于 2020-09-18T19:40:29.023 回答