MediaWiki:Common.js

Aus Hist. Verein Herne / Wanne-Eickel

Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.

  • Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
  • Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
  • Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
/* ============================================================
 * Vorlage:Hauptseite/Neue Artikel
 * Lädt die letzten 20 neu erstellten Seiten via MediaWiki-API
 * und rendert pro Seite eine Kachel mit Bild, Titel, Auszug.
 *
 * Voraussetzung: Erweiterungen PageImages und TextExtracts
 * sind aktiviert (im Wiki bereits der Fall).
 *
 * Bitte als Ergänzung in MediaWiki:Common.js einfügen.
 * ============================================================ */

( function () {
    'use strict';

    function escapeHtml( s ) {
        return String( s )
            .replace( /&/g, '&' )
            .replace( /</g, '&lt;' )
            .replace( />/g, '&gt;' )
            .replace( /"/g, '&quot;' )
            .replace( /'/g, '&#39;' );
    }

    function formatDate( ts ) {
        if ( !ts ) { return ''; }
        var d = new Date( ts );
        if ( isNaN( d.getTime() ) ) { return ''; }
        var monate = [ 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
            'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember' ];
        return d.getDate() + '. ' + monate[ d.getMonth() ] + ' ' + d.getFullYear();
    }

    function renderEmpty( container, text ) {
        container.innerHTML = '<div class="hv-neue-artikel-leer"><em>' +
            escapeHtml( text ) + '</em></div>';
    }

    function renderGrid( container, ordered, pageMap, platzhalter ) {
        container.innerHTML = '';
        ordered.forEach( function ( item ) {
            var p = pageMap[ item.title ];
            if ( !p || p.missing !== undefined ) { return; }

            var url = mw.util.getUrl( item.title );

            var card = document.createElement( 'div' );
            card.className = 'hv-neue-artikel-kachel';

            // Bild (mit Link auf die Seite)
            var imgWrap = document.createElement( 'a' );
            imgWrap.className = 'hv-neue-artikel-bild';
            imgWrap.href = url;
            imgWrap.title = item.title;
            var img = document.createElement( 'img' );
            img.loading = 'lazy';
            if ( p.thumbnail && p.thumbnail.source ) {
                img.src = p.thumbnail.source;
                img.alt = item.title;
                imgWrap.appendChild( img );
            } else if ( platzhalter ) {
                // Kein Page-Image vorhanden -> Vereinslogo als Platzhalter
                img.src = platzhalter;
                img.alt = item.title;
                imgWrap.classList.add( 'hv-neue-artikel-bild-platzhalter' );
                imgWrap.appendChild( img );
            } else {
                imgWrap.classList.add( 'hv-neue-artikel-bild-leer' );
            }
            card.appendChild( imgWrap );

            // Titel
            var titel = document.createElement( 'div' );
            titel.className = 'hv-neue-artikel-titel';
            var a = document.createElement( 'a' );
            a.href = url;
            a.textContent = item.title;
            titel.appendChild( a );
            card.appendChild( titel );

            // Auszug
            if ( p.extract ) {
                var ext = document.createElement( 'div' );
                ext.className = 'hv-neue-artikel-auszug';
                ext.textContent = p.extract;
                card.appendChild( ext );
            }

            // Datum
            if ( item.timestamp ) {
                var dt = document.createElement( 'div' );
                dt.className = 'hv-neue-artikel-datum';
                dt.textContent = formatDate( item.timestamp );
                card.appendChild( dt );
            }

            container.appendChild( card );
        } );

        if ( !container.children.length ) {
            renderEmpty( container, 'Keine neuen Artikel gefunden.' );
        }
    }

    function ladeNeueArtikel( container ) {
        var limit = parseInt( container.getAttribute( 'data-hv-limit' ) || '20', 10 );
        var ns = parseInt( container.getAttribute( 'data-hv-namespace' ) || '0', 10 );
        // Platzhalterbild für Artikel ohne eigenes Vorschaubild.
        // - Nicht gesetzt (Standard): Datei:Nochkeinbild.png
        // - Leerer String: kein Platzhalter (Streifenmuster).
        // - URL oder Pfad (enthält "/" oder beginnt mit "http"):
        //   wird direkt als Bild-URL verwendet.
        // - Sonst: als Wiki-Dateiname interpretiert und per
        //   Special:FilePath aufgelöst.
        var platzhalterAttr = container.getAttribute( 'data-hv-platzhalter' );
        if ( platzhalterAttr === null ) { platzhalterAttr = 'Nochkeinbild.png'; }
        if ( isNaN( limit ) || limit < 1 ) { limit = 20; }
        if ( limit > 50 ) { limit = 50; }

        mw.loader.using( [ 'mediawiki.api', 'mediawiki.util' ] ).done( function () {
            var api = new mw.Api();
            var platzhalterUrl = null;
            if ( platzhalterAttr === '' ) {
                platzhalterUrl = null;
            } else if ( /^https?:\/\//.test( platzhalterAttr ) || platzhalterAttr.charAt( 0 ) === '/' ) {
                platzhalterUrl = platzhalterAttr;
            } else {
                platzhalterUrl = mw.util.getUrl(
                    'Special:FilePath/' + platzhalterAttr, { width: 320 }
                );
            }

            // 1) Liste neu erstellter Seiten holen
            api.get( {
                action: 'query',
                list: 'recentchanges',
                rcnamespace: ns,
                rctype: 'new',
                rcshow: '!redirect',
                rcprop: 'title|timestamp',
                rclimit: limit,
                format: 'json',
                formatversion: 2
            } ).done( function ( data ) {
                var rc = ( data && data.query && data.query.recentchanges ) || [];
                if ( !rc.length ) {
                    renderEmpty( container, 'Keine neuen Artikel gefunden.' );
                    return;
                }
                // Doppelte Titel filtern (z. B. wenn zweimal in RC auftauchen)
                var seen = {};
                var ordered = [];
                rc.forEach( function ( e ) {
                    if ( !seen[ e.title ] ) {
                        seen[ e.title ] = true;
                        ordered.push( { title: e.title, timestamp: e.timestamp } );
                    }
                } );

                // 2) Bilder + Auszüge holen
                api.get( {
                    action: 'query',
                    titles: ordered.map( function ( o ) { return o.title; } ).join( '|' ),
                    prop: 'pageimages|extracts',
                    pithumbsize: 320,
                    pilimit: 'max',
                    exintro: 1,
                    explaintext: 1,
                    exchars: 200,
                    exlimit: 'max',
                    format: 'json',
                    formatversion: 2
                } ).done( function ( data2 ) {
                    var pages = ( data2 && data2.query && data2.query.pages ) || [];
                    var pageMap = {};
                    pages.forEach( function ( p ) { pageMap[ p.title ] = p; } );
                    renderGrid( container, ordered, pageMap, platzhalterUrl );
                } ).fail( function () {
                    renderEmpty( container, 'Fehler beim Laden der Seitendaten.' );
                } );
            } ).fail( function () {
                renderEmpty( container, 'Fehler beim Abruf der API.' );
            } );
        } );
    }

    function initAll( $content ) {
        var root = ( $content && $content[ 0 ] ) || document;
        var nodes = root.querySelectorAll( '.hv-neue-artikel-grid' );
        Array.prototype.forEach.call( nodes, function ( node ) {
            if ( node.getAttribute( 'data-hv-loaded' ) === '1' ) { return; }
            node.setAttribute( 'data-hv-loaded', '1' );
            ladeNeueArtikel( node );
        } );
    }

    if ( window.mw && mw.hook ) {
        mw.hook( 'wikipage.content' ).add( initAll );
    } else if ( document.readyState !== 'loading' ) {
        initAll();
    } else {
        document.addEventListener( 'DOMContentLoaded', function () { initAll(); } );
    }

}() );