You can wrap it in a class.
Here’s an example:
class WPSE_Answers_Counting
{
private $instance_answers = 0;
private $instance_prev_answers = 0;
private $instance_answer = 0;
public function init()
{
add_shortcode( 'answers', [ $this, 'answers_shortcode' ] );
add_shortcode( 'ans', [ $this, 'answer_shortcode' ] );
}
public function answers_shortcode( $atts = [], $content = null )
{
// Output with [answers] counting
return sprintf(
"<div class="answers-wrapper">
<div id='answers-%d' class="answers">
%s
</div>
</div>",
$this->instance_answers++,
do_shortcode( $content )
);
}
public function answer_shortcode( $atts = [], $content = null )
{
// Reset single [ans] counting after each [answers]
if( $this->instance_prev_answers != $this->instance_answers )
$this->instance_answer = 1;
// Output with [ans] counting
$out = sprintf(
"<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="https://wordpress.stackexchange.com/questions/211265/?ins=%d&ans=%d">%s</a>
</dd>
</dl>",
$this->instance_answers,
$this->instance_answer++,
esc_html( $content )
);
// Update the previous [answers] instance count
$this->instance_prev_answers = $this->instance_answers;
return $out;
}
} // end class
Create an object instance, then this shortcode mayhem:
[answers][ans]a1[/ans][ans]b1[/ans][ans]c1[/ans][/answers]
[answers][ans]a2[/ans][ans]b2[/ans][ans]c2[/ans][/answers]
[answers][ans]a3[/ans][ans]b3[/ans][ans]c3[/ans][/answers]
will output as:
<div class="answers-wrapper">
<div id='answers-0' class="answers">
<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="https://wordpress.stackexchange.com/questions/211265/?ins=1&ans=1">a1</a>
</dd>
</dl>
<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="?ins=1&ans=2">b1</a>
</dd>
</dl>
<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="?ins=1&ans=3">c1</a>
</dd>
</dl>
</div>
</div><br />
<div class="answers-wrapper">
<div id='answers-1' class="answers">
<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="?ins=2&ans=1">a2</a>
</dd>
</dl>
<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="?ins=2&ans=2">b2</a>
</dd>
</dl>
<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="?ins=2&ans=3">c2</a>
</dd>
</dl>
</div>
</div><br />
<div class="answers-wrapper">
<div id='answers-2' class="answers">
<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="?ins=3&ans=1">a3</a>
</dd>
</dl>
<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="?ins=3&ans=2">b3</a>
</dd>
</dl>
<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="?ins=3&ans=3">c3</a>
</dd>
</dl>
</div>
</div>
with the (hopfully) correct instance number counting you’re after.
Update:
You’ll probably want to reset the single [ans]
counting after each [answers]
, so I adjusted the class to support that.
Here’s the static version:
add_shortcode( 'answers', 'WPSE_Answers_Counting::answers_shortcode' );
add_shortcode( 'ans', 'WPSE_Answers_Counting::answer_shortcode' );
class WPSE_Answers_Counting
{
private static $instance_answers = 0;
private static $instance_prev_answers = 0;
private static $instance_answer = 0;
public static function answers_shortcode( $atts = [], $content = null )
{
return sprintf(
"<div class="answers-wrapper">
<div id='answers-%d' class="answers">
%s
</div>
</div>",
self::$instance_answers++,
do_shortcode( $content )
);
}
public static function answer_shortcode( $atts = [], $content = null )
{
// Reset single [ans] coutning
if( self::$instance_prev_answers != self::$instance_answers )
self::$instance_answer = 1;
$out = sprintf(
"<dl class="answer-item">
<dd class="wp-caption-text answer-caption">
<a href="https://wordpress.stackexchange.com/questions/211265/?ins=%d&ans=%d">%s</a>
</dd>
</dl>",
self::$instance_answers,
self::$instance_answer++,
esc_html( $content )
);
// Update the previous instance
self::$instance_prev_answers = self::$instance_answers;
return $out;
}
} // end class