DokuWiki

It's better when it's simple

User Tools

Site Tools


plugin:spoiler

This is an old revision of the document!


Spoiler Plugin

Compatible with DokuWiki

2007-06-26+, Lemming, Anteater, Rincewind, Angua, Adora Belle, Weatherwax, Binky, Ponder Stibbons, Hrun, Detritus, Greebo

plugin Adds initially hidden sections

Last updated on
2007-07-19
Provides
Syntax

This extension has not been updated in over 2 years. It may no longer be maintained or supported and may have compatibility issues.

Similar to folded, stepbystep, togglewrap, wrap

Tagged with hide

Spoiler tag for DokuWiki. Allows sections that are initially hidden, and are shown when a “Show” button is clicked. The spoiler can be hidden again by pressing the button. An optional title can be given, otherwise a “Spoiler:” text is shown before the button.

Syntax

<spoiler>Content with default title</spoiler>
<spoiler |Plot details>The butler did it!</spoiler>
<spoiler>
This spoiler contains another spoiler
<spoiler>8-o</spoiler>
</spoiler>

You can make a button for this code with plugin:custombuttons.

See https://wiki.hokkanen.org/projects/dokuwiki/spoiler FIXME for images, playground, and download.

Discussion

I'd like to see it work within a list:

  * <spoiler>
    * Foo
    * Bar
    </spoiler>

This would be a very helpful bonus to this already very helpful plugin.

Yes, it doesn't work with latest Dokuwiki version. Perhaps author would never come with solution as plugin released in 2007…


Patch to provide control over all 'spoiler' items in a page

Usage:

%%~~SPOILER:open|Label Text~~%%
%%~~SPOILER:close|Label Text~~%%
%%~~SPOILER:hide|Label Text~~%%
%%~~SPOILER~~%%

Default behaviour is open, which is to un-hide all spoiler items, this is opposite of using <spoiler> without ~~SPOILER~~.

Permitted modes are:

  • open : All spoiler tags are expanded and visible when the page is rendered
  • close: All spoiler tags are collapsed (closed) and visible when the page is rendered
  • hide : All spoiler tags are not visible and the button to open/close them is not rendered

The Label Text works similar to <spoiler>.

Here are the code changes to style.css and syntax.php:

*** ./style.css Wed Jul 18 14:14:43 2007
--- ./new_style.css     Tue Nov 17 15:43:41 2009
***************
*** 24,26 ****
--- 24,47 ----
        margin-top: 0.5em;
  }
 
+ .spoilerctrl {
+       margin-top: 0.5em;
+       margin-bottom: 1em;
+ }
+
+ .spoilerctrl .title {
+       /* font-size: 110%; */
+       font-size: 90%;
+       font-weight: bold;
+       display: block;
+       float: left;
+ }
+
+ .spoilerctrl .title:after {
+       content: ': ';
+ }
+
+
+ .spoilerctrl input {
+       font-size: 70%;
+ }
*** ./syntax.php        Thu Jul 19 15:32:57 2007
--- ./new_syntax.php    Tue Nov 17 15:43:41 2009
***************
*** 56,61 ****
--- 56,62 ----
        function connectTo($mode) {
                // Lookahead assertion: check that there is an end tag.
                $this->Lexer->addEntryPattern('<spoiler[^>\r\n]*?>(?=.*?</spoiler>)', $mode, 'plugin_spoiler');
+               $this->Lexer->addSpecialPattern('~~SPOILER[^~\r\n]*?~~', $mode, 'plugin_spoiler');
        }
 
        function postConnect() {
***************
*** 73,88 ****
                                        $title = substr($options, strpos($options, '|') + 1);
                                }
 
!                               return array($state, $title);
                                break;
                        case DOKU_LEXER_MATCHED :
                                break;
                        case DOKU_LEXER_UNMATCHED :
!                               return array($state, $match);
                                break;
                        case DOKU_LEXER_EXIT :
                                break;
                        case DOKU_LEXER_SPECIAL :
                                break;
                }
                return array($state);
--- 74,108 ----
                                        $title = substr($options, strpos($options, '|') + 1);
                                }
 
!                               return array($state, $title, '');
                                break;
                        case DOKU_LEXER_MATCHED :
                                break;
                        case DOKU_LEXER_UNMATCHED :
!                               return array($state, $match, '');
                                break;
                        case DOKU_LEXER_EXIT :
                                break;
                        case DOKU_LEXER_SPECIAL :
+                               // "~~SPOILER" options "~~"
+                               $options = substr($match, 8, -2);
+
+                                 $endPos = strlen($options) + 1;
+                               if (strpos($options, '|') !== False) {
+                                         $endPos = strpos($options,'|');
+                                       $title = substr($options, $endPos + 1);
+                               }
+
+                                 $switch = 'show';
+                                 $options = substr($options,1,$endPos - 1);
+                               if (strpos($options, ':') !== False) {
+                                         $startPos = strpos($options,':');
+                                       $switch = substr($options, $startPos + 1, $endPos - ($startPos + 1));
+                               }
+
+                                 if ($title == '') $title = 'Spoiler Control';
+
+                               return array($state, $title, $switch);
                                break;
                }
                return array($state);
***************
*** 90,96 ****
 
        function render($mode, &$renderer, $data) {
                if($mode == 'xhtml'){
!                       list($state, $payload) = $data;
 
                        switch ($state) {
                                case DOKU_LEXER_ENTER :
--- 110,116 ----
 
        function render($mode, &$renderer, $data) {
                if($mode == 'xhtml'){
!                       list($state, $payload, $switch) = $data;
 
                        switch ($state) {
                                case DOKU_LEXER_ENTER :
***************
*** 100,105 ****
--- 120,139 ----
                                        break;
                                case DOKU_LEXER_MATCHED :
                                        break;
+                               case DOKU_LEXER_SPECIAL :
+                                       $script = "if (this.value == 'Show All') { spoilerControl(1); this.value = 'Hide All' } else { spoilerControl(0); this.value = 'Show All' }";
+                                         switch($switch){
+                                             case 'close':
+                                               $renderer->doc .= '<div class="spoilerctrl"><div class="title">'. $payload .'</div><input type="button" value="Show All" onClick="'. $script .'" /></div><script type="text/javascript">spoilerControl(0);</script>';
+                                                 break;
+                                             case 'hide':
+                                               $renderer->doc .= '<script type="text/javascript">spoilerControl(0);</script>';
+                                                 break;
+                                             default:
+                                               $renderer->doc .= '<div class="spoilerctrl"><div class="title">'. $payload .'</div><input type="button" value="Hide All" onClick="'. $script .'" /></div>';
+                                                 break;
+                                         }
+                                       break;
                                case DOKU_LEXER_UNMATCHED :
                                        $renderer->doc .= $renderer->_xmlEntities($payload);
                                        break;

Also, add the file script.js:

function spoilerControl(state) {
    var el = document.getElementsByTagName('DIV');
    for(var j=0; j < el.length; j++) {
    var className = el[j].className;
    if (className == "spoiler") {
        if (state == 1) {
            el[j].style.display = '';
        }else {
            el[j].style.display = 'none';
        }
    }
    }
}

This extra file hides away any 'spoiler' items when printing (call it print.css):

div.dokuwiki .spoiler {
    visibility: hidden;
    display: none;
}
div.dokuwiki .spoilerctrl {
    visibility: hidden;
    display: none;
}

– Chris Usher 2009-11-17


Problems

  • Spoiler will not work in a table
  • Bug with apostrophe ' in spoiler title
    • Put string $payload = str_replace(“'”,“’”,$payload); after string list($state, $payload) = $data;
  • Spoiler can't hold include syntax inside. Include will be showed under it
  • No spacing after first paragraph in spoiler, cause it come without '<p></p>' html tags.
plugin/spoiler.1588659199.txt.gz · Last modified: 2020-05-05 08:13 by mekineer

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki