在每个短代码实例的wp_footer中生成不同的代码

时间:2014-04-04 21:12:28

标签: jquery wordpress init shortcode

我创建了一个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
));

因此,在timeoutspeed设置不同的页面上有两个短代码,我现在得到:

/* <![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');  }

我无法绕过如何做到这一点。我可能只是对数组如何工作有误解。有任何想法吗?非常感谢任何/所有帮助。

2 个答案:

答案 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');  } ?>

据我从试验和错误中可以看出,这个顺序非常重要。它基本上是:

  1. 设置变量以存储参数,以便以后在初始化中使用
  2. 将变量拉入短代码功能
  3. 将短代码属性存储为脚本的参数(因此它们将以JavaScript引擎可以解析的方式输出)
  4. 在你的短代码功能之后,将变量添加到你的JavaScript初始化中(这必须在你的页脚中 - 我不知道如何将它输出到头部)
  5. 希望这有助于某人。 :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并不是一个好习惯。

希望这有帮助。