Topic on Skin talk:Chameleon

TOC as component type

7
DrLulzMD (talkcontribs)

How could I create a new component using the TOC? Would it involve more than just creating a TOC.php under /skins/chameleon/Components?

I'm looking to do something like the below in the xml layout.

<row>
	<cell span="10">
		<component type="MainContent"></component>
	</cell>
	<cell span="2">
		<component type="TableOfContents"></component>
	</cell>
</row>
F.trott (talkcontribs)

Yes, that should be all that's needed. Although the type and the file name and the class name should all be the same, e.g. TableOfContents in your case. Just make TableOfContents a subclass of Component.php and implement the getHtml() method. Have a look at Silent.php for a minimal implementation.

DrLulzMD (talkcontribs)

Thank you for replying. I'm quite new to php, but do have some understanding of what should be done to achieve the above. In addition to Silent.php is there another subclass .php which I can model that is similar to my goal?

F.trott (talkcontribs)

Any of the other component classes. The simpler ones are maybe PersonalTools or Logo. In principle you just need to return the HTML code of your component. The question is, where to get the HTML for the TOC from. For that you will need to search the MW code base, i.e. find where/how the TOC is built and where (if anywhere) it is stored. If it is stored somewhere, great, just grab it. If not, call the method, that builds it. You will probably also need to suppress integration of the TOC into the page text.

In your component you can get the Skin object by calling $this->getSkin(). From there you can find your way to a number of other relevant object, e.g. for the OutputPage use $skin->getOutput(). Just saw, that OutputPage has the methods enableTOC() and isTOCEnabled(). Maybe search from where these are called.

DrLulzMD (talkcontribs)

Indeed. I was looking at getPersonalTools and getFooterLinks and was hoping there was something similar for toc, but I think not.

So I'll need to implement something that iterates through all available toc elements?

F.trott (talkcontribs)

I don't think so. The TOC is displayed already (in the page text normally), so the code should exist somewhere. You just need to find out where.

FunkyBeats99 (talkcontribs)

It is probably not the cleanest way to do it, and I am no PHP maniac either, but it seems to work:

  • Download Extension:DeToc and follow the installation instructions (it is a really light extension);
  • Create a TableOfContents.php file in the Components folder of the Chameleon skin. It must contain the following:
<?php
namespace Skins\Chameleon\Components;
use DeToc;
/**
* TableOfContents class.
*
* This class extracts the table of contents, normally inside the page text, and makes it a component.
* It uses the DeToc extension
*
*/
class TableOfContents extends Component {
    public function getToc() {
        $new_body = DeToc::RemoveToc( $this->mSkinTemplate->data[ 'bodycontent' ], $extracted_toc );
        return $extracted_toc;
    }
    /**
     * Builds the HTML code for this component
     *
     * @return String the HTML code
     */
    public function getHtml() {
        return '<div id="newtoc">' . $this->getToc() . '</div>';
    }
}

To use this new "extracted" ToC, you would have to add the component, in the way you want it, to your custom layout, i.e. custom.xml :

<component type="TableOfContents"/>

You would of course need to hide the usual table of contents thanks to CSS by placing these lines in MediaWiki:Common.css or MediaWiki:Chameleon.css :

#toc {
display: none;
}

This is tested with Chameleon 4.0 but it should work with previous releases.

Reply to "TOC as component type"