在 DokuWiki 的 render 阶段修改指令

您的问题是关于在 DokuWiki 插件的 render() 方法中获取并修改指令的示例。

在 DokuWiki 中,通常 render() 方法接收的是已经处理过的数据,而不是原始指令。但是,有几种方法可以在渲染阶段获取和修改指令:

1. 使用 nest() 方法处理修改后的指令

最直接的方法是使用 nest() 方法,它允许您传入一组指令并执行它们:

public function render($mode, Doku_Renderer $renderer, $data) {  
    if ($mode !== 'xhtml') return false;  

    // 获取原始指令  
    $instructions = p_get_instructions($data['text']);  

    // 修改指令  
    foreach ($instructions as &$instruction) {  
        if ($instruction[0] === 'header') {  
            // 修改标题级别,例如将所有标题提升一级  
            $instruction[1][1] = max(1, $instruction[1][1] - 1);  
        }  
    }  

    // 使用修改后的指令  
    $renderer->nest($instructions);  

    return true;  
}

这个示例中,我们获取了原始指令,修改了所有标题的级别,然后使用 nest() 方法执行修改后的指令。

2. 创建自定义渲染器

另一种方法是创建一个自定义渲染器,它可以拦截和修改指令的执行:

class MyCustomRenderer extends Doku_Renderer_xhtml {  
    public function header($text, $level, $pos) {  
        // 修改标题级别  
        $level = max(1, $level - 1);  
        // 调用父类方法  
        parent::header($text, $level, $pos);  
    }  
}  

public function render($mode, Doku_Renderer $renderer, $data) {  
    if ($mode !== 'xhtml') return false;  

    // 创建自定义渲染器  
    $customRenderer = new MyCustomRenderer();  

    // 获取指令  
    $instructions = p_get_instructions($data['text']);  

    // 使用自定义渲染器执行指令  
    foreach ($instructions as $instruction) {  
        if (method_exists($customRenderer, $instruction[0])) {  
            call_user_func_array([$customRenderer, $instruction[0]], $instruction[1] ?: []);  
        }  
    }  

    // 将自定义渲染器的输出添加到原始渲染器  
    $renderer->doc .= $customRenderer->doc;  

    return true;  
}

3. 实际示例:bin/render.php

DokuWiki 的 bin/render.php 命令行工具提供了一个实际的例子,展示了如何获取指令并将其传递给渲染器: render.php:51-60

在这个示例中,p_get_instructions($source) 获取指令,然后将它们传递给 p_render() 函数进行渲染。

4. 使用 p_render() 函数

p_render() 函数是 DokuWiki 中处理指令渲染的核心函数: parserutils.php:688-693

您可以在自己的插件中使用类似的方法:

public function render($mode, Doku_Renderer $renderer, $data) {  
    if ($mode !== 'xhtml') return false;  

    // 获取指令  
    $instructions = p_get_instructions($data['text']);  

    // 修改指令  
    foreach ($instructions as &$instruction) {  
        // 修改指令...  
    }  

    // 创建一个临时渲染器  
    $tempRenderer = new Doku_Renderer_xhtml();  

    // 执行修改后的指令  
    foreach ($instructions as $instruction) {  
        if (method_exists($tempRenderer, $instruction[0])) {  
            call_user_func_array([$tempRenderer, $instruction[0]], $instruction[1] ?: []);  
        }  
    }  

    // 将临时渲染器的输出添加到原始渲染器  
    $renderer->doc .= $tempRenderer->doc;  

    return true;  
}

5. 使用 nest() 方法的实际实现

DokuWiki 的 nest() 方法是专门设计用来执行指令的: renderer.php:136-144

这个方法遍历指令数组,并对每个指令调用相应的渲染器方法。

总结

在 DokuWiki 的 render() 阶段修改指令的关键步骤是:

  1. 获取指令(通常使用 p_get_instructions()
  2. 修改指令数组
  3. 使用 nest() 方法或手动遍历执行修改后的指令

这种方法允许您在渲染阶段完全控制内容的呈现方式,而不仅仅是修改最终的 HTML 输出。

注意事项

  • 修改指令可能会影响缓存,您可能需要禁用缓存($renderer->info['cache'] = false;
  • 确保您的修改不会破坏文档结构(例如,确保开始和结束标签匹配)
  • 不同的渲染模式(如 xhtml、metadata 等)可能需要不同的处理方式
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇