I believe the real issue you had was with echoing your data instead of returning it.
A shortcode should return the output to be drawn, which is then drawn in place of the short code.
Here is the code using HEREDOC syntax for outputs and the query. I believe this makes things much more readable once you get used to it. See http://php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc
Changes to get_past_events:
- Moved it out of the other function (for clarity)
- Provided a default input variable (for clarity of input expectations)
- Skip processing if no events received
- Moved
get_site_url()
call out of loop (same for every item) - Used HEREDOC notation (for clarity and clean output)
- Renamed the function to make it less likely to conflict
The get_past_events function:
function do_my_get_past_events( $past_events = array() ) {
$output="";
if ( is_array($past_events) && 0 < count($past_events) ) {
$site_url = get_site_url();
foreach ( $past_events as $past_event_slug ) {
$output .= <<<HTML
<li><a href="https://wordpress.stackexchange.com/questions/175004/{$site_url}/eventi/{$past_event_slug}">{$past_event_slug}</a></li>
HTML;
}
}
return $output;
}
Changes to archive_render:
- Pull shortcode attributes into an array (clarity)
- Declare
event_items
(so we can skip processing if needed) - Added
prepare
statement (prevent sql injection) using digit - Used HEREDOC for query string (clarity)
- Adjusted
rientro
variable (left hand declaration – clarity) - Changed
string
variable tocustom_short_code
(clarity) - Return the final output (the actual fix)
- Added optional block in case a default is wanted
- Renamed the function to make it less likely to conflict with anything
The archive_render function:
add_shortcode("archive", "do_my_custom_archive_render");
function do_my_custom_archive_render($atts) {
$options = shortcode_atts(
array(
'year' => 0,
'rientro' => 'no'
),
$atts
);
$past_event_items="";
if ( !empty( $options['year'] ) ) {
global $wpdb;
$query = <<<SQL
SELECT event_name
FROM wp_em_events
WHERE
EXTRACT(YEAR FROM event_end_date) = %d
AND event_end_date < CURDATE()
SQL;
$query = $wpdb->prepare( $query, (int) $options['year'] );
$past_events = $wpdb->get_col($query);
$past_event_items = do_my_get_past_events( $past_events );
}
$rientro = ( 'si' == "{$options['rientro']}" )? 'yes' : 'no';
# If there are no event items for the year provided the user will get an empty box
# If that is not what is wanted, uncomment the following 3 lines
# if ( empty($past_event_items) ) {
# $past_event_items="<li>No Events Found</li>";
# }
$custom_short_code = <<<HTML
[one_third last="{$rientro}" class="" id=""]
[accordian class="" id=""]
[toggle title="{$options['year']}" open="no"]
<ul>
{$past_event_items}
</ul>
[/toggle]
[/accordian]
[/one_third]
HTML;
return do_shortcode( $custom_short_code );
}
Here is the same code without using HEREDOC for those unfamiliar with it.
function do_my_get_past_events( $past_events = array() ) {
$output="";
if ( is_array($past_events) && 0 < count($past_events) ) {
$site_url = get_site_url();
foreach ( $past_events as $past_event_slug ) {
$output .= '<li><a href="' . $site_url . '/eventi/' . $past_event_slug . '">' . $past_event_slug . '</a></li>' . "\r\n";
}
}
return $output;
}
add_shortcode("archive", "do_my_custom_archive_render");
function do_my_archive_render($atts) {
$options = shortcode_atts(
array(
'year' => 0,
'rientro' => 'no'
),
$atts
);
$past_event_items="";
if ( !empty( $options['year'] ) ) {
global $wpdb;
$query = "SELECT event_name FROM wp_em_events WHERE EXTRACT(YEAR FROM event_end_date) = %d AND event_end_date < CURDATE()";
$query = $wpdb->prepare( $query, (int)$options['year'] );
$past_events = $wpdb->get_col($query);
$past_event_items = do_my_get_past_events( $past_events );
}
$rientro = ( 'si' == "{$options['rientro']}" )? 'yes' : 'no';
# Uncomment the following 3 lines if you want.
# if ( empty($past_event_items) ) {
# $past_event_items="<li>No Events Found</li>";
# }
$custom_short_code="[one_third last="" . $rientro . '" class="" id=""][accordian class="" id=""][toggle title="' . $options['year'] . '" open="no"]<ul>' . $past_event_items . '</ul>[/toggle][/accordian][/one_third]';
return do_shortcode( $custom_short_code );
}