我创建了一个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');
这很好用,只要我在那里编写的默认值适合项目。相反,我希望能够在短代码中设置这些参数,如:[slides slideshow = tour timeout = 10000 speed = 1200]。如您所见,init有一些主要限制。它选择.slds-slideshow的所有实例,而不是通过唯一的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
));
因此,在timeout
和speed
设置不同的页面上有两个短代码,我现在得到:
/* <![CDATA[ */
var avrgslds_vars = {"instance":"53442837d55c2","timeout":"10000","speed":"500"};
var avrgslds_vars = {"instance":"5344283814479","timeout":"5000","speed":"200"};
/* ]]> */
(我为实例设置了一个新变量:$instance = uniqid();
)
这似乎是一个重大改进!所以在我的javascript初始化中,我尝试在我的短代码中回显一个变量集,它将包含所有短代码&#34; atts&#34; (参数):
$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>
我无法像我试图做的那样从我的短代码函数外部选择变量:
function slds_init() { ?>
<script>
jQuery(function($) {
$(document).ready(function() {
<?php echo $jQselectors; ?>
});
});
</script>
<?php
}
add_action('wp_footer', 'slds_init'); }
我无法绕过如何做到这一点。我可能只是对数组如何工作有误解。有任何想法吗?非常感谢任何/所有帮助。
答案 0 :(得分:1)
分数!弄清楚了。这主要只是一个可变范围问题。
首先,我完全没有使用wp_localize_script()
,因为这需要更多的JavaScript知识,因为我有更多的PHP技术诀窍。对于更精通JavaScript的人来说,这似乎是一个很好的解决方案,并再次感谢@birgire的建议!我使用了他推荐的uniqid()
函数,为每个短代码实例(在我的短代码函数中)分配一个唯一的类:
$instance = 'slds-'.uniqid();
<div class="<?php echo $instance; ?>">
然后我在我的短代码函数开始之前设置了一个变量(在之前,所以它可以在中使用,在我的短代码函数之后) :
$jQselectors = "";
我把它拉进我的短代码功能:
function slds_shortcode( $atts ) { // <-- Beginning of my shortcode function
global $jQselectors;
这样我可以添加一个jQuery选择器,每次运行短代码函数时都会处理短代码实例中的所有相关参数:
$jQselectors .= "
$('.".$instance." .slides').responsiveSlides({
auto: ".$auto.",
speed: ".$speed.",
timeout: ".$timeout."
});";
所以在我的init函数(在我的短代码函数之后运行)中,我再次将该变量拉入以编写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-
答案 1 :(得分:0)
您可以尝试将wp_enqueue_script()
和wp_localise_script
直接包含在短信代码回调中。
但如果您的网页上有多个短代码调用,则可能会遇到来自多个wp_localise_script
来电的覆盖问题:
var my_setting = {"foo":"bar1"};
var my_setting = {"foo":"bar2"};
只有最后一个被排队的剧本选中。
Here's similar problem described on WPSE
幸运的是,有一些可用的解决方法,例如this one on WPSE,尝试用以下内容分隔实例:
var my_setting1 = {"foo":"bar1"};
var my_setting2 = {"foo":"bar2"};
您可以尝试为每个短代码调用自动生成唯一ID,而不是[myshortcode instance="1"]
种解决方法。它有一个方便的PHP函数:uniqid()
。
ps:在PHP代码中使用extract
并不是一个好习惯。
希望这有帮助。