Displaying Theme and Plugin Versions

  • Code Snippet

I wanted to output the current versions of specific plugins automatically and the parent theme (I am using a child theme), just to draw attention to what is being used. Originally, I thought I would limit it to Bricks, but I immediately had a need to use it in Etch, so I opted for the…

I wanted to output the current versions of specific plugins automatically and the parent theme (I am using a child theme), just to draw attention to what is being used. Originally, I thought I would limit it to Bricks, but I immediately had a need to use it in Etch, so I opted for the shortcode approach.

The shortcode syntax

Here are examples of the shortcodes (you would wrap with brackets []). In Etch, you can add shortcodes in the builder without quotations (at least for now). If you are adding this in Core, you would need to wrap values in quotes (e.g., plugin_version slug=”automaticcss-plugin”).

  • Plugin
    • plugin_version slug=akismet/akismet.php
    • plugin_version slug=automaticcss-plugin
  • Theme
    • theme_version (active/child)
    • theme_version which=parent
    • theme_version which=twentytwentyfive

The Code

<?php
/**
 * Plugin Name: FW Versions (Themes & Plugins)
 * Description: Output current versions of selected plugins/themes via shortcodes & Bricks dynamic data/echo.
 * Version: 0.2.0
 * Requires at least: 6.0
 * Tested up to: 6.8.3
 */

// ---------- Helpers -----------------------------------------------------------

if ( ! function_exists( 'fw_get_plugin_version' ) ) {
	function fw_get_plugin_version( $ref = '' ) {
		if ( empty( $ref ) ) {
			return '';
		}

		// Cache briefly to avoid repeated scans.
		$key = 'fw_plugin_ver_' . md5( $ref );
		$ver = get_transient( $key );
		if ( false !== $ver ) { return $ver; }

		if ( ! function_exists( 'get_plugins' ) ) {
			require_once ABSPATH . 'wp-admin/includes/plugin.php';
		}

		$plugins = get_plugins();

		// 1) Exact match like "akismet/akismet.php"
		if ( isset( $plugins[ $ref ] ) && ! empty( $plugins[ $ref ]['Version'] ) ) {
			$ver = $plugins[ $ref ]['Version'];
			set_transient( $key, $ver, MINUTE_IN_SECONDS * 5 );
			return $ver;
		}

		// 2) Try by folder or slug
		$needle = trim( strtolower( $ref ) );
		foreach ( $plugins as $file => $data ) {
			// $file is "folder/plugin.php"
			$folder = strtolower( strtok( $file, '/' ) );
			$name   = strtolower( $data['Name'] ?? '' );

			if ( $needle === $folder || $needle === strtolower( $name ) ) {
				$ver = $data['Version'] ?? '';
				set_transient( $key, $ver, MINUTE_IN_SECONDS * 5 );
				return $ver;
			}
		}
		return '';
	}
}

if ( ! function_exists( 'fw_get_theme_version' ) ) {
	function fw_get_theme_version( $which = 'active' ) {
		// $which: 'active' (child if present), 'parent', or a stylesheet slug.
		$key = 'fw_theme_ver_' . md5( $which );
		$ver = get_transient( $key );
		if ( false !== $ver ) { return $ver; }

		if ( 'parent' === $which ) {
			$theme = wp_get_theme();
			$theme = $theme->parent() ?: $theme; // fall back to active if no parent
		} elseif ( 'active' === $which ) {
			$theme = wp_get_theme();
		} else {
			// Treat as stylesheet slug
			$theme = wp_get_theme( $which );
			if ( ! $theme->exists() ) {
				return '';
			}
		}

		$ver = $theme->get( 'Version' ) ?: '';
		set_transient( $key, $ver, MINUTE_IN_SECONDS * 5 );
		return $ver;
	}
}
if ( ! function_exists( 'fw_get_wp_version' ) ) {
	function fw_get_wp_version() {
		return get_bloginfo( 'version' );
	}
}
// ---------- Shortcodes --------------------------------------------------------

/**
 * [plugin_version slug="akismet/akismet.php"] or [plugin_version slug="akismet"]
 */
add_shortcode( 'plugin_version', function( $atts ) {
	$atts = shortcode_atts( [
		'slug' => '',
	], $atts, 'plugin_version' );

	return esc_html( fw_get_plugin_version( $atts['slug'] ) );
});

/**
 * [theme_version] (active/child), [theme_version which="parent"], or [theme_version which="twentytwentyfive"]
 */
add_shortcode( 'theme_version', function( $atts ) {
	$atts = shortcode_atts( [
		'which' => 'active', // active|parent|{stylesheet}
	], $atts, 'theme_version' );

	return esc_html( fw_get_theme_version( $atts['which'] ) );
});

/**
 * [wp_version] or [wp_version prefix="WordPress "]
 */
add_shortcode( 'wp_version', function( $atts ) {
	$atts = shortcode_atts( [
		'prefix' => '', // e.g., "WordPress "
	], $atts, 'wp_version' );

	$version = get_bloginfo( 'version' ); // same as $GLOBALS['wp_version']
	return esc_html( $atts['prefix'] . $version );
});