relativens plugin

relativens plugin by Peter Lamberg
Links & media that don't start with / or : default to being relative to the namespace in which the current page is.

Last updated on 2008-12-31. Provides Syntax.
Compatible with DokuWiki 2008-05-05.

Conflicts with relativelinks!
Similar to relativelinks.

Tagged with links, namespace.

    This plugin is a remake of relativelinks plugin. This does basically the same thing, but is implemented in a more subtle way. It also tries to handle media.

    Download and Installation

    Download and install the plugin using the Plugin Manager using the following URL. Refer to Plugins on how to install plugins manually.

    Code

    <?php
    /**
     * Plugin relativens: Links & media that don't start with / or : default
     * to being relative to the namespace in which the current page is.
     *
     * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
     * @author     Peter Lamberg (pe78 [at] pelam dot fi)
     * @based_on   "pagespace" plugin by Symon Bent and "baselink" plugin Robert Meerman. Contains portion of code from DokuWiki source file handler.php.
     */
     
    if(!defined('DOKU_INC')) die();
     
    if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
    require_once(DOKU_PLUGIN.'syntax.php');
     
    class syntax_plugin_relativens extends DokuWiki_Syntax_Plugin {
     
        function getInfo() {
            return array('author' => 'Peter Lamberg',
                         'email'  => 'pe78 [at] pelam dot fi',
                         'date'   => '2008-12-30',
                         'name'   => 'relativens',
                         'desc'   => "Plugin relativens: Links & media that don't start with / or : default to being relative to the namespace in which the current page is.",
                         'url'    => 'http://www.dokuwiki.org/plugin:relativens');
        }
     
        function getType() {
            return 'substition';
        }
     
        // before built in links & media
        function getSort(){ return 299; }
     
        function connectTo($mode) {
            $this->Lexer->addSpecialPattern("\[\[.+?\]\]",$mode,'plugin_relativens');
            $this->Lexer->addSpecialPattern("\{\{[^\}]+\}\}",$mode,'plugin_relativens');
        }
     
        function handle($match, $state, $pos, &$handler) {
            // Following link parsing code is originally copied from Dokuwiki handler.php
     
            // See which one we caught
            $isMedia = preg_match('/^\{\{/', $link);
     
            $isMedia = 0;
     
            $originalMatch = $match;
     
            // Strip the opening and closing markup
            // At same time detect if this is media or link
            // handler.media and handler.internallink do this too, but
            // they don't check if they replaced anything.
            $match = preg_replace(array('/^\{\{/','/\}\}$/u'),'',$match, 2, $isMedia);
            $match = preg_replace(array('/^\[\[/','/\]\]$/u'),'',$match, 2);
     
            // Split title from URL
            $linkAndTitle = preg_split('/\|/u',$match,2);
            $linkTrimmed = trim($linkAndTitle[0]);
     
            $modifiedMatch = $originalMatch;
     
            // Give special treatment to the first few characters
            // of internal links and media links (media links are always "internal"?).
            // Sadly excluding the non internal links is a complicated process
            // and we end up doing it twice, but at least the results of these
            // handle functions are cached.
            if($isMedia || $this->isLinkInternal($linkTrimmed)) {
                // unless it's explicitly absolute,
                // Make it look like relative
                $modifiedMatch = preg_replace('/(^(?:\[\[|\{\{)\s*)(?![\:\/])/', '\\1./', $modifiedMatch, 1);
            }
            // let the regular handler take care of the rest
            if($isMedia) {
                $handler->media($modifiedMatch, $state, $pos);
            }
            else
            {
                $handler->internallink($modifiedMatch, $state, $pos);
            }
        }
     
     
        function isLinkInternal($linkPart) {
            // If conditions copied from Dokuwiki handler.php
            if ( preg_match('/^[a-zA-Z\.]+>{1}.*$/u',$linkPart) ) {
                return false;
            }elseif ( preg_match('/^\\\\\\\\[\w.:?\-;,]+?\\\\/u',$linkPart) ) {
                return false;
            }elseif ( preg_match('#^([a-z0-9\-\.+]+?)://#i',$linkPart) ) {
                return false;
            }elseif ( preg_match('<'.PREG_PATTERN_VALID_EMAIL.'>',$linkPart) ) {
                return false;
            }elseif ( preg_match('!^#.+!',$linkPart) ) {
                return false;
            }else{
                return true;
            }
        }
     
        function render($mode, &$renderer, $data) {
            // Should never come here, since we leech the original handler for most processing
            return false;
        }
     
    }

    PHP4

    This code assumes php5 because of the preg_replace call - it has one argument too much for php4. To get it working on php4, change

    $match = preg_replace(array('/^\{\{/','/\}\}$/u'),'',$match, 2, $isMedia);
    

    to

    $match = preg_replace(array('/^\{\{/','/\}\}$/u'),'',$match, 2);
    

    To let it work more proper with media in php4 nevertheless, also change

           // See which one we caught
            $isMedia = preg_match('/^\{\{/', $link);
    
            $isMedia = 0;
    

    To

           // See which one we caught
            $isMedia = preg_match('/^\{\{/', $match);
    
            // $isMedia = 0;
    

    I'm not sure what all this implies, but it seems to be working here.

    Allthough using this fix, other plugins that use the media link format (like { { mp3play>your:link:here } } ) seem to loose their trigger and get displayed as a normal media link.

    pike 200901

    I have also noticed some weird behaviour with media links…

    I think I can see why that “mp3play” link would not work. The plugin assumes that:

    • Only “internal links” should be “relativized”
      • Links with special syntax like “mp3play>” are not considered”internal links”
    • Except, that all media links are considered “internal”

    Then I think it proceeds and mucks up that mp3play> prefix by inserting ./ at the wrong place

    The code that mangles the link to be relative should be made more sensible, or the assumption that media links are always relative should be removed…

    I'll try to fix this and the php4 compatibility next time I need to hack our internal wiki…

    Peter 200907

     
    plugin/relativens.txt · Last modified: 2009/10/07 15:59 by laynee
     
    Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
    Imprint Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki
    WikiForumIRCBugsGitXRefTranslate