Revision [20150]
This is an old revision of WikiFile made by ChewBakka on 2008-08-15 17:02:58.
WikiFile action and handler
This module allows you to put images (and other files) anywhere on any page (provided you have write access to that page).
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 into the MillenniumFalcon page
So you edit the respective page and put the {{file}} placeholder at the place where you want to see the image.
MillenniumFalcon
===== Millennium Falcon =====
Below you see a photograph of the Millennium Falcon, last year on Tatooine.
There was lots of sand, as always.
{{file}}
Below you see a 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. A click on the image displays another form, allowing you to replace the photo with another one or just to delete it.
Now, suppose you want to add more images to the same page. Then you need to distinguish the files by adding an id.
MillenniumFalcon
===== Millennium Falcon =====
Below you see a photograph of the Millennium Falcon, last year on Tatooine.
There was lots of sand, as always.
{{file}}
On the next images, some Jawas admire the mighty space vessel:
{{file id="jawas1"}}
{{file id="jawas2"}}
Below you see a photograph of the Millennium Falcon, last year on Tatooine.
There was lots of sand, as always.
{{file}}
On the next images, some Jawas admire the mighty space vessel:
{{file id="jawas1"}}
{{file id="jawas2"}}
As you see above, it is allowed to have one file per page which has no id. Also, don't worry about id of images on other pages - the id just need to be unique inside the wiki page.
Advanced usage
To display an image also on another page, you do not need to upload it twice. Instead, you can tell the file placeholder to fetch the image from a different page:
{{file page="PageWhichContainsTheFile"}}
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 second file as MillenniumFalcon~jawas1.jpg along with MillenniumFalcon~javas1.file which is a plain ascii file containing some metadata.
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
- *
- * Displays a file in the page (as image or link) and optinally an upload form.
- *
- * Syntax: {{file [id="idvalue"] [page="PageToTakeFileFrom"]}}
- *
- * Save this PHP file in the actions subdirectory.
- *
- * @package Actions
- * @name File
- *
- * @author {@link http://wikkawiki.org/ChewBakka ChewBakka} (first draft)
- */
- /**
- * Reads the file's metadata file and returns it as an array.
- *
- * @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.
- */
- {
- function getFile( $tag, $wikka, $id )
- {
- $data = null; // this variable will be returned
- $sep = ($id ? '~' : '' ); // Separator between tag and id in filename
- // Read the metadata from the file TagName~id.file
- $metafile = $wikka->config['upload_path'].'/'.$tag.$sep.$id.'.file';
- {
- // Lines look like "key: value" -> convert them to an array
- 'extension' => '', // file extension, e.g. 'png', 'jpg', 'ogg'
- 'content-type' => '', // mime content type, e.g. 'image/png'
- 'uploaded' => '?', // date and time, . e.g. '2007-01-31 18:00'
- 'uploader' => '?', // wikiname, e.g. 'ChewBakka'
- 'image' => 'false', // 'true' for image files
- 'width' => '', // width in pixels (images only)
- 'height' => '' // height in pixels (images only)
- );
- foreach ($lines as $line)
- {
- {
- }
- }
- // Add convenient attributes which can not be stored permanently
- $url = $wikka->config['base_url'] . $tag . '/file';
- if( $id )
- {
- // append ?id=value or &id=value
- }
- $data['filename'] = $tag.$sep.$id . '.' . $data['extension'];
- $data['path'] = $wikka->config['upload_path'] .'/' . $data['filename'];
- $data['metafile'] = $metafile;
- $data['url'] = $url;
- // Final check: file must exist.
- {
- $data = null;
- }
- }
- return $data;
- }
- }
- /**
- * Here the real action starts
- */
- // Initialize variables
- $language = 'DE' ; // change to 'DE' for german messages
- $output = ''; // The HTML code that is being generated by this action
- $tag = $this->GetPageTag(); // The page that the user requested
- $id = ''; // Optional file id, appended to the tag name
- $editid = '!NONE!'; // id of the image to which an upload/delete form is shown
- // Read the parameters from {{file id="..." page="..."}}
- {
- }
- {
- $editid = $_REQUEST['editid'];
- }
- if( $id )
- {
- // A file ID was submitted.
- // Check if it is alphanumeric and not longer than 100 characters
- // in order to prevent security issues.
- {
- $id = '!BAD!';
- $output = 'An illegal file ID was submittet';
- }
- }
- if( $id != '!BAD!' )
- {
- $data = getFile($tag,$this,$id);
- // The user is allowed to edit (= replace or delete) the file,
- // if it is attached to the same page that the user is viewing,
- // and the user may edit the page.
- $mayEdit = $this->HasAccess('write',$tag) && $tag == $this->GetPageTag();
- // The user is allowed to see the image (or download the file),
- // if he would also be allowed to read the page to which it is attached.
- if ($this->HasAccess( 'read', $tag ) && $data )
- {
- // Build an URL that shows the upload form: http://server/WikiPage?editid=id
- // (actually it reloads the page with an upload form below the file)
- $urlToEdit = '';
- if ($mayEdit && $id != $editid)
- {
- $tmp = $this->Href('', $tag);
- }
- // Create an img tage or a link
- if ($data['image'] == 'true')
- {
- // Image file - create an <img> tag
- $alt = ($urlToEdit ? 'Toggle edit' : 'Go to '.$tag );
- $output = '<img src="' . $data['url'] . '"'
- . ' width="' . $data['width'] . '"'
- . ' height="' . $data['height'] . '"'
- . ' alt="' . $alt . '"'
- . ' border="0">';
- if( $urlToEdit )
- {
- // Add an URL to show the upload form
- $output = '<a href="' . $urlToEdit . '">' . $output . '</a>';
- }
- else
- {
- // Add an URL to go to the page which embeds the file
- $output = '<a href="' . $this->Href('',$tag) . '">' . $output . '</a>';
- }
- }
- else
- {
- // Other file types - create a download link
- $output = '<a href="' . $data['url'] . '">' . $data['url'] . '</a>';
- if ($urlToEdit)
- {
- // Add an URL to show the upload form
- $output .= ' <a href="'.$urlToEdit.'">' . ($language=='DE'?'[BEARBEITEN]':'[EDIT]') . '</a>';
- }
- }
- }
- if ($mayEdit && ($id == $editid || $data == null))
- {
- // If on the same page and requested, also show an upload/delete form
- $deletelink = '';
- $hidelink = '';
- switch($language)
- {
- case 'DE':
- $headline = 'Eine Datei hochladen, so dass sie an dieser Stelle erscheint';
- $buttonlabel = 'Hochladen';
- if( $data )
- {
- $headline = ($data['image'] == 'true' ? 'Obiges Bild' : 'Obige Datei' )
- . ' durch Hochladen einer neuen Datei ÜBERSCHREIBEN';
- $deletelink = '<br />'
- . ($data['image'] == 'true' ? 'Obiges Bild' : 'Obige Datei' )
- . ' aus dem Wiki '
- . 'cmd=delete">LÖSCHEN</a>';
- $hidelink = '<br />Dieses Formular <a href="' . $this->Href() . '">AUSBLENDEN</a>';
- }
- break;
- default:
- $headline = 'Upload a file to appear here';
- $buttonlabel = 'Upload';
- if( $data )
- {
- $headline = 'REPLACE the '
- . ($data['image'] == 'true' ? 'image' : 'file' )
- . ' above by uploading a new file';
- $buttonlabel = 'Upload';
- . 'cmd=delete">DELETE</a>'
- . ' the '
- . ($data['image'] == 'true' ? 'image' : 'file' )
- . ' above from the wiki';
- $hidelink = '<br /><a href="' . $this->Href() . '">HIDE</a> this form';
- }
- }
- $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="hidden" name="id" value="' . $id . '">'
- . '<input type="submit" value="' . $buttonlabel . '">'
- . $deletelink
- . $hidelink
- . '</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
- *
- * Supports file retrieval and upload.
- *
- * Syntax: http://server/WikiName/file[?id=someid]
- *
- * Save this PHP file in the handlers/page subdirectory.
- *
- * @package Handlers
- * @name File
- *
- * @author {@link http://wikkawiki.org/ChewBakka ChewBakka} (first draft)
- */
- /**
- * Reads the file's metadata file and returns it as an array.
- *
- * @author {@link http://wikkawiki.org/ChewBakka ChewBakka} (first draft)
- * @input $tag name of the page; default = current page.
- * @output Array or (if no file) null.
- */
- function getFile( $tag, $wikka, $id )
- {
- $data = null; // this variable will be returned
- $sep = ($id ? '~' : '' ); // Separator between tag and id in filename
- // Read the metadata from the file TagName~id.file
- $metafile = $wikka->config['upload_path'].'/'.$tag.$sep.$id.'.file';
- {
- // Lines look like "key: value" -> convert them to an array
- 'extension' => '', // file extension, e.g. 'png', 'jpg', 'ogg'
- 'content-type' => '', // mime content type, e.g. 'image/png'
- 'uploaded' => '?', // date and time, . e.g. '2007-01-31 18:00'
- 'uploader' => '?', // wikiname, e.g. 'ChewBakka'
- 'image' => 'false', // 'true' for image files
- 'width' => '', // width in pixels (images only)
- 'height' => '' // height in pixels (images only)
- );
- foreach ($lines as $line)
- {
- {
- }
- }
- // Add convenient attributes which can not be stored permanently
- $data['filename'] = $tag.$sep.$id . '.' . $data['extension'];
- $data['path'] = $wikka->config['upload_path'] .'/' . $data['filename'];
- $data['metafile'] = $metafile;
- $data['url'] = $wikka->config['base_url'] . $tag . '/file' . ($id?'?id='.$id:'');
- // Final check: file must exist.
- {
- $data = null;
- }
- }
- return $data;
- }
- /**
- * Store an http-uploaded 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, $id )
- {
- $pathname = $wikka->config['upload_path'] . '/' . $wikka->tag . ($id?'~':'') . $id;
- $path = $pathname . '.' . $extension;
- $contenttype = '';
- // Remove existing file if it already exists
- if ($data = getFile( $wikka->GetPageTag(), $wikka, $id ) )
- {
- // File exists; remove it first
- // E.g. if a GIF exists and the user replaces it with a PNG now.
- $data = null;
- }
- {
- // Find the mime type (it will be stored in the metadata)
- {
- }
- if( ! $contenttype )
- {
- switch( $extension )
- {
- // Quick resonse for most frequently used file types
- case 'png':
- $contenttype = 'image/png';
- break;
- case 'jpg':
- $contenttype = 'image/jpeg';
- break;
- case 'ogg':
- $contenttype = 'application/ogg';
- break;
- case 'zip':
- $contenttype = 'application/zip';
- break;
- default:
- // Use wikka's own mime_types.txt
- {
- {
- {
- {
- $contenttype = $a[0];
- break;
- }
- }
- }
- }
- }
- }
- // build an array with metadata
- 'extension' => $extension,
- 'content-type' => $contenttype,
- 'uploader' => $wikka->GetUserName(),
- 'image' => 'false'
- );
- {
- $data['image'] = 'true';
- $data['width'] = $size[0];
- $data['height'] = $size[1];
- }
- // Save the data array in the metadata file
- $contents = '';
- foreach ($data as $key => $value)
- {
- $contents .= ($key . ': ' . $value . "\n");
- }
- }
- }
- /**
- * Here the real handler starts
- */
- $handled = False;
- {
- // A file ID was submitted.
- // Check if it is alphanumeric and not longer than 100 characters
- // in order to prevent security issues.
- {
- $cmd = 'nothing';
- }
- }
- {
- $cmd = 'upload';
- }
- switch( $cmd )
- {
- case 'upload':
- // 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, $id );
- $this->Redirect( $this->Href() );
- }
- $handled = True;
- }
- break;
- case 'get':
- // Return the file
- if ($this->HasAccess('read') && $data = getFile($this->GetPageTag(),$this,$id))
- {
- if ($data['image'] != 'true')
- {
- }
- $handled = True;
- }
- break;
- case 'delete':
- // Delete the file permanently from the wiki
- if ($this->HasAccess('write') && $data = getFile($this->GetPageTag(),$this,$id))
- {
- }
- $this->Redirect( $this->Href() );
- $handled = True;
- break;
- }
- if( !$handled )
- {
- $this->Redirect( $this->Href() );
- }
- ?>
And now for the 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
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