我创建了一个Wordpress插件,它提供了一个自定义的帖子类型(幻灯片),这些可以按分类法(幻灯片)分组。使用简码[幻灯片],您可以显示这些幻灯片,并通过幻灯片放映来筛选它们。下面是我编码短代码的方式:
function slds_shortcode( $atts ) {
extract( shortcode_atts( array(
'slideshow' => 'all',
'timeout' => '5000',
), $atts ) );
$slideshow = $atts[slideshow];
global $post;
$tmp_post = $post;
$args = array( 'slideshows' => $slideshow, 'timeout' => $timeout, );
$myposts = get_posts( $args );
ob_start(); // Helps output the HTML where the shortcode is (otherwise it outputs before the content).
?>
<div id="<?php echo $slideshow; ?>" class="slds-slideshow">
<div class="timeout-<?php echo $timeout; ?>">
<?php foreach( $myposts as $post ) : setup_postdata($post); ?>
<div class="slide">
<?php the_content(); ?>
</div>
<?php endforeach; ?>
</div>
</div>
<?php
$post = $tmp_post;
return ob_get_clean();
}
add_shortcode('slides', 'slds_shortcode');
只有在文章中找到短代码时,脚本和样式表才会包含在页脚中。脚本(responsiveslides.js)需要一个init,它当前在页脚中输出是否在文章中找到短代码。我是这样生成的:
function slds_init() {
echo '
<script>
jQuery(function($) {
$(document).ready(function() {
$(".slds-slideshow .timeout-5000").responsiveSlides({
pause: true,
nav: true,
pager: true,
timeout: 5000,
speed: 1800
});
$(".slds-slideshow .timeout-10000").responsiveSlides({
pause: true,
nav: true,
pager: true,
timeout: 10000,
speed: 1800
});
});
});
</script>';
}
add_action('wp_footer', 'slds_init');
只要我在其中编码的默认值适合该项目,这就非常有效。相反,我希望能够在短代码中设置这些参数,如:[幻灯片幻灯片放映=巡演超时=10000速度=1200]。正如您在上面看到的,init有几个主要的限制。它将选择的所有实例。slds幻灯片显示,而不是通过唯一的id或类分别选择每个短代码输出,这意味着这些默认参数必须用于所有短代码输出。事实上,我有两个jQuery选择器的原因是,我可以添加一个备用的。将timeout类添加到输出,这只会更改哪个jQuery选择器影响短代码输出(或者幻灯片显示HTML,如果愿意)。这是一个劣质的解决方案。显然,如果我以这种方式依赖于类来处理所有参数,并且参数组合的数量几乎是无限的,那么init将变得极其沉重和笨拙。
如何基于短代码属性生成init的中间部分(jQuery选择器及其参数),使它们仍然与文章中短代码的HTML输出相关?
再次感谢@birGire你的想法!我想他们让我更接近我需要的地方。
我尝试了很多选择。我认为我仍然遇到的主要问题是让短代码实例在javascript初始化中生成任何内容。我将wp_localize_script()放在我的短码函数中,正如@birgire建议的那样:
wp_localize_script('slds_script', 'slds_vars', array(
'instance' => $instance,
'timeout' => $timeout,
'speed' => $speed
));
因此,页面上有两个短代码,设置不同的超时
和速度
,我现在得到:
/* <![CDATA[ */
var avrgslds_vars = {"instance":"53442837d55c2","timeout":"10000","speed":"500"};
var avrgslds_vars = {"instance":"5344283814479","timeout":"5000","speed":"200"};
/* ]]> */
(我为实例设置了一个新变量:$实例=uniqid();
)
这似乎是一个显著的进步!因此,在我的javascript初始化中,我尝试在我的短代码中回显一个变量集,该变量集包含所有短代码“atts”(参数):
$jQselectors = "";
$jQselectors .= " // Hoping this will keep the array keys from overwriting eachother.
$(slds_vars.instance).responsiveSlides({
pause: true,
nav: true,
pager: true,
timeout: $timeout,
speed: $speed
});
";
当然,当我看到这个结果后我意识到。。。
<script>
jQuery(function($) {
$(document).ready(function() {
});
});
</script>
我无法从我的shortcode函数外部选择变量,就像我试图做的那样:
function slds_init() { ?>
<script>
jQuery(function($) {
$(document).ready(function() {
<?php echo $jQselectors; ?>
});
});
</script>
<?php
}
add_action('wp_footer', 'slds_init'); }
我不知道该怎么做。我可能只是对数组的工作原理有误解。有什么想法吗?非常感谢您的帮助。
分数我明白了。这主要是一个可变范围的问题。
首先,我最终没有使用wp_localize_script()
,因为这需要更多的JavaScript知识,而我有更多的PHP知识。对于一个更精通JavaScript的人来说,这似乎是一个很好的解决方案,再次感谢@birGire的建议!不过,我使用了他推荐的uniqid()
函数,为每个短代码实例分配了一个唯一的类(在我的短代码函数中):
$instance = 'slds-'.uniqid();
<div class="<?php echo $instance; ?>">
因此,我在shortcode函数启动之前设置了一个变量(在之前,所以它可以在shortcode函数内部和之后使用):
$jQselectors = "";
我把它拉到我的快捷码函数中:
function slds_shortcode( $atts ) { // <-- Beginning of my shortcode function
global $jQselectors;
这样,我就可以添加一个jQuery选择器,每次运行短代码函数时都要处理短代码实例中的所有相关参数:
$jQselectors .= "
$('.".$instance." .slides').responsiveSlides({
auto: ".$auto.",
speed: ".$speed.",
timeout: ".$timeout."
});";
因此,在我的init函数(在我的shortcode函数之后运行)中,我再次拉入该变量来编写JavaScript初始化的中间部分:
<?php
function slds_init() { ?>
<script>
jQuery(function($) {
$(document).ready(function() {<?php
global $jQselectors;
echo $jQselectors; ?>
});
});
</script>
<?php
}
add_action('wp_footer', 'slds_init'); } ?>
据我所知,从试验和错误中,这个序列很重要。它基本上是这样的:
希望这对某人有帮助J
您可以尝试将wp\u enqueue\u script()
和wp\u localise\u script
直接包含到快捷码回调中。
但是,如果您的页面上有多个快捷码调用,您可能会因为多个wp\u localise\u script
调用而遇到覆盖问题:
var my_setting = {"foo":"bar1"};
var my_setting = {"foo":"bar2"};
其中,排队脚本只拾取最后一个。
下面是WPSE上描述的类似问题
幸运的是,有一些变通方法可用,如WPSE上的这一种,尝试将实例与以下内容分开:
var my_setting1 = {"foo":"bar1"};
var my_setting2 = {"foo":"bar2"};
您可以尝试为每个短代码调用自动生成唯一的ID,而不是[myshortcode instance=“1”]
这类解决方法。这里有一个方便的PHP函数:uniqid()
。
ps:在PHP代码中使用提取
不是很好的做法。
希望这能有所帮助。