Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

MediaWiki:Common.js: Difference between revisions

MediaWiki interface page
Add WordPress header/footer proxy integration
 
Replace dynamic WP proxy with static custom header/footer nav
Line 1: Line 1:
/* ─── Menhirs Fate Wiki — WordPress Header/Footer Integration ──────────────
/* ─── Menhirs Fate Wiki — Custom Header & Footer ─────────────────────────
  *
  *
  * Fetches the live WP header and footer from a server-side proxy (/wp-nav.php)
  * Static parchment-banner header and dark footer matching the WordPress
  * which caches the WordPress site HTML for 1 hourThe proxy avoids CORS.
  * theme at menhirsfate.comNo dynamic proxy — pure CSS + HTML injection.
  *
  *
  * Astra (WordPress theme) CSS is loaded inside a CSS @layer so it has lower
  * Layout:
  * priority than Citizen's unlayered styles, preventing conflicts.
*  HEADER  →  dark logo bar  +  parchment ribbon nav
  * ─────────────────────────────────────────────────────────────────────────── */
  *   FOOTER  →  dark 3-column (Contact · Information · Wiki) + copyright
  * ───────────────────────────────────────────────────────────────────────── */
( function () {
( function () {
     'use strict';
     'use strict';


     /* Load Astra stylesheets inside @layer wp-astra so they lose to Citizen */
     /* ── Google Font ─────────────────────────────────────────────────────── */
     function loadAstraCSS( inlineCSS ) {
    var link = document.createElement( 'link' );
         // Inject Astra CSS custom properties (colour tokens, spacing vars)
    link.rel = 'stylesheet';
        if ( inlineCSS ) {
    link.href = 'https://fonts.googleapis.com/css2?family=Crimson+Text:ital,wght@0,400;0,600;0,700;1,400&display=swap';
            var s = document.createElement( 'style' );
    document.head.appendChild( link );
            s.id = 'mf-wp-inline-css';
 
            s.textContent = '@layer wp-astra {\n' + inlineCSS + '\n}';
    /* ── HEADER ──────────────────────────────────────────────────────────── */
             document.head.appendChild( s );
    var header = document.createElement( 'div' );
    header.id = 'mf-header';
    header.innerHTML = [
        '<div id="mf-header-top">',
        '  <a href="https://www.menhirsfate.com/" id="mf-logo-link">',
        '    <img src="https://www.menhirsfate.com/wp-content/uploads/2024/08/white-logo-scaled-120x65.png"',
        '        alt="Menhirs Fate" id="mf-logo" />',
        '  </a>',
        '</div>',
        '<nav id="mf-ribbon">',
        '  <div id="mf-ribbon-inner">',
        '    <a href="https://www.menhirsfate.com/" class="mf-nav-item mf-nav-back">&larr; MenhirsFate.com</a>',
        '    <a href="/wiki/Main_Page" class="mf-nav-item">Home</a>',
        '    <div class="mf-nav-item mf-has-dropdown">',
        '      <span class="mf-nav-label">Nations <span class="mf-caret">&#9662;</span></span>',
        '      <div class="mf-dropdown">',
        '        <a href="/wiki/The_Crownlands/Avereaux">Avereaux</a>',
        '        <a href="/wiki/The_Wonder">The Wonder</a>',
        '        <a href="/wiki/Valdraeth">Valdraeth</a>',
        '        <a href="/wiki/The_Urdrevan_People">The Urdrevan People</a>',
        '        <a href="/wiki/The_Republic_of_Portavas">The Republic of Portavas</a>',
        '        <a href="/wiki/The_Hammerstadt_Charter">The Hammerstadt Charter</a>',
        '        <a href="/wiki/Kairos">Kairos</a>',
        '        <a href="/wiki/Syradonia">Syradonia</a>',
        '        <a href="/wiki/Morvalis">Morvalis</a>',
        '      </div>',
        '    </div>',
        '    <div class="mf-nav-item mf-has-dropdown">',
        '      <span class="mf-nav-label">Gameplay <span class="mf-caret">&#9662;</span></span>',
        '      <div class="mf-dropdown">',
        '        <a href="/wiki/Look_and_Feel">Look and Feel</a>',
        '        <a href="/wiki/Basic_Skills">Basic Skills</a>',
        '        <a href="/wiki/Magical_Skills">Magical Skills</a>',
        '        <a href="/wiki/Monstering">Monstering</a>',
        '        <a href="/wiki/Accessibility">Accessibility</a>',
        '      </div>',
        '    </div>',
        '    <div class="mf-nav-item mf-has-dropdown">',
        '      <span class="mf-nav-label">Resources <span class="mf-caret">&#9662;</span></span>',
        '      <div class="mf-dropdown">',
        '        <a href="/wiki/Funded_Builds">Funded Builds</a>',
        '        <a href="/wiki/Camping_Information">Camping Information</a>',
        '        <a href="/wiki/Special:Categories">Browse by Category</a>',
        '      </div>',
        '    </div>',
        '  </div>',
        '</nav>'
    ].join( '\n' );
 
    document.body.insertBefore( header, document.body.firstChild );
 
    /* ── FOOTER ──────────────────────────────────────────────────────────── */
     var footer = document.createElement( 'div' );
    footer.id = 'mf-footer';
    footer.innerHTML = [
        '<div id="mf-footer-main">',
        '  <div class="mf-footer-col">',
        '    <h4>Contact</h4>',
        '    <div class="mf-social-icons">',
        '      <a href="https://www.youtube.com/@MenhirsFate" target="_blank" rel="noopener" title="YouTube" class="mf-social-yt">',
        '        <svg viewBox="0 0 24 24" width="36" height="36"><path fill="currentColor" d="M23.5 6.2a3 3 0 0 0-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 0 0 .5 6.2 31.9 31.9 0 0 0 0 12a31.9 31.9 0 0 0 .5 5.8 3 3 0 0 0 2.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2.1A31.9 31.9 0 0 0 24 12a31.9 31.9 0 0 0-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z"/></svg>',
        '      </a>',
        '      <a href="https://discord.gg/menhirsfate" target="_blank" rel="noopener" title="Discord" class="mf-social-dc">',
        '        <svg viewBox="0 0 24 24" width="36" height="36"><path fill="currentColor" d="M20.3 4.4A19.6 19.6 0 0 0 15.5 3a14 14 0 0 0-.6 1.3 18.2 18.2 0 0 0-5.8 0A14 14 0 0 0 8.5 3 19.6 19.6 0 0 0 3.7 4.4 20.5 20.5 0 0 0 .2 17.6a19.8 19.8 0 0 0 6 3 14.7 14.7 0 0 0 1.3-2.1 12.8 12.8 0 0 1-2-.9l.5-.4a14.1 14.1 0 0 0 12 0l.5.4a12.8 12.8 0 0 1-2 .9 14.7 14.7 0 0 0 1.3 2.1 19.8 19.8 0 0 0 6-3A20.5 20.5 0 0 0 20.3 4.4zM8 14.8c-1.1 0-2-1-2-2.3s.9-2.3 2-2.3 2.1 1 2 2.3-.9 2.3-2 2.3zm8 0c-1.1 0-2-1-2-2.3s.9-2.3 2-2.3 2.1 1 2 2.3-.9 2.3-2 2.3z"/></svg>',
        '      </a>',
        '      <a href="https://www.facebook.com/MenhirsFate" target="_blank" rel="noopener" title="Facebook" class="mf-social-fb">',
        '        <svg viewBox="0 0 24 24" width="36" height="36"><circle cx="12" cy="12" r="12" fill="currentColor"/><path fill="#111" d="M16 12.4h-2.5v7.1h-3v-7.1H9V9.8h1.5V8.1c0-1.2.6-3.1 3.1-3.1h2.3v2.5h-1.7c-.3 0-.7.1-.7.7v1.6H16l-.3 2.6z"/></svg>',
        '      </a>',
        '    </div>',
        '  </div>',
        '  <div class="mf-footer-col">',
        '    <h4>Information</h4>',
        '    <a href="https://www.menhirsfate.com/contact-us/">Contact Us</a>',
        '    <a href="https://www.menhirsfate.com/volunteer-application/">Volunteer Application</a>',
        '    <a href="https://www.menhirsfate.com/my-account/">My Account</a>',
        '    <a href="https://www.menhirsfate.com/policies/">Policies</a>',
        '    <a href="https://www.menhirsfate.com/terms-and-conditions/">Terms and Conditions</a>',
        '    <a href="https://www.menhirsfate.com/branding-guidelines/">Branding Guidelines</a>',
        '  </div>',
        '  <div class="mf-footer-col">',
        '    <h4>Wiki</h4>',
        '    <a href="/wiki/Main_Page">Main Page</a>',
        '    <a href="/wiki/Special:RecentChanges">Recent Changes</a>',
        '    <a href="/wiki/Special:AllPages">All Pages</a>',
         '    <a href="/wiki/Special:Categories">Categories</a>',
        '  </div>',
        '</div>',
        '<div id="mf-footer-copy">',
        '  Copyright &copy; ' + new Date().getFullYear() + ' Menhirs Fate',
        '</div>'
    ].join( '\n' );
 
    document.body.appendChild( footer );
 
    /* ── Mobile hamburger toggle ─────────────────────────────────────────── */
    var ribbon = document.getElementById( 'mf-ribbon-inner' );
    var burger = document.createElement( 'button' );
    burger.id = 'mf-burger';
    burger.setAttribute( 'aria-label', 'Toggle menu' );
    burger.innerHTML = '<span></span><span></span><span></span>';
    document.getElementById( 'mf-header-top' ).appendChild( burger );
 
    burger.addEventListener( 'click', function () {
        ribbon.classList.toggle( 'mf-open' );
        burger.classList.toggle( 'mf-open' );
    } );
 
    ribbon.addEventListener( 'click', function ( e ) {
        if ( e.target.tagName === 'A' ) {
            ribbon.classList.remove( 'mf-open' );
             burger.classList.remove( 'mf-open' );
         }
         }
        // Import Astra theme stylesheets inside a named layer
    } );
        var layerStyle = document.createElement( 'style' );
        layerStyle.id = 'mf-wp-astra-imports';
        layerStyle.textContent = [
            '@layer wp-astra {',
            '  @import url("https://www.menhirsfate.com/wp-content/themes/astra/assets/css/minified/main.min.css");',
            '  @import url("https://www.menhirsfate.com/wp-content/themes/astra/assets/css/minified/menu-animation.min.css");',
            '}'
        ].join( '\n' );
        document.head.appendChild( layerStyle );
    }


     /* Insert WP header as first child of <body>, above all Citizen UI */
     /* ── Touch-friendly dropdowns for mobile ─────────────────────────────── */
     function injectHeader( html ) {
     var dropdownToggles = document.querySelectorAll( '.mf-has-dropdown > .mf-nav-label' );
         if ( !html ) return;
    Array.prototype.forEach.call( dropdownToggles, function ( label ) {
        var wrap = document.createElement( 'div' );
         label.addEventListener( 'click', function ( e ) {
        wrap.id = 'mf-wp-header';
            e.stopPropagation();
        wrap.innerHTML = html;
            var parent = this.parentNode;
        document.body.insertBefore( wrap, document.body.firstChild );
            var siblings = document.querySelectorAll( '.mf-has-dropdown.mf-dropdown-open' );
    }
            Array.prototype.forEach.call( siblings, function ( s ) {
 
                if ( s !== parent ) s.classList.remove( 'mf-dropdown-open' );
    /* Append WP footer after all Citizen UI */
            } );
    function injectFooter( html ) {
            parent.classList.toggle( 'mf-dropdown-open' );
        if ( !html ) return;
         } );
        var wrap = document.createElement( 'div' );
     } );
        wrap.id = 'mf-wp-footer';
         wrap.innerHTML = html;
        document.body.appendChild( wrap );
     }


     /* Fetch from the server-side proxy — same origin, no CORS needed */
     document.addEventListener( 'click', function () {
    fetch( '/wp-nav.php', { cache: 'default' } )
        var open = document.querySelectorAll( '.mf-has-dropdown.mf-dropdown-open' );
        .then( function ( r ) {
         Array.prototype.forEach.call( open, function ( el ) {
            return r.ok ? r.json() : Promise.reject( r.status );
             el.classList.remove( 'mf-dropdown-open' );
         } )
        .then( function ( data ) {
             loadAstraCSS( data.inlineCSS || '' );
            injectHeader( data.header || '' );
            injectFooter( data.footer || '' );
        } )
        .catch( function () {
            /* Silently fail — wiki remains fully functional without the WP nav */
         } );
         } );
    } );


}() );
}() );

Revision as of 12:11, 11 March 2026

/* ─── Menhirs Fate Wiki — Custom Header & Footer ─────────────────────────
 *
 * Static parchment-banner header and dark footer matching the WordPress
 * theme at menhirsfate.com.  No dynamic proxy — pure CSS + HTML injection.
 *
 * Layout:
 *   HEADER  →  dark logo bar  +  parchment ribbon nav
 *   FOOTER  →  dark 3-column (Contact · Information · Wiki) + copyright
 * ───────────────────────────────────────────────────────────────────────── */
( function () {
    'use strict';

    /* ── Google Font ─────────────────────────────────────────────────────── */
    var link = document.createElement( 'link' );
    link.rel = 'stylesheet';
    link.href = 'https://fonts.googleapis.com/css2?family=Crimson+Text:ital,wght@0,400;0,600;0,700;1,400&display=swap';
    document.head.appendChild( link );

    /* ── HEADER ──────────────────────────────────────────────────────────── */
    var header = document.createElement( 'div' );
    header.id = 'mf-header';
    header.innerHTML = [
        '<div id="mf-header-top">',
        '  <a href="https://www.menhirsfate.com/" id="mf-logo-link">',
        '    <img src="https://www.menhirsfate.com/wp-content/uploads/2024/08/white-logo-scaled-120x65.png"',
        '         alt="Menhirs Fate" id="mf-logo" />',
        '  </a>',
        '</div>',
        '<nav id="mf-ribbon">',
        '  <div id="mf-ribbon-inner">',
        '    <a href="https://www.menhirsfate.com/" class="mf-nav-item mf-nav-back">&larr; MenhirsFate.com</a>',
        '    <a href="/wiki/Main_Page" class="mf-nav-item">Home</a>',
        '    <div class="mf-nav-item mf-has-dropdown">',
        '      <span class="mf-nav-label">Nations <span class="mf-caret">&#9662;</span></span>',
        '      <div class="mf-dropdown">',
        '        <a href="/wiki/The_Crownlands/Avereaux">Avereaux</a>',
        '        <a href="/wiki/The_Wonder">The Wonder</a>',
        '        <a href="/wiki/Valdraeth">Valdraeth</a>',
        '        <a href="/wiki/The_Urdrevan_People">The Urdrevan People</a>',
        '        <a href="/wiki/The_Republic_of_Portavas">The Republic of Portavas</a>',
        '        <a href="/wiki/The_Hammerstadt_Charter">The Hammerstadt Charter</a>',
        '        <a href="/wiki/Kairos">Kairos</a>',
        '        <a href="/wiki/Syradonia">Syradonia</a>',
        '        <a href="/wiki/Morvalis">Morvalis</a>',
        '      </div>',
        '    </div>',
        '    <div class="mf-nav-item mf-has-dropdown">',
        '      <span class="mf-nav-label">Gameplay <span class="mf-caret">&#9662;</span></span>',
        '      <div class="mf-dropdown">',
        '        <a href="/wiki/Look_and_Feel">Look and Feel</a>',
        '        <a href="/wiki/Basic_Skills">Basic Skills</a>',
        '        <a href="/wiki/Magical_Skills">Magical Skills</a>',
        '        <a href="/wiki/Monstering">Monstering</a>',
        '        <a href="/wiki/Accessibility">Accessibility</a>',
        '      </div>',
        '    </div>',
        '    <div class="mf-nav-item mf-has-dropdown">',
        '      <span class="mf-nav-label">Resources <span class="mf-caret">&#9662;</span></span>',
        '      <div class="mf-dropdown">',
        '        <a href="/wiki/Funded_Builds">Funded Builds</a>',
        '        <a href="/wiki/Camping_Information">Camping Information</a>',
        '        <a href="/wiki/Special:Categories">Browse by Category</a>',
        '      </div>',
        '    </div>',
        '  </div>',
        '</nav>'
    ].join( '\n' );

    document.body.insertBefore( header, document.body.firstChild );

    /* ── FOOTER ──────────────────────────────────────────────────────────── */
    var footer = document.createElement( 'div' );
    footer.id = 'mf-footer';
    footer.innerHTML = [
        '<div id="mf-footer-main">',
        '  <div class="mf-footer-col">',
        '    <h4>Contact</h4>',
        '    <div class="mf-social-icons">',
        '      <a href="https://www.youtube.com/@MenhirsFate" target="_blank" rel="noopener" title="YouTube" class="mf-social-yt">',
        '        <svg viewBox="0 0 24 24" width="36" height="36"><path fill="currentColor" d="M23.5 6.2a3 3 0 0 0-2.1-2.1C19.5 3.5 12 3.5 12 3.5s-7.5 0-9.4.6A3 3 0 0 0 .5 6.2 31.9 31.9 0 0 0 0 12a31.9 31.9 0 0 0 .5 5.8 3 3 0 0 0 2.1 2.1c1.9.6 9.4.6 9.4.6s7.5 0 9.4-.6a3 3 0 0 0 2.1-2.1A31.9 31.9 0 0 0 24 12a31.9 31.9 0 0 0-.5-5.8zM9.6 15.6V8.4l6.3 3.6-6.3 3.6z"/></svg>',
        '      </a>',
        '      <a href="https://discord.gg/menhirsfate" target="_blank" rel="noopener" title="Discord" class="mf-social-dc">',
        '        <svg viewBox="0 0 24 24" width="36" height="36"><path fill="currentColor" d="M20.3 4.4A19.6 19.6 0 0 0 15.5 3a14 14 0 0 0-.6 1.3 18.2 18.2 0 0 0-5.8 0A14 14 0 0 0 8.5 3 19.6 19.6 0 0 0 3.7 4.4 20.5 20.5 0 0 0 .2 17.6a19.8 19.8 0 0 0 6 3 14.7 14.7 0 0 0 1.3-2.1 12.8 12.8 0 0 1-2-.9l.5-.4a14.1 14.1 0 0 0 12 0l.5.4a12.8 12.8 0 0 1-2 .9 14.7 14.7 0 0 0 1.3 2.1 19.8 19.8 0 0 0 6-3A20.5 20.5 0 0 0 20.3 4.4zM8 14.8c-1.1 0-2-1-2-2.3s.9-2.3 2-2.3 2.1 1 2 2.3-.9 2.3-2 2.3zm8 0c-1.1 0-2-1-2-2.3s.9-2.3 2-2.3 2.1 1 2 2.3-.9 2.3-2 2.3z"/></svg>',
        '      </a>',
        '      <a href="https://www.facebook.com/MenhirsFate" target="_blank" rel="noopener" title="Facebook" class="mf-social-fb">',
        '        <svg viewBox="0 0 24 24" width="36" height="36"><circle cx="12" cy="12" r="12" fill="currentColor"/><path fill="#111" d="M16 12.4h-2.5v7.1h-3v-7.1H9V9.8h1.5V8.1c0-1.2.6-3.1 3.1-3.1h2.3v2.5h-1.7c-.3 0-.7.1-.7.7v1.6H16l-.3 2.6z"/></svg>',
        '      </a>',
        '    </div>',
        '  </div>',
        '  <div class="mf-footer-col">',
        '    <h4>Information</h4>',
        '    <a href="https://www.menhirsfate.com/contact-us/">Contact Us</a>',
        '    <a href="https://www.menhirsfate.com/volunteer-application/">Volunteer Application</a>',
        '    <a href="https://www.menhirsfate.com/my-account/">My Account</a>',
        '    <a href="https://www.menhirsfate.com/policies/">Policies</a>',
        '    <a href="https://www.menhirsfate.com/terms-and-conditions/">Terms and Conditions</a>',
        '    <a href="https://www.menhirsfate.com/branding-guidelines/">Branding Guidelines</a>',
        '  </div>',
        '  <div class="mf-footer-col">',
        '    <h4>Wiki</h4>',
        '    <a href="/wiki/Main_Page">Main Page</a>',
        '    <a href="/wiki/Special:RecentChanges">Recent Changes</a>',
        '    <a href="/wiki/Special:AllPages">All Pages</a>',
        '    <a href="/wiki/Special:Categories">Categories</a>',
        '  </div>',
        '</div>',
        '<div id="mf-footer-copy">',
        '  Copyright &copy; ' + new Date().getFullYear() + ' Menhirs Fate',
        '</div>'
    ].join( '\n' );

    document.body.appendChild( footer );

    /* ── Mobile hamburger toggle ─────────────────────────────────────────── */
    var ribbon = document.getElementById( 'mf-ribbon-inner' );
    var burger = document.createElement( 'button' );
    burger.id = 'mf-burger';
    burger.setAttribute( 'aria-label', 'Toggle menu' );
    burger.innerHTML = '<span></span><span></span><span></span>';
    document.getElementById( 'mf-header-top' ).appendChild( burger );

    burger.addEventListener( 'click', function () {
        ribbon.classList.toggle( 'mf-open' );
        burger.classList.toggle( 'mf-open' );
    } );

    ribbon.addEventListener( 'click', function ( e ) {
        if ( e.target.tagName === 'A' ) {
            ribbon.classList.remove( 'mf-open' );
            burger.classList.remove( 'mf-open' );
        }
    } );

    /* ── Touch-friendly dropdowns for mobile ─────────────────────────────── */
    var dropdownToggles = document.querySelectorAll( '.mf-has-dropdown > .mf-nav-label' );
    Array.prototype.forEach.call( dropdownToggles, function ( label ) {
        label.addEventListener( 'click', function ( e ) {
            e.stopPropagation();
            var parent = this.parentNode;
            var siblings = document.querySelectorAll( '.mf-has-dropdown.mf-dropdown-open' );
            Array.prototype.forEach.call( siblings, function ( s ) {
                if ( s !== parent ) s.classList.remove( 'mf-dropdown-open' );
            } );
            parent.classList.toggle( 'mf-dropdown-open' );
        } );
    } );

    document.addEventListener( 'click', function () {
        var open = document.querySelectorAll( '.mf-has-dropdown.mf-dropdown-open' );
        Array.prototype.forEach.call( open, function ( el ) {
            el.classList.remove( 'mf-dropdown-open' );
        } );
    } );

}() );