WordPress - 在页面中通过程序添加Elementor小部件

5
我在我的WordPress网站上安装了Elementor Pro,我编写了一个自定义插件,可以做一些事情并且以编程方式创建新页面。我能够创建这个页面,但问题是,我想在这个新页面中以编程方式插入一个Elementor小部件。
我已经联系了Elementor支持团队,看看他们是否有任何建议。但是他们的回复是:
“尽管我很愿意为您提供帮助,但是对于此类自定义代码/片段或任何指导,我们的支持范围之外,因为我们仅为现有的Elementor功能提供支持。”
那么,是否有任何方法可以通过代码实现这一点,我的意思是将特定的Elementor小部件插入到页面中?
1个回答

7

以下不是最佳解决方案,但我将解释如何找到一个解决方法。

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

当您创建页面时,会在wp_posts表中插入一行新记录,其post_type值为page。记录下post_id值(为了举例说明,让post_id123)。

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

enter image description here

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

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

现在,您将看到与我们页面(ID为123)相关联的所有元数据。

enter image description here

在我的案例中,我已经在Elementor中添加了一个小部件到这个页面(ID为123)。因此,正如您在上面的图像中看到的那样,它有一些附加的元数据。

那个_wp_page_template=page-fullwidth.php是因为我选择了全宽度作为我的页面的模板属性

enter image description here

这两个值似乎是必需的,以使其了解该页面是使用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(如果你使用的是Elementor插件的专业版)。如果你已经安装了相应版本(免费或专业版)的Elementor插件,那么这些常量已经被预定义。
接下来重要的部分是关于小部件数据和布局相关的数据存储在元键_elementor_data_elementor_controls_usage中。 _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
  }
]

早先在我的页面中添加了那个小部件,并通过 Elementor 编辑器将标签 ID 输入框设置为值 21,我明白我需要传递新的值来替换那个 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}]' );

请记住,这不是完美的解决方案。但我解释了我是如何想出一个解决该问题的变通方法。

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


是的,你的解决方案有效,但在我的情况下,我得到了一个混乱的页面设计,所以经过大量研究,我发现更新meta _elementor_data存在问题。因此,只需将wp_json_encode()函数添加到element_data中即可。例如:$_elementor_data ='[{"id":"2e0569b","elType":"s...'; //字符串格式的elementor数据 $json_value = wp_json_encode( $_elementor_data ); //将字符串数据编码为JSON,并进行一些健全性检查 $json_value = trim($json_value,'"'); //必要时删除引号 update_post_meta( $new_page_id, $_elementor_data );就这样! - Shebaz
干得不错,但是玩内部太冒险了。这个解决方案容易受到未来 Elementor 更新的影响。 - Mulli
1
@Mulli 是的,你说得对!希望Elementor团队能尽快提供更好、更直接的解决方案。 - Akhilesh B Chandran
请注意 - 可能会在没有通知的情况下发生故障。 - Mulli

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接