OEmbed 未应用于 Ajax 回调中的视频 link
OEmbed not applied to video link in Ajax Callback
我在使用 wp_editor()、tinyMCE 和 the_content 与视频嵌入相关的过滤器时遇到困难。
我正在输出一个前端 wp_editor() 表单,以允许注册用户从站点的前端创建新的 post。创建的新 post 是自定义 post 类型。
目标行为是:
- 注册用户输入内容并点击提交
- 表单由 jQuery/Ajax 处理,表单数据通过 post()
传递给 PHP 函数
- 创建了一个新的 post,并为 Ajax 回调生成了响应
- 响应是一个 JSON 数组,其中包含新 post 内容的 HTML
- 返回的 HTML 应用了 'the_content' 过滤器 - 嵌入式视频应正确显示
- Ajax 回调删除原始表单并将 post HTML 附加到 div
除了视频 oEmbed 之外,一切都按预期工作。
如果将视频 link 添加到内容中(在 wp_editor 中的新行),则 Ajax 回调构建的内容包括视频 URL 包裹在段落标签中 - oEmbed 没有工作,即使 HTML 应用了 'the_content' 过滤器。
刷新页面会循环显示新的 post,内容由 the_content()
标签显示 - 并且视频显示正确(oEmbed 已经工作)。
在 wp_editor 参数中设置 'wpautop' => false
没有帮助 - 弄乱了格式,无法修复视频。
是否有我缺少的 tinyMCE 设置?
我如何应用 'the_content' 过滤器 and/or 为 Ajax 回调构建 HTML 字符串有问题吗?
相关代码如下所示。
谢谢!
JQuery
(function( $ ) { 'use strict';
$(function() {
$('#student-submission-button').click( function(event) {
// Prevent default action
// -----------------------
event.preventDefault();
var submission_nonce_id = $('#the_nonce_field').val();
var submission_title = $('#inputTitle').val();
tinyMCE.triggerSave();
var submission_content = $('#editor').val();
var Data = {
action: 'student_submission',
nonce: submission_nonce_id,
workbook_ID: submission_workbook_ID,
content: submission_content,
title: submission_title,
};
// Do AJAX request
$.post( ajax_url, Data, function(Response) {
if( Response ) {
var submissionStatus = Response.status;
var submissionMessage = Response.report;
var postHTML = Response.content;
if ( 'success' == submissionStatus ) {
$('#user-feedback').html( submissionMessage );
$('#new-post').append( postHTML );
}
// Hide the form
$('.carawebs-frontend-form').hide(800, function() {
$(this).remove();
});
}
});
});
});
})( jQuery );
PHP
/**
* Return data via Ajax (excerpt)
*
*
*/
$response = array();
if( is_int( $new_submission_ID ) ) {
// Build a success response
// ------------------------
$new_post = get_post( $new_submission_ID, OBJECT );
$new_post_content = $new_post->post_content;
$return_content = "<h2>$new_post->post_title</h2>";
$return_content .= apply_filters( 'the_content', $new_post_content );
$response['status'] = "success";
$response['report'] = "New post created, ID: $new_submission_ID";
$response['content'] = $return_content;
} else {
// error report
}
wp_send_json( $response ); // send $response as a JSON object
形成HTML和wp_editor()
<form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post" enctype="multipart/form-data" class="carawebs-frontend-form">
<label for="inputTitle">Title</label>
<input type="text" class="form-control" id="inputTitle" name="inputTitle" placeholder="Title" value="" />
<label for="inputContent" class="topspace">Your Content</label>
<?php
$args = array(
'textarea_rows' => 45,
'teeny' => false,
'editor_height' => 400,
'editor_class' => 'cwfrontendadmin',
'quicktags' => false,
'textarea_name' => 'cw_content',
'tinymce' => array(
'content_css' => get_template_directory_uri() . '/assets/css/editor-style.css'
),
);
wp_editor( 'Enter your content...', 'editor', $args );
wp_nonce_field('name_of_action','the_nonce_field', true, true ); // name of action, name of nonce field
?>
<input id="student-submission-button" class="btn btn-primary" type="submit" name="submission-form" value="Save Content" />
更新
我已将其缩小到 the_content
过滤器的应用方式。我认为过滤后的内容已缓存,因此如果 post 内容在循环外返回,oEmbed 可能不会应用于所有内容。
现在我可以使用视频 oEmbed - 使用不同的方法将 post_content
插入变量:
<?php
global $post;
$post = get_post($new_submission_ID);
setup_postdata( $post );
$new_content = apply_filters('the_content', get_the_content());
$new_post_link = get_the_permalink();
$new_post_title = get_the_title();
wp_reset_postdata( $post );
这很好用,但如果有人能解释为什么构建 HTML 的原始方法不起作用就更好了。
根据 other sources 的说法,原因是 WP_Embed::shortcode()
(负责为嵌入式 html 换出视频)正在调用 global $post
变量信息。
这意味着您需要确保 global $post
变量包含您请求的 post 的信息。
我的 AJAX 响应方法现在包含 global $post
变量:
global $post;
$post = get_post( $id );
echo apply_filters( 'the_content', $post->post_content );
die();
这基本上只是您自己发现的延伸,但我认为这可能有助于明确 answer/solution oEmbed + AJAX for WordPress 的问题。
如果在循环外返回 post 内容,并且未设置 global $post
,则不会应用 oEmbed 过滤器。
这是因为视频嵌入内容缓存在 post 元 table 中,如果 post 内容在循环外返回,则无法访问。由 the_content
过滤器挂接的 WP_Embed class 并非设计用于循环外 - 这是在 Trac here.
上引用的
以下方法 returns 一个有效的视频 oEmbed 按照原始场景。 global $post
需要设置以使缓存的视频嵌入数据可用:
<?php
global $post;
$post = get_post( $new_submission_ID );
setup_postdata( $post );
$new_content = apply_filters( 'the_content', get_the_content() );
wp_reset_postdata( $post );
// return what you need via Ajax callback -
// $new_content contains the proper video embed HTML
TL;DR 版本
如果您需要在循环外应用 oEmbed 过滤器,您需要设置全局 post 变量,以便 WP_Embed
class 可以访问缓存的视频嵌入 html 在 post 的元数据中。
我在使用 wp_editor()、tinyMCE 和 the_content 与视频嵌入相关的过滤器时遇到困难。
我正在输出一个前端 wp_editor() 表单,以允许注册用户从站点的前端创建新的 post。创建的新 post 是自定义 post 类型。
目标行为是:
- 注册用户输入内容并点击提交
- 表单由 jQuery/Ajax 处理,表单数据通过 post() 传递给 PHP 函数
- 创建了一个新的 post,并为 Ajax 回调生成了响应
- 响应是一个 JSON 数组,其中包含新 post 内容的 HTML
- 返回的 HTML 应用了 'the_content' 过滤器 - 嵌入式视频应正确显示
- Ajax 回调删除原始表单并将 post HTML 附加到 div
除了视频 oEmbed 之外,一切都按预期工作。
如果将视频 link 添加到内容中(在 wp_editor 中的新行),则 Ajax 回调构建的内容包括视频 URL 包裹在段落标签中 - oEmbed 没有工作,即使 HTML 应用了 'the_content' 过滤器。
刷新页面会循环显示新的 post,内容由 the_content()
标签显示 - 并且视频显示正确(oEmbed 已经工作)。
在 wp_editor 参数中设置 'wpautop' => false
没有帮助 - 弄乱了格式,无法修复视频。
是否有我缺少的 tinyMCE 设置?
我如何应用 'the_content' 过滤器 and/or 为 Ajax 回调构建 HTML 字符串有问题吗?
相关代码如下所示。
谢谢!
JQuery
(function( $ ) { 'use strict';
$(function() {
$('#student-submission-button').click( function(event) {
// Prevent default action
// -----------------------
event.preventDefault();
var submission_nonce_id = $('#the_nonce_field').val();
var submission_title = $('#inputTitle').val();
tinyMCE.triggerSave();
var submission_content = $('#editor').val();
var Data = {
action: 'student_submission',
nonce: submission_nonce_id,
workbook_ID: submission_workbook_ID,
content: submission_content,
title: submission_title,
};
// Do AJAX request
$.post( ajax_url, Data, function(Response) {
if( Response ) {
var submissionStatus = Response.status;
var submissionMessage = Response.report;
var postHTML = Response.content;
if ( 'success' == submissionStatus ) {
$('#user-feedback').html( submissionMessage );
$('#new-post').append( postHTML );
}
// Hide the form
$('.carawebs-frontend-form').hide(800, function() {
$(this).remove();
});
}
});
});
});
})( jQuery );
PHP
/**
* Return data via Ajax (excerpt)
*
*
*/
$response = array();
if( is_int( $new_submission_ID ) ) {
// Build a success response
// ------------------------
$new_post = get_post( $new_submission_ID, OBJECT );
$new_post_content = $new_post->post_content;
$return_content = "<h2>$new_post->post_title</h2>";
$return_content .= apply_filters( 'the_content', $new_post_content );
$response['status'] = "success";
$response['report'] = "New post created, ID: $new_submission_ID";
$response['content'] = $return_content;
} else {
// error report
}
wp_send_json( $response ); // send $response as a JSON object
形成HTML和wp_editor()
<form action="<?php echo $_SERVER['REQUEST_URI']; ?>" method="post" enctype="multipart/form-data" class="carawebs-frontend-form">
<label for="inputTitle">Title</label>
<input type="text" class="form-control" id="inputTitle" name="inputTitle" placeholder="Title" value="" />
<label for="inputContent" class="topspace">Your Content</label>
<?php
$args = array(
'textarea_rows' => 45,
'teeny' => false,
'editor_height' => 400,
'editor_class' => 'cwfrontendadmin',
'quicktags' => false,
'textarea_name' => 'cw_content',
'tinymce' => array(
'content_css' => get_template_directory_uri() . '/assets/css/editor-style.css'
),
);
wp_editor( 'Enter your content...', 'editor', $args );
wp_nonce_field('name_of_action','the_nonce_field', true, true ); // name of action, name of nonce field
?>
<input id="student-submission-button" class="btn btn-primary" type="submit" name="submission-form" value="Save Content" />
更新
我已将其缩小到 the_content
过滤器的应用方式。我认为过滤后的内容已缓存,因此如果 post 内容在循环外返回,oEmbed 可能不会应用于所有内容。
现在我可以使用视频 oEmbed - 使用不同的方法将 post_content
插入变量:
<?php
global $post;
$post = get_post($new_submission_ID);
setup_postdata( $post );
$new_content = apply_filters('the_content', get_the_content());
$new_post_link = get_the_permalink();
$new_post_title = get_the_title();
wp_reset_postdata( $post );
这很好用,但如果有人能解释为什么构建 HTML 的原始方法不起作用就更好了。
根据 other sources 的说法,原因是 WP_Embed::shortcode()
(负责为嵌入式 html 换出视频)正在调用 global $post
变量信息。
这意味着您需要确保 global $post
变量包含您请求的 post 的信息。
我的 AJAX 响应方法现在包含 global $post
变量:
global $post;
$post = get_post( $id );
echo apply_filters( 'the_content', $post->post_content );
die();
这基本上只是您自己发现的延伸,但我认为这可能有助于明确 answer/solution oEmbed + AJAX for WordPress 的问题。
如果在循环外返回 post 内容,并且未设置 global $post
,则不会应用 oEmbed 过滤器。
这是因为视频嵌入内容缓存在 post 元 table 中,如果 post 内容在循环外返回,则无法访问。由 the_content
过滤器挂接的 WP_Embed class 并非设计用于循环外 - 这是在 Trac here.
以下方法 returns 一个有效的视频 oEmbed 按照原始场景。 global $post
需要设置以使缓存的视频嵌入数据可用:
<?php
global $post;
$post = get_post( $new_submission_ID );
setup_postdata( $post );
$new_content = apply_filters( 'the_content', get_the_content() );
wp_reset_postdata( $post );
// return what you need via Ajax callback -
// $new_content contains the proper video embed HTML
TL;DR 版本
如果您需要在循环外应用 oEmbed 过滤器,您需要设置全局 post 变量,以便 WP_Embed
class 可以访问缓存的视频嵌入 html 在 post 的元数据中。