Wiki source for GrabCodeHandler


Show raw source

=====Grab Code Handler=====
{{lastedit}}

>>==See also:==
Documentation: ""GrabCodeHandlerInfo""
Other: ImprovedFormatter.>>This is the development page for the Grab Code handler.::c::


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 [[http://wush.net/trac/wikka/log/trunk/?action=stop_on_copy&rev=51&stop_rev=49&mode=stop_on_copy | 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**
%%(php)
return $output;
}
%%

**modified**
%%(php)
//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";
}
%%
~&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 [[WikkaBetaFeatures | 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:%%(php;334) #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 .= '<input type="hidden" name="code" value="'.urlencode($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)
<?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;
?>
%%

==3. Modify ##wikka.php##==

Make the two following modifications in **##./wikka.php##**:

**A. original**
%%(php)
// raw page handler
elseif ($this->method == "raw")
{
header("Content-type: text/plain");
print($this->Method($this->method));
}
%%

**A. modified**
%%(php)
// 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));
}
%%

**B. original**
%%(php)
if (!preg_match("/(xml|raw|mm)$/", $method))
{
%%

**B. modified**
%%(php)
if (!preg_match("/(xml|raw|mm|grabcode)$/", $method))
{
%%

----
==== 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
Valid XHTML :: Valid CSS: :: Powered by WikkaWiki