Grab Code Handler
Last edited by DarTar:
Replaces old-style internal links with new pipe-split links.
Fri, 20 May 2016 07:38 UTC [diff]
Replaces old-style internal links with new pipe-split links.
Fri, 20 May 2016 07:38 UTC [diff]
This is the development page for the Grab Code handler.
I'm working on a handler to select on the fly code blocks contained in Wikka pages and download them as files.
The idea is to add a Download button at the end of each code block in order to save the code snippet as a file with an appropriate name and extension.
Changelog
- [2006-04-23]
New version committed to the SVN repository (Revisions 49-51): code block syntax now accepts an optional value for filename: %%(php;12;myfile.php) ... %%. If filename is specified a small header for the code block is generated, and filename is used as a title for the download button and as a name for the downloadable file.
- [2004-02-17]
I've uploaded this handler on this server as a beta feature. Feedback is welcome. See the issues section at the bottom of this page for more details.
The code
1. Modify the formatter
Make the following modifications in formatters/wakka.php
original
return $output;
}
}
modified
//build form
$form = $wakka->FormOpen("grabcode");
$form .= '<input type="submit" class="grabcodebutton" style="float:right; margin-right:20px; margin-top:0px; font-size: 10px; color: #000;font-weight: normal; font-family: Verdana, Arial, sans-serif; background-color: #DDD; text-decoration: none; height:18px;" name="save" value="Grab" title="Download this code"/>';
$form .= '<input type="hidden" name="code" value="'.urlencode($code).'" />';
$form .= $wakka->FormClose();
// output
return "$output \n $form";
}
$form = $wakka->FormOpen("grabcode");
$form .= '<input type="submit" class="grabcodebutton" style="float:right; margin-right:20px; margin-top:0px; font-size: 10px; color: #000;font-weight: normal; font-family: Verdana, Arial, sans-serif; background-color: #DDD; text-decoration: none; height:18px;" name="save" value="Grab" title="Download this code"/>';
$form .= '<input type="hidden" name="code" value="'.urlencode($code).'" />';
$form .= $wakka->FormClose();
// output
return "$output \n $form";
}
- DarTar, you should get rid of the <br /> before the form - that's what causes (most of) the extra vertical whitespace between the codeblock and the button that we already discussed on #wikka. The codeblock already is a block (div), so whatever comes after it will automatically start on a new line; the <br /> is adding an extra one. See the weird and confusing effect this can have now on the item 'Double-click editing' on WikkaBugs (especially since you're also floating it). For readable HTML output, add a "\n" before the form instead of <br />.
- As a next step, give it a class: putting in the styling here prevents people from giving it their own styling to fit in with their skin! --JavaWoman
- Good point. As we discussed, I can't give a class to the form using the FormOpen() method, for the time being I add a class to the input button, in the future this will be handled by the appropriate contextual CSS selectors -- DarTar
- See AdvancedFormOpen for a solution. --JavaWoman
- Now that AdvancedFormOpen and ImprovedFormatter have both been installed on this site as a beta feature, I've adapted the code above slightly to take advantage of the capability of the new FormOpen() method to add a class to the form. The new code is now as follows:
- #return $output;
- // START DarTar modified 2005-02-17
- // slight mod JavaWoman 2005-06-12: coding style, class for form
- //build form
- $form = $wakka->FormOpen('grabcode','','post','','grabcode');
- $form .= '<input type="submit" name="save" class="grabcodebutton" style="line-height:10px; float:right; vertical-align: middle; margin-right:20px; margin-top:0px; font-size: 10px; color: #000; font-weight: normal; font-family: Verdana, Arial, sans-serif; background-color: #DDD; text-decoration: none; height:18px;" value="Grab" title="Download this code" />';
- $form .= $wakka->FormClose();
- // output
- return $output."\n".$form;
- // END DarTar modified 2005-02-17
(See ImprovedFormatter for the full code.)
- With this, every grabcode form gets a class 'grabcode' which can now be used to properly style the form (the styling still needs to be done, though, and will make the embedded style for the button superfluous). --JavaWoman
2. Create a grabcode handler
Save the following code as handlers/page/grabcode.php
<?php
/**
* Downloads a code snippet as a file.
*
* Usage: The handler is called from a form appended to any code block in Wikka pages.
*
* @package Handlers
* @name grabcode
* @author {@link http://wikka.jsnx.com/DarTar Dario Taraborelli}
* @version 0.1
* @since Wikka 1.1.X
* @todo - address header issues with different browsers.
* - modify formatter to take care of filename.
*/
$code = urldecode($_POST["code"]);
//$filename = ($_POST["name"])? $_POST["name"] : "snippet.php"; # forthcoming
$filename = "codesnippet.php"; # forthcoming
//header('Content-type: application/force-download');
header('Content-type: text/plain');
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Content-Length: '.strlen($code));
header('Content-Description: $filename Download Data');
header('Pragma: no-cache');
header('Content-Disposition: attachment; filename="' . $filename . '"');
echo $code;
?>
/**
* Downloads a code snippet as a file.
*
* Usage: The handler is called from a form appended to any code block in Wikka pages.
*
* @package Handlers
* @name grabcode
* @author {@link http://wikka.jsnx.com/DarTar Dario Taraborelli}
* @version 0.1
* @since Wikka 1.1.X
* @todo - address header issues with different browsers.
* - modify formatter to take care of filename.
*/
$code = urldecode($_POST["code"]);
//$filename = ($_POST["name"])? $_POST["name"] : "snippet.php"; # forthcoming
$filename = "codesnippet.php"; # forthcoming
//header('Content-type: application/force-download');
header('Content-type: text/plain');
header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Content-Length: '.strlen($code));
header('Content-Description: $filename Download Data');
header('Pragma: no-cache');
header('Content-Disposition: attachment; filename="' . $filename . '"');
echo $code;
?>
3. Modify wikka.php
Make the two following modifications in ./wikka.php:
A. original
// raw page handler
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
A. modified
// raw page handler
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
// grabcode handler
elseif ($this->method == "grabcode")
{
print($this->Method($this->method));
}
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
// grabcode handler
elseif ($this->method == "grabcode")
{
print($this->Method($this->method));
}
B. original
B. modified
Issues
- There are some known issues related to the way in which browsers interpret the Content-Disposition header sent by PHP (especially with IE) and I will try to figure out how this can be fixed. Help/suggestions are welcome.
- Currently the handler is stored in the handlers/page/ folder, but it is not a page handler (it does not perform operations on the page as a whole) so we might try to find a better organization in the handlers file structure.
- It seems that Content-type: application/force-download doesn't work under M$Windows/IE so I changed it back to Content-type: text/plain which should just display a text version of the code snippet.
References
PHP:header
CategoryDevelopmentHandlers
One thing that might be neat is expanding this to another option in the code formatter area that is used for geshi and do something like (php;1;afile.php) and have content disposition add a file name to the header for the grabcode handler.
Just a thought
That is *exactly* what we already had in mind as a next step! ;-)
(The GeSHi wrapper function will have to be adapted for that, too - as well as the handling of built-in code formatters.)
(not apache, php.ini or grabcode.php)
I commented out the line:-
header("Cache-Control: no-cache");
(1197 in the standard wikka.php)
I dont know what the implications of that will be yet...
"Internet Explorer was not able to open this Internet site. The requested site is either unavailable or cannot be found. Please try again later.",
personaly I only use it to check paces render ok... users were complaining though fr reference ir was IE6 on W2K (display of the headers showed that despite code to the contrary in grabhandler.php the page was not cacheable... that changed when commented in wikka.php)
Is it too much to ask for a button that displayed the name of the file you are downloading, optionally specified through the edit box (i.e %%php ... ,"wikka.php" ...) and that would result in "Grab wikka.php" and the download dialog box would have the "wikka.php" already instead of the default "codesnippet.txt"
Or the grabcode handler could get it from inside the code from a comment (i.e. @filename=wikka.php)