MediaWiki RawFile: Difference between revisions

From miki
Jump to navigation Jump to search
(Created page with "__TOC__ '''RawFile''' is an extension made by Philippe Teuwen to allow downloading directly text in <tt><pre></tt> or <tt><source></tt> block as a file. This page is p...")
 
(→‎History: We have a work-around for templates)
 
(11 intermediate revisions by the same user not shown)
Line 11: Line 11:


* Download file {{file|RawFile.php}} below, and copy it to {{file|$IP/extensions/RawFile/RawFile.php}} on your mediawiki server.
* Download file {{file|RawFile.php}} below, and copy it to {{file|$IP/extensions/RawFile/RawFile.php}} on your mediawiki server.
{{hiddenSourceFile||RawFile.php|content=<source lang="php">
{{hiddenSourceFile||RawFile.php|content=<file name="RawFile.php" tag=source>2nd download link</file><source lang="php">
<?php
<?php


Line 46: Line 46:
else
else
$title = Title::newFromText( $titleText );
$title = Title::newFromText( $titleText );
//Don't expand templates or we'll lose our anchors {{#...}}
return $title->getFullURL( 'action=raw&anchor='.urlencode( $filename ) );
return $title->getFullURL( 'action=raw&anchor='.urlencode( $filename ) );
}
}
Line 53: Line 54:
}
}


function efRawFile_FileTagRender( $input, $args, &$parser ) {
function efRawFile_FileTagRender( $input, $args, $parser, $frame ) {
if( $args['title'] == '' )
if( $args['title'] == '' )
$title = $parser->mTitle;
$title = $parser->mTitle;
else
else
$title = Title::newFromText( $args['title'] );
$title = Title::newFromText($parser->recursiveTagParse( $args['title'], $frame ));

$link=$title->getFullURL( 'action=raw' );
//We expand templates, so <file> tag cannot be mixed with {{#fileanchor}} anchors
$link=$title->getFullURL( 'action=raw&templates=expand' );
if( $args['name'] != '' )
if( $args['name'] != '' )
$link.='&name='.urlencode( $args['name'] );
$link.='&name='.urlencode( $parser->recursiveTagParse( $args['name'], $frame ) );
if( $args['anchor'] != '' )
if( $args['anchor'] != '' )
$link.='&anchor='.urlencode( $args['anchor'] );
$link.='&anchor='.urlencode( $parser->recursiveTagParse( $args['anchor'], $frame ) );
if( $args['tag'] != '' )
if( $args['tag'] != '' )
$link.='&tag='.urlencode( $args['tag'] );
$link.='&tag='.urlencode( $parser->recursiveTagParse( $args['tag'], $frame ) );

return $parser->recursiveTagParse( "[$link $input]" );
return $parser->recursiveTagParse( "[$link $input]", $frame );
}
}


Line 78: Line 82:
$filename=$_GET['name'];
$filename=$_GET['name'];
$anchor=$_GET['anchor'];
$anchor=$_GET['anchor'];
// for backward compatibility, accept also URLs with parameter 'file'
if( $anchor=='' )
$anchor=$_GET['file'];
$tag=$_GET['tag'];
$tag=$_GET['tag'];
// Either anchor or name must be specified
// Either anchor or name must be specified
Line 87: Line 94:
// wfResetOutputBuffers();
// wfResetOutputBuffers();
header("Content-disposition: attachment;filename={$filename}");
header("Content-disposition: attachment;filename={$filename}");
header("Content-type: application/octetstream");
header("Content-type: application/octet-stream");
header("Content-Transfer-Encoding: binary");
header("Content-Transfer-Encoding: binary");
header("Expires: 0");
header("Expires: 0");
header("Pragma: no-cache");
header("Pragma: no-cache");
header("Cache-Control: no-store");
header("Cache-Control: no-store");
$maskedtext=preg_replace('!<nowiki>.*?</nowiki>!se',
$maskedtext=preg_replace_callback('!<nowiki>.*?</nowiki>!s',
'preg_replace("/\\\\\\\\\\\'|./","X","$0")',
function($m) { return ereg_replace(".","X",$m[0]); },
$text);
$text);
if (($anchor!='') && preg_match_all('/({{#fileanchor: *'.$anchor.' *}})|(<[^>]+ class *= *"([^"]*\w)?'.$anchor.'(\w[^"]*)?"[^>]*>)/i', $maskedtext, $matches, PREG_OFFSET_CAPTURE))
if (($anchor!='') && preg_match_all('/({{#fileanchor: *'.$anchor.' *}})|(<[^>]+ class *= *"([^"]*\w)?'.$anchor.'(\w[^"]*)?"[^>]*>)/i', $maskedtext, $matches, PREG_OFFSET_CAPTURE))
Line 127: Line 134:


$wgExtensionCredits['parserhook'][] = array('name' => 'RawFile',
$wgExtensionCredits['parserhook'][] = array('name' => 'RawFile',
'version' => '0.4',
'version' => '0.5.1',
'author' => 'Philippe Teuwen, Michael Peeters',
'author' => 'Philippe Teuwen, Michael Peeters',
'url' => 'http://www.mediawiki.org/wiki/Extension:RawFile',
'url' => 'http://www.mediawiki.org/wiki/Extension:RawFile',
Line 144: Line 151:
require_once("$IP/extensions/RawFile/RawFile.php");
require_once("$IP/extensions/RawFile/RawFile.php");
</source>
</source>

=== History ===
;Version 0.5.1
* See [http://wiki.yobi.be/wiki/Mediawiki_RawFile Yobi].
* Integrate patch from Jani Uusitalo to recursively parse tag attribute values in case they contain [https://www.mediawiki.org/wiki/Help:Magic_words magic words] such as wiki templates or parameters. This is useful when using <code>&lt;file>...</file></code> in wiki templates.
* Prepare fix for <code>anchor not found</code> bug when using short notation <code>&lt;file name="filename" [tag="''tagname''"]>link text</file></code> in wiki templates. This still doesn't work because of the way MediaWiki (v1.22.1) expands templates in raw output (see [https://bugzilla.wikimedia.org/show_bug.cgi?id=61341 bugzilla 61341]).
;Version 0.5-mip.2
* Expand templates in raw output when using tag <code>&lt;file></code> to improve use of this tag in template. This allows to have the file content to come from templates as well (see [https://www.mediawiki.org/wiki/Manual:Parameters_to_index.php#Raw Mediawiki parameters to index.php?action=raw]).
;Version 0.5-mip.1
* Import changes from [http://mummila.net/wiki/Koodilistaus:RawFile.php Mummila]. This allows expanding template parameters in <code>&lt;file></code> tag.
** Work-around available. See bugzilla bug report, or example section above.


== Examples ==
== Examples ==


;References
Examples as for version 0.4:
* [http://www.mediawiki.org/wiki/Manual:Tag_extensions Tag extensions on mediawiki.org]

Example below requires version 0.4 or above:


<pre><nowiki>
<pre><nowiki>
Line 177: Line 198:


This gives:
This gives:
<hr/>

* '''Method 1''': Returns the block that immediately follows. Save [{{#file: method1.txt}} this file]: <code>Hello, World!</code>
* '''Method 1''': Returns the block that immediately follows. Save [{{#file: method1.txt}} this file]: <code>Hello, World!</code>
: But this other example fails because of the &lt;br&gt; tag... So save [{{#file: method1-fail.txt}} this file]:<br>
: But this other example fails because of the &lt;br&gt; tag... So save [{{#file: method1-fail.txt}} this file]:<br>
Line 187: Line 208:
* '''Method 3''': Same as above, but using html attribute 'class'. Save [{{#filelink: method3.txt}} this file] (but not this <code>code text</code>):<br>
* '''Method 3''': Same as above, but using html attribute 'class'. Save [{{#filelink: method3.txt}} this file] (but not this <code>code text</code>):<br>
:{{#fileanchor: method3.txt}}<code>We can still </code> very easily <code class="method3.txt">interleave downloadable text with wiki comments but with less typing</code>
:{{#fileanchor: method3.txt}}<code>We can still </code> very easily <code class="method3.txt">interleave downloadable text with wiki comments but with less typing</code>
<code class="method3.txt">s
<code class="method3.txt">
Obviously, there is absolutely
Obviously, there is absolutely
no limitation
no limitation
Line 203: Line 224:
:{{#fileanchor: method6.txt}}<code>Again, we can </code>also very easily <code class="method6.txt">interleave downloadable code with wiki text while using the new syntax</code>
:{{#fileanchor: method6.txt}}<code>Again, we can </code>also very easily <code class="method6.txt">interleave downloadable code with wiki text while using the new syntax</code>


=== Example using templates ===
References:

* [http://www.mediawiki.org/wiki/Manual:Tag_extensions Tag extensions on mediawiki.org]
The new syntax <code>&lt;file name="..." [tag="..."]>...&lt;/file></code> allows for using the RawFile extension in templates as well.

The example below uses the template [[Template:Rawfiledownloadexample]] to avoid duplication between the file name in the text and as a parameter in the <code>&lt;file></code> tag.

See the template source for instructions on how to create the template.

<pre>
{{Rawfiledownloadexample|name=myfile.txt|content=Once upon a time
There was a Tag
Tag was clickable
And clicked it was}}
</pre>

The code above gives
<hr/>
{{Rawfiledownloadexample|name=myfile.txt|content=Once upon a time
There was a Tag
Tag was clickable
And clicked it was}}


== Patches ==
== Patches ==
Line 313: Line 353:
: The text of the link to display.
: The text of the link to display.
|}
|}

== Bugs ==
* RawFile does not work well in templates. This is because templates parameters in tag values are not expanded by MediaWiki. See [https://bugzilla.wikimedia.org/show_bug.cgi?id=61341 bugzilla 61341].

Latest revision as of 10:24, 17 February 2014

RawFile is an extension made by Philippe Teuwen to allow downloading directly text in <pre> or <source> block as a file.

This page is part of the pages dedicated to Mediawiki.

Download and install instructions

  • Download file RawFile.php below, and copy it to $IP/extensions/RawFile/RawFile.php on your mediawiki server.
  • Edit $IP/LocalSettings.php, and add to the end of the file:
require_once("$IP/extensions/RawFile/RawFile.php");

History

Version 0.5.1
  • See Yobi.
  • Integrate patch from Jani Uusitalo to recursively parse tag attribute values in case they contain magic words such as wiki templates or parameters. This is useful when using <file>...</file> in wiki templates.
  • Prepare fix for anchor not found bug when using short notation <file name="filename" [tag="tagname"]>link text</file> in wiki templates. This still doesn't work because of the way MediaWiki (v1.22.1) expands templates in raw output (see bugzilla 61341).
Version 0.5-mip.2
Version 0.5-mip.1
  • Import changes from Mummila. This allows expanding template parameters in <file> tag.
    • Work-around available. See bugzilla bug report, or example section above.

Examples

References

Example below requires version 0.4 or above:

* '''Method 1''': Returns the block that immediately follows. Save [{{#file: method1.txt}} this file]: <code>Hello, World!</code>
: But this other example fails because of the <br> tag... So save [{{#file: method1-fail.txt}} this file]:<br>
:<code>Hello, World!</code>.

* '''Method 2''': Indicates the block(s) with anchors. Save [{{#filelink: method2.txt}} this file] (but not this <code>code text</code>):<br>
:{{#fileanchor: method2.txt}}<code>We can then </code> very easily {{#fileanchor: method2.txt}}<code>interleave downloadable text with wiki comments</code>

* '''Method 3''': Same as above, but using html attribute 'class'. Save [{{#filelink: method3.txt}} this file] (but not this <code>code text</code>):<br>
:{{#fileanchor: method3.txt}}<code>We can still </code> very easily <code class="method3.txt">interleave downloadable text with wiki comments but with less typing</code>
<code class="method3.txt">
Obviously, there is absolutely
no limitation
on the size of the 
text
</code>

* '''Method 4''': Same as method 1, but using new syntax (custom wiki tag). Save <file name="method4.txt">'''this''' file</file>: <code>Hello, World!</code>

* '''Method 5''': Same as above, but specifying which tag to include. Save ''<file name="method5.txt" tag="code">this file</file>'':
<source lang="text">This text is skipped.</source>
:<code>This is the text that will be returned...</code>

* '''Method 6''': Same as method 2 / 3, but using new syntax (custom wiki tag). Save <file anchor="method6.txt">this file</file>. Of course the old syntax <code>{{#fileanchor}}</code> for anchor is still supported.<br>
:{{#fileanchor: method6.txt}}<code>Again, we can </code>also very easily <code class="method6.txt">interleave downloadable code with wiki text while using the new syntax</code>

This gives:


  • Method 1: Returns the block that immediately follows. Save [{{#file: method1.txt}} this file]: Hello, World!
But this other example fails because of the <br> tag... So save [{{#file: method1-fail.txt}} this file]:
Hello, World!.
  • Method 2: Indicates the block(s) with anchors. Save [{{#filelink: method2.txt}} this file] (but not this code text):
{{#fileanchor: method2.txt}}We can then very easily {{#fileanchor: method2.txt}}interleave downloadable text with wiki comments
  • Method 3: Same as above, but using html attribute 'class'. Save [{{#filelink: method3.txt}} this file] (but not this code text):
{{#fileanchor: method3.txt}}We can still very easily interleave downloadable text with wiki comments but with less typing

Obviously, there is absolutely no limitation on the size of the text

  • Method 4: Same as method 1, but using new syntax (custom wiki tag). Save <file name="method4.txt">this file</file>: Hello, World!
  • Method 5: Same as above, but specifying which tag to include. Save <file name="method5.txt" tag="code">this file</file>:
This text is skipped.
This is the text that will be returned...
  • Method 6: Same as method 2 / 3, but using new syntax (custom wiki tag). Save <file anchor="method6.txt">this file</file>. Of course the old syntax {{#fileanchor}} for anchor is still supported.
{{#fileanchor: method6.txt}}Again, we can also very easily interleave downloadable code with wiki text while using the new syntax

Example using templates

The new syntax <file name="..." [tag="..."]>...</file> allows for using the RawFile extension in templates as well.

The example below uses the template Template:Rawfiledownloadexample to avoid duplication between the file name in the text and as a parameter in the <file> tag.

See the template source for instructions on how to create the template.

{{Rawfiledownloadexample|name=myfile.txt|content=Once upon a time
There was a Tag
Tag was clickable
And clicked it was}}

The code above gives


You can download file "myfile.txt" below, just click this link: <file name="myfile.txt" tag="pre">myfile.txt</file>.

Once upon a time
There was a Tag
Tag was clickable
And clicked it was


Patches

I contributed some changes to RawFile. The patch are detailed below.

Patch v0.2 → v0.3

The patch below adds an optional parameter to hook {{#filelink}}. With 1 param, the file is fetched from the current page as usual:

Save [{{#filelink: fstab}} this file] in your <tt>/etc</tt> directory.

With 2 param, the 2nd param is telling which page to fetch the file from:

Save [{{#filelink: fstab|Config files - fstab}} this file] in your <tt>/etc</tt> directory.

Patch v0.3 → v0.4

Changes in v0.4

  • Anchors can be specified using html class attribute
  • New syntax for Links and Anchor-links:
<file [name="..."] [anchor="..."] [tag="..."] [title="..."] >Link text</file>
  • Support multiple files on the same page with same name.
  • Can specify the tag name of the block to download (to skip some irrelevant blocks when using an anchor-link).
  • Ignore <br> tag.
  • Some error reporting.

The extension introduces 3 elements:

Anchor
Used to flag that the next code block in the wiki text belongs to a specific file. The code block can be any wiki block (such as <pre>, <code>, <tt>, <source>...). <br> tags are ignored. Note that anchors are invisible in the wiki display.
Link
They are transformed by the extension into links that allows for downloading all blocks attached to a given anchor name.
Anchor-link
A shortcut notation mixing both an anchor and download link, handy for regular use, when a single code block is used and when the download link can be at the same position as the anchor.

The syntax is as follows. The syntax using tag <file> and tag attribute class is new since v0.4. Note that elements of both syntaxes can be mixed in a same page.

Element Syntax and description
Anchor
{{#fileAnchor: anchorname}}
<pre class='anchorname'>...</pre>
<code class="anchorname">...</code>
<code class="cssclass anchorname">...</code>
...

Indicates that the next wiki block is attached to an anchor anchorname. The content of that block will be downloaded (possibly appended with other blocks if there are several blocks attached to the same anchorname) when a file link is clicked on.
(since v0.4) To attach an anchor anchorname to a wiki block, simply add an attribute class="anchorname" to it. The extension supports multi-class specification, meaning that a same block can be associated to different files, and that the class attribute can still be used to specify custom CSS properties as in standard wiki text.

anchorname
class="anchorname"
The name of the anchor to which the wiki block is attached
Link
[{{#fileLink: anchorname}} link text]
[{{#fileLink: anchorname|pagetitle}} link text]
<file anchor="anchorname" [name="filename"] [title="pagetitle"]>link text</file>

Creates a link to download all blocks that are attached to an anchor anchorname.

anchorname
anchor="anchorname"
The name of the anchor to look for. All blocks attached to an anchor anchorname will be downloaded.
name="filename"
Optional - Specifies the name of the file to download. If absent, anchorname is then used as the name of the downloaded file.
pagetitle
tag="pagetitle"
Optional - Indicates that the blocks to download are on the wiki page titled pagetitle. If absent, blocks are looked for on the current page.
link text
The text of the link to display.
Anchor-link
[{{#file: filename}} link text]
<file name="filename" [tag="''tagname''"]>link text</file>

Creates a link to download the next wiki block as a file named filename.
(since v0.4) The attribute tag can be used to specify the tagname of the block to download.

filename
name="filename"
The name of the file to download.
tag="tagname"
Optional - When set, the extension only looks for blocks whose name matches the given tagname. This attribute is particularly useful when there are some irrelevant blocks between the anchor-link and the block you want to download. If absent, the first encountered block following the anchor is downloaded.
link text
The text of the link to display.

Bugs

  • RawFile does not work well in templates. This is because templates parameters in tag values are not expanded by MediaWiki. See bugzilla 61341.