When you want “this site only” behavior in multisite, the basic approach is to identify it by slug (the URL path). Because IDs can differ between environments, the slug that appears in the URL is safer.
<?php
$slug = trim(get_blog_details()->path, '/'); // e.g. 'shop' (empty string on the main site)
if ($slug === 'shop') {
// work for the shop site only
}
?>Information you can identify sites with
<?php
get_current_blog_id(); // 3 (the site ID)
trim(get_blog_details()->path, '/'); // 'shop' (subdirectory-style slug)
get_blog_details()->domain; // 'example.com' (shop.example.com on a subdomain install)
get_bloginfo('name'); // the site name
is_main_site(); // true on the main site
get_main_site_id(); // the main site's ID
home_url(); // that site's front page URL
?>| What you check | Stability | Where it fits |
|---|---|---|
| Slug (path) | ◎ Matches the URL | Use this by default. Subdirectory installs |
| Domain | ◎ Matches the URL | Subdomain installs, mapped domains |
| Site ID | △ Differs between environments | Temporary work within one environment |
is_main_site() | ◎ | Branching on “is this the parent site?” |
Wrap it in a helper function
Writing the check in many places makes changes painful. Collecting it into one function is what I’d recommend.
<?php
/** The current site's slug ('main' for the main site) */
function mynet_site_slug() {
if (!is_multisite()) {
return 'main';
}
if (is_main_site()) {
return 'main';
}
$details = get_blog_details();
// subdomain install (shop.example.com → shop)
if (defined('SUBDOMAIN_INSTALL') && SUBDOMAIN_INSTALL) {
return explode('.', $details->domain)[0];
}
// subdirectory install (/shop/ → shop)
return trim($details->path, '/');
}Because the call is the same on subdomain and subdirectory installs, switching install types later touches only one place.
<?php if (mynet_site_slug() === 'shop') : ?>
<p class="notice">Shipping is a flat $5 nationwide.</p>
<?php endif; ?>Hold per-site settings in an array
Once the branches multiply, collecting the settings into a single array reads better than lining up if statements.
<?php
function mynet_config($key = null) {
$all = [
'main' => ['color' => '#333333', 'label' => 'Head office', 'tel' => '+1 555-0101'],
'shop' => ['color' => '#e8618c', 'label' => 'Shop', 'tel' => '+1 555-0102'],
'school' => ['color' => '#3d7ea6', 'label' => 'School', 'tel' => '+1 555-0103'],
];
$config = $all[mynet_site_slug()] ?? $all['main'];
return $key === null ? $config : ($config[$key] ?? null);
}
?>
<p>Contact: <?php echo esc_html(mynet_config('tel')); ?></p>Adding a site is one more line in the array. No hunting around for branches.
TipsDesigning parent and child themes for multisiteTheme-side design (parent/child themes versus one theme with branching)Put it in a body class and split in CSS
Anything that doesn’t need PHP branching is easier to maintain on the CSS side.
<?php
add_filter('body_class', function ($classes) {
$classes[] = 'site-' . sanitize_html_class(mynet_site_slug());
return $classes;
});.site-shop { --color-primary: #e8618c; }
.site-school { --color-primary: #3d7ea6; }
.site-shop .site-header::after { content: "SHOP"; }Looking up a site ID from a URL
For when “I want that site’s posts but I don’t know its ID.”
<?php
$blog_id = get_blog_id_from_url('example.com', '/shop/'); // subdirectory install
$blog_id = get_blog_id_from_url('shop.example.com', '/'); // subdomain install
// returns 0 when nothing is found
if ($blog_id) {
switch_to_blog($blog_id);
// …fetch things…
restore_current_blog();
}
?>You have to pass the path exactly, leading and trailing slashes included (/shop/). When it won’t resolve, var_dump()ing the result of get_sites() to see the actual path format is the quick route.
A helper for looking up an ID from a slug
A small function that keeps hard-coded IDs out of your code.
<?php
/** Look up a site ID from a slug (0 when not found) */
function mynet_blog_id_by_slug($slug) {
foreach (get_sites(['number' => 100]) as $site) {
if (trim($site->path, '/') === $slug) {
return (int) $site->blog_id;
}
}
return 0;
}Call it as mynet_blog_id_by_slug('shop') and you point at the same site across environments. Where it’s called a lot, adding caching (set_site_transient()) makes it safer still.
Identifying sites in the admin screen
The same function works for admin screen customization. Note, though, that in the admin screen get_blog_details() refers to the site being edited (and in the network admin you’re in the main site’s context).
<?php
add_action('admin_notices', function () {
if (mynet_site_slug() === 'shop') {
echo '<div class="notice notice-info"><p>On the shop site, check the price before publishing a product.</p></div>';
}
});When the operating rules differ per site, a line in the admin screen cuts down on questions.
Summary
- Identify by slug (
trim(get_blog_details()->path, '/')) by default. IDs shift between environments - Collect it into one helper function that absorbs the subdomain/subdirectory difference
- Consolidate per-site differences into a settings array, and push appearance onto
body_classplus CSS - Look up an ID from a URL with
get_blog_id_from_url(), and from a slug with your own helper
Keep “which site am I on?” answered in one place and your branches don’t scatter as sites are added.