Extension:SiteGraph

From MediaWiki.org
Jump to navigation Jump to search
MediaWiki extensions manual
Crystal Clear action run.svg
SiteGraph
Release status: stable
Implementation Tag
Description Uses the Extension:GraphViz plugin to create a site map.
Author(s) Kenny Root (kRutOntalk)
Latest version 1.1.0
MediaWiki 1.6.0 or newer
License GPLv3
Download No link
Translate the SiteGraph extension if it is available at translatewiki.net
Check usage and version matrix.

What can this extension do?[edit]

The SiteGraph extension creates a site graph based on all the pages in your Wiki using the Graphviz program. This presents a map of your site with clickable links for users to get a sense of the connectiveness of your wiki.


Download instructions[edit]

Please cut and paste the code found below and place it in $IP/extensions/SiteGraph/SiteGraph.php. Note: $IP stands for the root directory of your MediaWiki installation, the same directory that holds LocalSettings.php.

You also need the GraphViz extension for this plugin to work properly.

Installation[edit]

To install this extension, add the following to LocalSettings.php:

require_once("$IP/extensions/GraphViz/GraphViz.php");
require_once("$IP/extensions/SiteGraph/SiteGraph.php");

In a page of your choosing, use the <sitegraph> tag. Tweak it using options from the Graphviz manual. Here is an example:

<sitegraph type="digraph" layout="neato">
graph [
  center=true,
  fontname="Verdana",
  bgcolor="transparent",
  truecolor="true",
  fontsize=12,
  overlap="orthoyx",
  splines="true",
  pack="true",
  sep="0.1",
  dpi=62,
  ratio="compress",
  epsilon="0.001",
];

edge [
  fontsize=12,
  arrowsize=0.5,
  len=0.5
];

node [
  fontsize=12,
  shape="plaintext",
  height=0.25,
  width=0.25,
  fontcolor=blue,
];
</sitegraph>


Code[edit]

<?php
/*
 * SiteGraph.php - A MediaWiki tag extension for adding site graphs based on GraphViz.
 * @author Kenneth L. Root
 * @version 1.1.0
 * @copyright Copyright (C) 2007-2009 Kenneth L. Root
 * @license GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
 *
 * Updated July 30, 2010 by Chase.
 * -----------------------------------------------------------------------
 * Description:
 *     This is a MediaWiki extension which a site graph utilizing the
 *     GraphViz plugin and program.
 *
 * Installation:
 *     1. Place this in a directory (SiteGraph) under $IP/extensions
 *     2. Enable the extension by adding this line to your LocalSettings.php:
 *        require_once('extensions/SiteGraph/SiteGraph.php');
 *
 * Usage:
 *     Once installed, you may utilize SiteGraph by adding the <sitegraph> tag.
 *
 * Example:
 *
 * <sitegraph type="digraph" layout="neato">
 * graph [
 *   center=true,
 *   fontname="Verdana",
 *   bgcolor="transparent",
 *   truecolor="true",
 *   fontsize=12,
 *   overlap="orthoyx",
 *   splines="true",
 *   pack="true",
 *   sep="0.1",
 *   dpi=62,
 *   ratio="compress",
 *   epsilon="0.001",
 * ];
 *
 * edge [
 *   fontsize=12,
 *   arrowsize=0.5,
 *   len=0.5
 * ];
 *
 * node [
 *   fontsize=12,
 *   shape="plaintext",
 *   height=0.25,
 *   width=0.25,
 *   fontcolor=blue,
 * ];
 * </sitegraph>
 *
 * Version Notes:
 *     version 1.0.0:
 *     Initial release.
 * -----------------------------------------------------------------------
 * Copyright (c) 2007-2009 Kenneth L. Root
 *
 *    This program is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * -----------------------------------------------------------------------
 */


$wgExtensionFunctions[] = 'SiteGraph_init';
$wgExtensionCredits['parserhook'][] = array(
  'name' => 'SiteGraph',
  'version' => '1.1.0',
  'author' => '[http://the-b.org/ Kenny Root]',
  'url' => 'http://the-b.org/SiteGraph',
  'description' => 'Create a sitemap graph through GraphViz.',
);

/**
 * Sets up the SiteGraph Parser hook and system messages
 */
function SiteGraph_init() {
  global $wgParser, $wgMessageCache;
  $wgParser->setHook( 'sitegraph', 'SiteGraph_render' );
}

function SiteGraph_render($text, $params = array()) {
  global $wgContLang, $wgOut;
  
  $dbr = wfGetDB(DB_SLAVE);
  list($page, $pagelinks) = $dbr->tableNamesN('page', 'pagelinks');
  
  $type = "graph";
  if (array_key_exists('type', $params))
        $type = $params['type'];

  $layout = "dot";
  if (array_key_exists('layout', $params))
        $layout = $params['layout'];

  $html = array();
  $html[] = "<graphviz layout='$layout'>$type A {";
  $html[] = $text;
  
  $query = "SELECT
    page_namespace AS namespace,
    page_title AS title
    FROM $page
    WHERE page_namespace = ".NS_MAIN."
    AND page_is_redirect = 0";
  
  $res = $dbr->query($query);
  $num = $dbr->numRows($res);

  for ($i = 0; $i < $num && $row = $dbr->fetchObject($res); $i++) {
    $title = Title::makeTitleSafe($row->namespace, $row->title);
	
    $html[] = "\"". $row->title ."\" [label=\"" . htmlspecialchars($wgContLang->convert($title->getPrefixedText())) . "\" URL=\"" . 	$title->getLocalURL() . "\"];";
  }

  $query = "SELECT
    page1.page_namespace AS namespace1,
    page1.page_title AS title1,
    page2.page_namespace AS namespace2,
    page2.page_title AS title2
    FROM $page page1
    LEFT JOIN $pagelinks link1 ON page1.page_id = link1.pl_from
    LEFT JOIN $page page2 ON link1.pl_title = page2.page_title
    LEFT JOIN $pagelinks link2 ON page2.page_id = link2.pl_from
    WHERE link2.pl_title = page1.page_title
    AND page1.page_title < page2.page_title
    AND (page1.page_namespace = ".NS_MAIN." OR page1.page_namespace >= 100)
    AND (page2.page_namespace = ".NS_MAIN." OR page2.page_namespace >= 100)
    AND page1.page_is_redirect = 0
    AND page2.page_is_redirect = 0";
  
  $res = $dbr->query($query);
  $num = $dbr->numRows($res);

  for ($i = 0; $i < $num && $row = $dbr->fetchObject($res); $i++) {
    $html[] = "\"". $row->title1 ."\" -> \"". $row->title2 ."\" [dir=\"both\"];";
  }

  $query = "SELECT DISTINCT
    page1.page_namespace AS namespace1,
    page1.page_title AS title1,
    page2.page_namespace AS namespace2,
    page2.page_title AS title2
    FROM $page page1
    INNER JOIN $pagelinks link1 ON page1.page_id = link1.pl_from
    INNER JOIN $page page2 ON link1.pl_title = page2.page_title
    LEFT JOIN $pagelinks link2 ON ((page2.page_id = link2.pl_from) AND (page1.page_title = link2.pl_title))
    WHERE link2.pl_from IS NULL
    AND page1.page_id <> page2.page_id
    AND (page1.page_namespace = 0 OR page1.page_namespace >= 102)
    AND (page2.page_namespace = 0 OR page2.page_namespace >= 102)
    AND page1.page_is_redirect = 0 AND page2.page_is_redirect = 0;";
  
  $res = $dbr->query($query);
  $num = $dbr->numRows($res);

  if ($type == "graph")
        $connector = "--";
  else
        $connector = "->";

  for ($i = 0; $i < $num && $row = $dbr->fetchObject($res); $i++) {
    $html[] = "\"". $row->title1 ."\" ". $connector ." \"". $row->title2 ."\";";
  }

  $html[] = "}</graphviz>";

  return '<!-- ENCODED_SITEGRAPH '. base64_encode(implode($html, "\n")) . ' -->';
}

if (!function_exists('processSiteGraphOutput')) {
    $wgHooks['ParserAfterTidy'][] = 'processSiteGraphOutput';
    function processSiteGraphOutput(&$out, &$text) {
        global $wgOut;

        # Find all hidden content and restore to normal
        $matches = array();
        $nmatch = preg_match_all(
            '/<!-- ENCODED_SITEGRAPH ([0-9a-zA-Z\\+]+=*) -->/esm',
            $text,
            $matches,
            PREG_SET_ORDER);

        for ($i = 0; $i < $nmatch; $i++) {
            $text = str_replace(
                $matches[$i][0],
                $wgOut->parse(base64_decode($matches[$i][1])),
                $text);
        }
        return true;
    }
}

See also[edit]