Revision [20129]
This is an old revision of WikiFile made by ChewBakka on 2008-07-16 01:50:39.
WikiFile action and handler
In Wikka, almost everything is a page.
For example, a category is a page to which other pages link. If you want to start a new category, you do not need to learn something new - just create the category page and link your pages to it.
Here I would like to present a solution where a file is represented by a page too. I will first give a description on how to use it, then the necessary pieces of code.
You can also think of files as attachments; any wikka page can have at most one attachment.
I did everything in Wikka 1.1.6.2 so I can not tell whether it will work in older versions.
How to use it
Example: assume you have a photograph of the Millennium Falcon in a file named IMG_1234.JPG on your computer. You want to put it in the wiki.
First you create a page for the image, say MillenniumFalconOnTatooine, as follows, and save it.
MillenniumFalconOnTatooine
===== Millennium Falcon photograph =====
Photograph of the Millennium Falcon, last year on Tatooine.
There was lots of sand, as always.
{{file}}
Photograph of the Millennium Falcon, last year on Tatooine.
There was lots of sand, as always.
{{file}}
The page now shows a form which allows you to upload the file.
After uploading, you see the image in the page, and below the image another upload form is visible, in case you want to replace the photo with another one later.
In order to display the image on other pages, include the following modified file action in the other page:
Code for embedding an image from another page
{{file page="MillenniumFalconOnTatooine"}}
This will display the image on another page.
And of cause all of this works with other file types too. If a file is not an image, then the file action displays an URL through which you can download the file.
How to install it
We are going to add two program files to the Wikka software, and create a folder.
In your Wikka root directory, there is a folder named actions which contains several php files. Save the following code (use the grab button) as file.php in the actions folder.
actions/file.php (line 1)
- <?php
- /**
- * WikiFile action
- *
- * Display the page's file, either inline or as link.
- *
- * If the file is an image, then it is displayed inline.
- * For other file types, a download link is printed.
- * Note that at most one file can be stored in a page.
- *
- * Syntax:
- * {{file [page="SomeWikkaName"]}}
- *
- * @package Actions
- * @name File
- *
- * @author {@link http://wikkawiki.org/ChewBakka ChewBakka} (first draft)
- *
- * @input string $page: name of the page whose file is to be displayed.
- * optional; default is the current page itself.
- */
- /**
- * Return an array describing the file which is stored in a page.
- *
- * @author {@link http://wikkawiki.org/ChewBakka ChewBakka} (first draft)
- * @input $tag name of the page; default = current page.
- * @output Array or (if no file in page) null. Keys:
- * extension file extension, e.g. 'png', 'jpg', 'ogg'
- * content-type mime content type, e.g. 'image/png'
- * uploaded when and who,. e.g. '2007-01-31 ChewBakka'
- * image 'yes' or 'no'
- * width Width in pixels (images only)
- * height Height in pixels (images only)
- * filename PageName.ext
- * path upload_path/PageName.extension
- * url 'http://..../PageName/file'
- */
- {
- function getFile( $tag, $wikka )
- {
- $data = null; // this variable will be returned
- $metafile = $wikka->config['upload_path'].'/'.$tag.'.file'; // metadata
- {
- // Lines look like "key: value" -> convert into array
- 'extension' => '',
- 'content-type' => '',
- 'uploaded' => '<unknown> <unknown>',
- 'image' => 'false',
- 'width' => '',
- 'height' => '',
- 'filename' => '',
- 'path' => '',
- 'url' => ''
- );
- foreach ($lines as $line)
- {
- {
- }
- }
- // Convenient attributes which can not be stored permanently
- $data['filename'] = $tag . '.' . $data['extension'];
- $data['path'] = $wikka->config['upload_path'] .'/' . $data['filename'];
- $data['url'] = $wikka->config['base_url'] . $tag . '/file';
- // Final check: file must exist.
- {
- $data = null;
- }
- }
- return $data;
- }
- }
- /**
- * Here the real action starts
- */
- // Initialize variables
- $output = ''; // The HTML code that is being generated by this action
- $uploadform = False; // Show an upload form instead of the file?
- $tag = $this->GetPageTag(); // The page that the user requested
- {
- $tag = $vars['page'];
- }
- $data = getFile($tag,$this);
- // Check whether current user has read access and if there is a file.
- if ($this->HasAccess( 'read', $tag ) && $data )
- {
- if ($data['image'] == 'true')
- {
- // Image file - create an <img> tag
- $output = '<a href="' . $tag . '">'
- . '<img src="' . $data['url'] . '"'
- . ' width="' . $data['width'] . '"'
- . ' height="' . $data['height'] . '"'
- . ' alt="' . $tag . '"'
- . ' border="0">'
- . '</a>';
- }
- else
- {
- // Plain file - create a download link
- $output = '<a href="' . $data['url'] . '">' . $data['url'] . '</a>';
- }
- }
- if ($this->HasAccess( 'write', $tag ) && $tag == $this->GetPageTag())
- {
- // If on the same page, also show an upload form
- $headline = 'Attach a file to this page';
- $buttonlabel = 'Attach selected file';
- if( $data )
- {
- $headline = 'Replace above file/image with another one'
- . '<br />'
- . '(Note: if you do this, the new file/image will appear '
- . 'INSTEAD of the existing file/image everywhere in the wiki!)'
- ;
- $buttonlabel = 'REPLACE FILE/IMAGE (THINK TWICE!!!)';
- }
- $miniref = $this->Href('file', $tag);
- $output = $output
- . '<br />' . $headline . ' <br />'
- . '<form action="' . $miniref . '" method="POST" enctype="multipart/form-data">'
- . (!$this->config["rewrite_mode"] ? '<input type="hidden" name="wakka" value="' . $miniref . '" />' : '')
- . '<input name="file" type="file" size="72">'
- . '<input type="submit" value="' . $buttonlabel . '">'
- . '</form><br />'
- ;
- }
- print $this->ReturnSafeHTML($output);
- ?>
Also in your Wikka root directory, there is a folder named handlers, which in turn contains a folder names page which contains several php files. Save the following code (use the grab button) as file.php in the handlers/page folder. (Yes, we have two files with the same name, but in different locations and with different function).
handlers/page/file.php (line 1)
- <?php
- /**
- * WikiFile handler
- *
- * @package Handlers
- * @name File
- *
- * @author {@link http://wikkawiki.org/ChewBakka ChewBakka} (first draft)
- *
- * @input ?action=get returns the file via http
- * uploading a file causes storage of the file "in the page",
- * overwriting any previous page file.
- *
- */
- /**
- * mimeTypeFromExtension()
- * Return mime type for the given file extension.
- * Slow, but useful if PHP's mime_content_type() cannot be used.
- * Uses Wikka's mime_types.txt and some hardcoded associations.
- *
- * @author {@link http://wikkawiki.org/ChewBakka ChewBakka} (first draft)
- * @input $extension file extension, e.g. 'png', 'jpg', 'ogg'
- * @output mime content type, e.g. 'image/png', or empty string.
- */
- function mimeTypeFromExtension( $extension, $wikka )
- {
- // Quick resonse for most frequently used file types
- if ($extension == 'png') return 'image/png';
- if ($extension == 'jpg') return 'image/jpeg';
- if ($extension == 'ogg') return 'application/ogg';
- // If not recoginzed, use mime_types.txt
- {
- {
- {
- {
- return $a[0];
- }
- }
- }
- }
- return ''; // if nothing was found
- }
- /**
- * saveFile()
- * Store an http-uploaded file in the current page.
- * Any previous file will be replaced with the new file.
- *
- * @author {@link http://wikkawiki.org/ChewBakka ChewBakka} (first draft)
- * @input $uploaded_file An item from PHP's $_FILES array (see there)
- * @output None
- */
- function saveFile( $uploaded_file, $wikka )
- {
- $pathname = $wikka->config['upload_path'] . '/' . $wikka->tag;
- $path = $pathname . '.' . $extension;
- $contenttyp = '';
- {
- {
- }
- if( ! $contenttype )
- {
- $contenttype = mimeTypeFromExtension( $extension );
- }
- // build an array with metadata
- 'extension' => $extension,
- 'content-type' => $contenttype,
- 'image' => 'false'
- );
- {
- $data['image'] = 'true';
- $data['width'] = $size[0];
- $data['height'] = $size[1];
- }
- // Create metadata file
- $contents = '';
- foreach ($data as $key => $value)
- {
- $contents .= ($key . ': ' . $value . "\n");
- }
- }
- }
- /**
- * Return an array describing the file which is stored in a page.
- *
- * @author {@link http://wikkawiki.org/ChewBakka ChewBakka} (first draft)
- * @input $tag name of the page; default = current page.
- * @output Array or (if no file in page) null. Keys:
- * extension file extension, e.g. 'png', 'jpg', 'ogg'
- * content-type mime content type, e.g. 'image/png'
- * uploaded when and who,. e.g. '2007-01-31 ChewBakka'
- * image 'yes' or 'no'
- * width Width in pixels (images only)
- * height Height in pixels (images only)
- * filename PageName.ext
- * path upload_path/PageName.extension
- * url 'http://..../PageName/file'
- */
- function getFile( $tag, $wikka )
- {
- $data = null; // this variable will be returned
- $metafile = $wikka->config['upload_path'].'/'.$tag.'.file'; // metadata
- {
- // Lines look like "key: value" -> convert into array
- 'extension' => '',
- 'content-type' => '',
- 'uploaded' => '<unknown> <unknown>',
- 'image' => 'false',
- 'width' => '',
- 'height' => '',
- 'filename' => '',
- 'path' => '',
- 'url' => ''
- );
- foreach ($lines as $line)
- {
- {
- }
- }
- // Convenient attributes which can not be stored permanently
- $data['filename'] = $tag . '.' . $data['extension'];
- $data['path'] = $wikka->config['upload_path'] .'/' . $data['filename'];
- $data['url'] = $wikka->config['base_url'] . $tag . '/file';
- // Final check: file must exist.
- {
- $data = null;
- }
- }
- return $data;
- }
- /**
- * Here the real handler starts
- */
- $handled = False;
- {
- // User uploaded a file
- if ($this->HasAccess('write'))
- {
- $uploadedfile = $_FILES['file'];
- if ($uploadedfile['error'] > 0)
- {
- // redirect to page
- $this->redirect( $this->Href(), 'Transmitted file was damaged' );
- }
- else
- {
- saveFile( $uploadedfile, $this );
- $this->Redirect( $this->Href() );
- }
- $handled = True;
- }
- }
- else
- {
- // No upload => return the file
- if ($this->HasAccess('read') && $data = getFile($this->GetPageTag(),$this))
- {
- if ($data['image'] != 'true')
- {
- }
- $handled = True;
- }
- }
- if( !$handled )
- {
- $this->Redirect( $this->Href(), 'Unknown' );
- }
- ?>
And now for the really last step - read your wikka.config.php, it should contain a line like this:
wikka.config.php (line 40)
- // ...
- 'upload_path' => 'uploads',
- // ...
This means that the Wikka root folder should contain a folder named uploads; please create this folder if it does not exist.
Should the above line not be in your config file, please add the line too.
Ready! If something does not work yet, leave me a comment. --ChewBakka
How it works
Behind the scenes, an uploaded file is stored in the uploads directory along with a metadata file. In the example above, Wikka stores the uploaded file IMG_1234.JPG as MillenniumFalconOnTatooine.jpg along with MillenniumFalconOnTatooine.file which contains the metadata. The latter is a plain ascii file which tells Wikka that the actual file is a jpg file.
History
2007-Feb-05
handlers/page/file.php: bugfix (switch without break, now if/elseif); sends filename with download (makes download easier)
libs/Wakka.class.php: supports *.*.gz
2008-Jul-15
Complete rewrite.
Only ACTION and HANDLER; no more Wikka.class.php modifications.
Credits
While developing the above code, I browsed through many Wikka sources in order to learn how to write a good extension, and how to document it. They were too many to remember, so I just want to say thanks to all the people who made Wikka.
Category: CategoryUserContributions User contributions