転載・引用について

ユーザ用ツール

サイト用ツール


tweet:2009:0207_05

Blikiを整理

Blikiの入力画面には特に何も記載されていないので、Templateが扱えるかどうかを確認してみた。

結論から言えば、このコードはそこまで考慮して書かれていないので、Templateを導入することは出来なかった。
そこまでの対応をするくらいなら1から書いた方が早いかもしれない。そんな時間はないので、今回はここで諦めよう。

しかし、最初からHeaderと末尾にTag位は入れたいなぁ。

そうそう、コードを読んでたらあまりにも整形されていなかったので、手で整形し直した。ついでに、無駄な判断分があったので、一部修正。
まぁ、あんまりにも小さな修正なので、影響は皆無だろう。ま、いいか。取りあえず貼り付けてみる。

$ cat ./syntax.php
<?php
/**
 * bliki Plugin: Adds a simple blogging engine to your wiki
 * 
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Beau Lebens <beau@dentedreality.com.au>
 * @author     Anthony Caetano <Anthony.Caetano@Sanlam.co.za>
 * @author     HEO SeonMeyong <seirios.seirios.org>
 * 
 */
 
if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
 
/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_bliki extends DokuWiki_Syntax_Plugin {
 
    /**
     * return some info
     */
    function getInfo(){
        return array(
            'author' => 'Beau Lebens',
            'email'  => 'beau@dentedreality.com.au',
            'date'   => '2005-09-06',
            'name'   => 'Bliki: The Wiki Blog',
            'desc'   => 'Adds basic blogging functionality to any page of your wiki.',
            'url'    => 'http://www.dokuwiki.org/plugin:bliki',
        );
    }
 
    /**
     * What kind of syntax are we?
     */
    function getType(){
        return 'substition';
    }
 
    /**
     * What kind of syntax do we allow (optional)
     */
    function getAllowedTypes() {
        return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs');
    }
 
    /**
     * What about paragraphs? (optional)
     */
    function getPType(){
        return 'block';
    }
 
    /**
     * Where to sort in?
     */ 
    function getSort(){
        return 400;
    }
 
 
    /**
     * Connect pattern to lexer
     */
    function connectTo($mode) {
      $this->Lexer->addSpecialPattern('~~BLIKI~~', $mode, 'plugin_bliki');
    }
 
    /**
     * Handle the match
     */
    function handle($match, $state, $pos, &$handler){
        return array();
    }
 
    /**
    * @return Array
    * @param String $ID
    * @param Int $num
    * @param Int $offset
    * @desc Finds the full pathnames of the most recent $num posts, starting at the optional within the $ID blog/namespace.
    */
    function getPosts($ID, $num, $offset = 0) {
        global $conf;
        $recents = array();
        $counter = 0;
 
        // fully-qaulify the ID that we're working with (to dig into the namespace)
        $fp = wikiFN($ID);
        $ID = substr($fp, 0, strrpos($fp, '.'));

        // Only do it if the namespace exists
        if (is_dir($ID . '/')) {
            if ($conf['bliki']['structure'] == 'flat') {
                $posts = $this->read_dir_to_array($ID . '/', 'file', '/^[0-9]{4}-[0-9]{2}-[0-9]{2}-[0-9]{6}\.txt$/');
                sort($posts);
                while (sizeof($recents) < $num && sizeof($posts)) {
                    $post = array_pop($posts);
                    $counter++;
                    if ($counter > $offset) {
                        $recents[] = $ID . '/' . $post;
                    }
                }
                return $recents;
            } else {   // $conf['bliki']['structure'] == 'deep'
                $years = $this->read_dir_to_array($ID . '/', 'dir');
                sort($years);
                // Now start working backwards through it all and get the most recent posts
                while (sizeof($recents) < $num && sizeof($years)) {
                    $year = array_pop($years);
                    $months = $this->read_dir_to_array($ID . '/' . $year . '/', 'dir');
                    sort($months);
                    while (sizeof($recents) < $num && sizeof($months)) { 
                        $month = array_pop($months); 
                        $days = $this->read_dir_to_array($ID . '/' . $year . '/' . $month . '/', 'dir');
                        sort($days);
                        while (sizeof($recents) < $num && sizeof($days)) {
                            $day = array_pop($days);
                            $posts = $this->read_dir_to_array($ID . '/' . $year . '/' . $month . '/' . $day . '/', 
                                                              'file', 
                                                              '/^[0-9]{6}\.txt$/');
                            sort($posts);
                            while (sizeof($recents) < $num && sizeof($posts)) {
                                $post = array_pop($posts);
                                $counter++;
                                if ($counter > $offset) {
                                    $recents[] = $ID . '/' . $year . '/' . $month . '/' . $day . '/' . $post;
                                }
                            }
                        }
                    }
                }
                return $recents;
            }
        }
    }
 
    /**
    * @return String
    * @param Array $list
    * @desc Compiles the contents of all the files listed (as fully-qualified paths)  
    *       in $list into a single string. Compiles in the order listed. Adds date headers
    *       where required and a footer after each post.
    */
    function compilePosts($list) {
        global $ID, $conf;

        if (sizeof($list)) {
            $last_date = false;
            $str = '';
            foreach ($list as $file) {
                // Decide if we need to add a date divider
                $file = str_replace('\\', '/', $file);
                $ts = $this->getTimestampFromFile($file);
                $date = date('Y-m-d', $ts);
                if ($date != $last_date) {
                    $str .= $this->getDateHeader($ts);
                    $last_date = $date;
                }
                // Add this file's contents to the output
                $str .= file_get_contents($file);
                // And add a wiki-formatted footer of meta data as well, accounting for rewrites
                $post_url = $this->getUrlPartFromTimestamp($ID, $ts);
                $edit_url = $this->getRewriteUrl($post_url, 'do=edit', false);
                $timestamp = date($conf['bliki']['datefooter'], $ts);
                $str .= str_replace(array('{timestamp}', '{permalink}', '{edit}'), array($timestamp, $post_url, "this>$edit_url"), $conf['bliki']['footer']);
            }
            return $str;
        } else {
            return '';
        }
    }
 
    /**
    * @return String
    * @param timestamp $ts
    * @desc Returns a wiki-formatted date header for between posts.
    */
    function getDateHeader($ts) {
        global $conf;
 
        $date = date($conf['bliki']['dateheader'], $ts);
        return $date . "\n";
    }
 
    /**
    * @return timestamp
    * @param String $filename
    * @desc Returns a timestamp based on the filename/namespace structure
    */
    function getTimestampFromFile($file) {
        global $conf;
 
        if ($conf['bliki']['structure'] == 'flat') {
            $parts = explode('-', basename($file));
            $ts = mktime(substr($parts[3], 0, 2), substr($parts[3], 2, 2), substr($parts[3], 4, 2), $parts[1], $parts[2], $parts[0]);
        } else {  // $conf['bliki']['structure'] == 'deep'
            $parts = explode('/', dirname($file));
            $s = sizeof($parts);
            $date = $parts[$s-3] . '-' . $parts[$s-2] . '-' . $parts[$s-1];
            $filename = basename($file);
            $ts = mktime(substr($filename, 0, 2), substr($filename, 2, 2), substr($filename, 4, 2), $parts[$s-2], $parts[$s-1], $parts[$s-3]);
        }
        return $ts;
    }
 
    /**
    * @return String
    * @param String $ID
    * @param timestamp $ts
    * @desc Returns a post url for a post based on the post's timestamp and the base ID
    */
    function getUrlPartFromTimestamp($ID, $ts=0) {
        global $conf;
 
        if ($ts == 0) {
            $ts = time();
        }
        if ($conf['userewrite'] > 0) {
            $sep = ($conf['useslash'] == true ? '/' : ':');
        } else {
            $sep = ':';
        }
        if ($conf['bliki']['structure'] == 'flat') {
            return $ID . $sep . date('Y-m-d-His', $ts);
        } else { // $conf['bliki']['structure'] == 'deep'
            return $ID . $sep . date('Y' . $sep . 'm' . $sep . 'd' . $sep . 'His', $ts);
        }
    }
 
    /**
    * @return String
    * @param String $url
    * @param String $query
    * @desc Returns a url properly prefixed according to the $conf['rewrite'] option
    *       A $page is an appropriately constructed (namespace inclusive and considering $conf['useslash']) page reference
    *       A $query contains a query string parameters to append
    */
    function getRewriteUrl($page, $query, $base = true) {
        global $conf;

        if ($base) {
            $str = DOKU_BASE;
        }
        if ($conf['userewrite'] == 0) {
            $str .= DOKU_SCRIPT . '?id=' . $page;
            if ($query != '') {
                $str .=  '&' . $query;
            }
        } else if ($conf['userewrite'] == 1) {
            $str .= idfilter($page, false);
            if ($query != '') {
                $str .=  '?' . $query;
            }
        } else {
            $str .= DOKU_SCRIPT . '/' . idfilter($page, false);
            if ($query != '') {
                $str .=  '?' . $query;
            }
        }
        return $str;
    }
 
    /**
    * @return String
    * @param String $label
    * @desc Creates the HTML required for the "New Post" link, using the lable provided.
    */
    function newPostLink($label) {
        global $conf, $ID;
 
        $sep = ($conf['useslash'] == true ? '/' : ':');
        $html = '<div id="blognew"><a href="';
        $html .= $this->getRewriteUrl($this->getUrlPartFromTimestamp($ID, time() + (isset($conf['bliki']['offset']) ? ($conf['bliki']['offset'] * 3600) : 0)), 'do=edit');
        $html .= '">' . $label . '</a></div>';
        return $html;
    }
 
    /**
    * @return String
    * @param Int $page
    * @param String $label
    * @desc Creates the HTML required for a link to an older/newer page of posts. 
    */
    function pagingLink($page, $label) {
        global $conf, $ID;
 
        $html = '<a href="';
        $html .= $this->getRewriteUrl($ID, "page=$page");
        $html .= '">' . $label . '</a>';
        return $html;
    }
 
    /**
    * @return Array
    * @param String $dir
    * @param String $select
    * @param String $match
    * @desc Reads all entries in a directory into an array, sorted alpha, dirs then files.
    *       $select is used to selects either only dir(ectories), file(s) or both
    *       If $match is supplied, it should be a / delimited regex to match the filename against
    */
    function read_dir_to_array($dir, $select = 'both', $match = false) { 
        $files = array();
        $dirs  = array();
 
        // Read all the entries in the directory specified
        $handle = @opendir($dir);
        if (!$handle) {
            return false;
        }
        while ($file = @readdir($handle)) {
            // Ignore self and parent references
            if ($file != '.' && $file != '..') {
                if (($select == 'both' || $select == 'dir') && is_dir($dir . $file)) {
                    $dirs[] = $file;
                } else if (($select == 'both' || $select == 'file') && !is_dir($dir . $file)) { 
                    if (is_string($match)) {
                        if (!preg_match($match, $file)) {
                            continue;
                        }
                    }
                    $files[] = $file;
                }
            }
        }
        @closedir($handle);
 
        // Sort anything found alphabetically and combine the results (dirs->files)
        if (sizeof($dirs) > 0) {
            sort($dirs, SORT_STRING);
        }
        if (sizeof($files) > 0) {
            sort($files, SORT_STRING);
        }
 
        // Put the directories and files back together and return them
        return array_merge($dirs, $files);
    }
 
    /**
     * Create output
     */
    function render($mode, &$renderer, $data) {
        global $ID, $conf;

        // Set the page number (determines which posts we display)
        if (isset($_REQUEST['page'])) {
            $page = $_REQUEST['page'];
        } else {
            $page = 0;
        }
 
        if ($mode == 'xhtml') {
            // Addlink for creating a new post
            $renderer->doc .= $this->newPostLink($conf['bliki']['newlabel']);

            // Go and get the required blog posts and compile them into one wikitext string
            // FIXME $config var for how many? or inline directive?
            $recents = $this->getPosts($ID, $conf['bliki']['numposts'], ($page * $conf['bliki']['numposts']));
            $compiled = $this->compilePosts($recents);

            // Disable section editing to avoid weird links
            $conf['maxseclevel'] = 0;

            // Disbale caching because we need to get new files always
            $renderer->info['cache'] = false;

            // Add the compiled blog posts after rendering them.
            $renderer->doc .= p_render('xhtml', p_get_instructions($compiled), $info);

            // Add a link to older entries if we filled the number per page (assuming there's more)
            if (sizeof($recents) == $conf['bliki']['numposts']) {
                $renderer->doc .= '<div id="blogolder">' . $this->pagingLink($page+1, $conf['bliki']['olderlabel']) . '</div>';
            }

            // And also a link to newer posts if we're not on page 0
            if ($page != 0) {
                $renderer->doc .= '<div id="blognewer">' . $this->pagingLink($page-1, $conf['bliki']['newerlabel']) . '</div>';
            }
            return true;
        }
        return false;
    }
}
 
?>
$ 
追記

ああ、やっぱりTagをうち忘れた。後で困るって。

このウェブサイトはクッキーを使用しています。 Webサイトを使用することで、あなたはあなたのコンピュータにクッキーを保存することに同意します。 また、あなたはあなたが私たちのプライバシーポリシーを読んで理解したことを認めます。 同意しない場合はウェブサイトを離れてください。クッキーに関する詳細情報
tweet/2009/0207_05.txt · 最終更新: 2009/02/07 05:00 by 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki