bug fixes for widgets and exports. snippets were exported as index.html or the

like, and widget toolboxes weren't popping up in a widgetized view.
This commit is contained in:
Chris Nehren 2008-05-31 19:42:38 +00:00
parent f5ad94c95e
commit 5dfc9e3bfc
8 changed files with 774 additions and 142 deletions

View file

@ -2437,7 +2437,6 @@ true.
sub isValidRssItem { 1 }
#-------------------------------------------------------------------
=head2 www_widgetView ( )
Returns the view() method of the asset object suitable for widgetizing.
@ -2451,7 +2450,9 @@ sub www_widgetView {
return $session->privilege->noAccess() unless $self->canView;
my $templateId = $session->form->process('templateId');
my $templateId = $session->form->process('templateId');
my $width = $session->form->process('width');
my $height = $session->form->process('height');
if($templateId eq 'none') {
$self->prepareView;
@ -2459,8 +2460,7 @@ sub www_widgetView {
else {
$self->prepareWidgetView($templateId);
}
$self->_outputWidgetJs;
return $self->view;
return $self->outputWidgetMarkup($width, $height, $templateId);
}
#-------------------------------------------------------------------
@ -2479,22 +2479,117 @@ sub prepareWidgetView {
my $template = WebGUI::Asset::Template->new($self->session, $templateId);
my $session = $self->session;
my $extras = $session->config->get('extrasURL');
my $yahooDomJs = $extras . '/yui/build/yahoo-dom-event/yahoo-dom-event.js';
my $widgetJs = $extras . '/widgetLinkTargets.js';
$template->prepare;
$self->{_viewTemplate} = $template;
}
sub _outputWidgetJs {
#-------------------------------------------------------------------
=head2 outputWidgetMarkup ( width, height, templateId )
Output the markup required for the widget view. Includes markup to handle the
widget macro in the iframe holding the widgetized asset. This does the following:
=item retrieves the content for this asset using its L</view> method
=item processes macros in that content
=item serializes the processed content in JSON
=item writes the JSON to a storage location
=item refers the user to download this JSON
=item references the appropriate JS files for the templating engine and the widget macro
=item invokes the templating engine on this JSON
=head3 width
The width of the iframe. Required for making widget-in-widget function properly.
=head3 height
The height of the iframe. Required for making widget-in-widget function properly.
=head3 templateId
The templateId for this widgetized asset to use. Required for making
widget-in-widget function properly.
=cut
sub outputWidgetMarkup {
# get our parameters.
my $self = shift;
my $width = shift;
my $height = shift;
my $templateId = shift;
# construct / retrieve the values we'll use later.
my $assetId = $self->getId;
my $session = $self->session;
my $extras = $session->config->get('extrasURL');
my $conf = $session->config;
my $extras = $conf->get('extrasURL');
# the widgetized version of content that has the widget macro in it is
# executing in an iframe. this iframe doesn't have a style object.
# therefore, the macro won't be able to output the stylesheet and JS
# information it needs to do its work. because of this, we need to output
# that content manually. construct the filesystem paths for those files.
my $containerCss = $extras . '/yui/build/container/assets/container.css';
my $containerJs = $extras . '/yui/build/container/container-min.js';
my $yahooDomJs = $extras . '/yui/build/yahoo-dom-event/yahoo-dom-event.js';
my $widgetJs = $extras . '/widgetLinkTargets.js';
$session->output->print("<script type='text/javascript' src='" . $yahooDomJs . "'></script>");
$session->output->print("<script type='text/javascript' src='" . $widgetJs . "'></script>");
my $wgWidgetJs = $extras . '/wgwidget.js';
my $ttJs = $extras . '/tt.js';
# the templating engine requires its source data to be in json format.
# write this out to disk and then serve the URL to the user. in this case,
# we'll be serializing the content of the asset which is being widgetized.
my $storage = WebGUI::Storage->get($session, $assetId);
my $content = $self->view;
WebGUI::Macro::process($session, \$content);
my $jsonContent = objToJson( { "asset$assetId" => { content => $content } } );
$storage->addFileFromScalar("$assetId.js", "data = $jsonContent");
my $jsonUrl = $storage->getUrl("$assetId.js");
# WebGUI.widgetBox.initButton() needs the full URL of the asset being
# widgetized, and also the full URL of the JS file that does most of the
# work.
my $fullUrl = "http://" . $conf->get("sitename")->[0] . $self->getUrl;
my $wgWidgetPath = 'http://' . $conf->get('sitename')->[0] . $extras . '/wgwidget.js';
# finally, given all of the above, construct our output. WebGUI outputs
# fully valid XHTML 1.0 Strict, and there's no reason this should be any
# different.
my $output = <<OUTPUT;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="$containerCss" />
<script type="text/javascript" src="$jsonUrl"></script>
<script type="text/javascript" src="$ttJs"></script>
<script type='text/javascript' src='$yahooDomJs'></script>
<script type='text/javascript' src='$containerJs'></script>
<script type='text/javascript' src='$wgWidgetJs'></script>
<script type='text/javascript'>
function setupPage() {
WebGUI.widgetBox.doTemplate('widget$assetId'); WebGUI.widgetBox.retargetLinksAndForms();
WebGUI.widgetBox.initButton( { 'wgWidgetPath' : '$wgWidgetPath', 'fullUrl' : '$fullUrl', 'assetId' : '$assetId', 'width' : $width, 'height' : $height, 'templateId' : '$templateId' } );
}
YAHOO.util.Event.addListener(window, 'load', setupPage);
</script>
</head>
<body id="widget$assetId">
\${asset$assetId.content}
</body>
</html>
OUTPUT
return $output;
}
1;

View file

@ -107,6 +107,43 @@ sub definition {
}
#-------------------------------------------------------------------
=head2 exportGetUrlAsPath ( index )
Translates a URL into an appropriate path and filename for exporting.
Overridden here to return a filename corresponding to the URL of this asset
as-is.
=head3 index
index filename passed from L</exportAsHtml>
=cut
sub exportGetUrlAsPath {
my $self = shift;
# we don't use this, but get it anyway
my $index = shift || 'index.html';
my $config = $self->session->config;
# make sure that the export path is valid
WebGUI::Asset->exportCheckPath($self->session);
# if we're still here, it's valid. get it.
my $exportPath = $config->get('exportPath');
# get the asset's URL as a URI::URL object for easy parsing of components
my $url = URI::URL->new($config->get("sitename")->[0] . $self->getUrl);
my @pathComponents = $url->path_components;
shift @pathComponents; # first item is the empty string
my $filename = pop @pathComponents;
# return a path with the filename part of the URL. No fancy twiddling needed.
return Path::Class::File->new($exportPath, @pathComponents, $filename);
}
#-------------------------------------------------------------------
=head2 getToolbar ( )

View file

@ -205,6 +205,7 @@ sub exportAsHtml {
my $indexFileName = $args->{indexFileName};
my $extrasUploadAction = $args->{extrasUploadAction};
my $rootUrlAction = $args->{rootUrlAction};
my $exportUrl = $args->{exportUrl};
# if we're doing symlinking of the root URL, then the current default asset
# is the root of the tree. take down that asset ID so we can pass it to
@ -282,8 +283,12 @@ sub exportAsHtml {
return ($returnCode, $message);
}
my $exportedCount = 0;
foreach my $assetId ( @{$assetIds} ) {
# set a scratch variable for widgets to know we're exporting
$exportSession->scratch->set('exportUrl', $exportUrl);
my $asset = WebGUI::Asset->newByDynamicClass($exportSession, $assetId);
my $fullPath = $asset->exportGetUrlAsPath;
@ -500,6 +505,10 @@ Translates a URL into an appropriate path and filename for exporting. For
example, given C<'/foo/bar/baz'>, will return C<'/foo/bar/baz/index.html'>
provided the value of indexFile as given to exportAsHtml was C<'index.html'>.
=head3 url
URL of the asset we need an export path for
=head3 index
index filename passed from L</exportAsHtml>
@ -815,6 +824,11 @@ sub www_export {
-name => "index",
-value => "index.html"
);
$f->text(
-label => 'Export site root URL',
-name => 'exportUrl',
-value => '',
);
# TODO: maybe add copy options to these boxes alongside symlink
$f->selectBox(
@ -858,7 +872,7 @@ sub www_exportStatus {
return $self->session->privilege->insufficient() unless ($self->session->user->isInGroup(13));
my $i18n = WebGUI::International->new($self->session, "Asset");
my $iframeUrl = $self->getUrl('func=exportGenerate');
foreach my $formVar (qw/index depth userId extrasUploadsAction rootUrlAction/) {
foreach my $formVar (qw/index depth userId extrasUploadsAction rootUrlAction exportUrl/) {
$iframeUrl = $self->session->url->append($iframeUrl, $formVar . '=' . $self->session->form->process($formVar));
}
@ -893,6 +907,7 @@ sub www_exportGenerate {
extrasUploadAction => $self->session->form->process('extrasUploadsAction'),
rootUrlAction => $self->session->form->process('rootUrlAction'),
depth => $self->session->form->process('depth'),
exportUrl => $self->session->form->process('exportUrl'),
});
if (!$success) {
$self->session->output->print($description, 1);

View file

@ -1,7 +1,7 @@
package WebGUI::Macro::Widget;
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2008 Plain Black Corporation.
# WebGUI is Copyright 2001-2007 Plain Black Corporation.
#-------------------------------------------------------------------
# Please read the legal notices (docs/legal.txt) and the license
# (docs/license.txt) that came with this distribution before using
@ -16,8 +16,8 @@ use strict;
sub process {
# get passed parameters
my $session = shift;
my $assetId = shift;
my $session = shift;
my $url = shift;
my $width = shift || 600;
my $height = shift || 400;
my $templateId = shift || 'none';
@ -27,94 +27,89 @@ sub process {
my $extras = $conf->get("extrasURL");
# add CSS and JS to the page
my $style = $session->style;
$style->setLink($extras."/yui/build/container/assets/container.css",{
my $style = $session->style;
$style->setLink($extras."/yui/build/container/assets/container.css",{
rel=>"stylesheet",
type=>"text/css",
}
);
$style->setScript($extras."/wgwidget.js",{
type=>"text/javascript"
}
);
$style->setScript($extras."/yui/build/yahoo-dom-event/yahoo-dom-event.js",{
type=>"text/javascript"
}
);
$style->setScript($extras."/yui/build/container/container-min.js",{
type=>"text/javascript"
}
);
# construct the absolute URL
my $asset = WebGUI::Asset->new($session, $assetId);
my $fullUrl = "http://" . $conf->get("sitename")->[0] . $asset->getUrl;
# construct path to wgwidget.js
my $wgWidgetPath = 'http://' . $conf->get('sitename')->[0] . $extras . '/wgwidget.js';
# and yahoo-dom-event.js
my $yahooDomJsPath = 'http://' . $conf->get('sitename')->[0] . $extras . '/yui/build/yahoo-dom-event/yahoo-dom-event.js';
my $imgSrc = $extras . '/gear.png';
# and the JS
$style->setScript($extras."/wgwidget.js",{
type=>"text/javascript"
}
);
$style->setScript($extras."/yui/build/yahoo-dom-event/yahoo-dom-event.js",{
type=>"text/javascript"
}
);
$style->setScript($extras."/yui/build/container/container-min.js",{
type=>"text/javascript"
}
);
my $output = <<"EOHTML";
<script>
# construct the absolute URL and get the asset ID
my $asset = WebGUI::Asset->newByUrl($session, $url);
my $assetId = $asset->getId;
var codeGeneratorButton;
# ... and the full URL. If there's an exportWidget scratch variable, we're
# exporting, and we need to use that URL.
my($fullUrl, $wgWidgetPath);
my $scratch = $session->scratch;
my $exportUrl = $scratch->get('exportUrl');
if($exportUrl) {
my $storage = WebGUI::Storage->get($session, $assetId);
$fullUrl = $exportUrl . $storage->getUrl("$assetId.html");
$wgWidgetPath = $exportUrl . $extras . '/wgwidget.js';
$scratch->delete('exportUrl');
my $content = $asset->view;
WebGUI::Macro::process($session, \$content);
my $containerCss = $extras . '/yui/build/container/assets/container.css';
my $containerJs = $extras . '/yui/build/container/container-min.js';
my $yahooDomJs = $extras . '/yui/build/yahoo-dom-event/yahoo-dom-event.js';
my $wgWidgetJs = $extras . '/wgwidget.js';
my $wgWidgetPath = $extras . '/wgwidget.js';
var handleButtonShow = function() {
codeGeneratorButton.show();
var tag = document.getElementById('jsWidgetCode');
tag.focus();
tag.select();
}
function initButton() {
var jsCode = "";
jsCode += "&lt;script type='text/javascript' src='$wgWidgetPath'&gt; &lt;/script&gt;";
jsCode += "&lt;script type='text/javascript'&gt;";
jsCode += "document.write(WebGUI.widgetBox.widget('$fullUrl', '$assetId', $width, $height, '$templateId')); &lt;/script&gt;";
// Instantiate the Dialog
codeGeneratorButton = new YAHOO.widget.SimpleDialog("codeGeneratorButton", {
width: "500px",
height: "200px",
fixedcenter: true,
visible: false,
draggable: true,
close: true,
text: "<textarea id='jsWidgetCode' rows='5' cols='50'>" + jsCode + "</textarea>",
icon: YAHOO.widget.SimpleDialog.ICON_INFO,
constraintoviewport: true,
modal: true,
zIndex: 9999,
buttons: [{text: "Dismiss", handler:dismissButton, isDefault: true}]
my $output = <<OUTPUT;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" type="text/css" href="$containerCss" />
<script type='text/javascript' src='$yahooDomJs'></script>
<script type='text/javascript' src='$containerJs'></script>
<script type='text/javascript' src='$wgWidgetJs'></script>
<script type='text/javascript'>
function setupPage() {
WebGUI.widgetBox.retargetLinksAndForms();
WebGUI.widgetBox.initButton( { 'wgWidgetPath' : '$wgWidgetPath', 'fullUrl' : '$fullUrl', 'assetId' : '$assetId', 'width' : $width, 'height' : $height, 'templateId' : '$templateId' } );
}
);
codeGeneratorButton.setHeader("Widget code");
YAHOO.util.Event.addListener(window, 'load', setupPage);
</script>
</head>
<body id="widget$assetId">
$content
</body>
</html>
OUTPUT
$storage->addFileFromScalar("$assetId.html", $content);
}
else {
$fullUrl = "http://" . $conf->get("sitename")->[0] . $asset->getUrl;
$wgWidgetPath = 'http://' . $conf->get('sitename')->[0] . $extras . '/wgwidget.js';
}
// Render the Dialog
codeGeneratorButton.render(document.body);
YAHOO.util.Event.addListener("show", "click", handleButtonShow, codeGeneratorButton, true);
}
var dismissButton = function () {
this.hide();
}
YAHOO.util.Event.addListener(window, "load", initButton);
# get the gear icon
my $imgSrc = $extras . '/gear.png';
my $output = <<EOHTML;
<a href="#$assetId" id="show$assetId" name="show$assetId"><img src="$imgSrc" /></a>
<script type="text/javascript">
YAHOO.util.Event.addListener(window, 'load', WebGUI.widgetBox.initButton, { 'wgWidgetPath' : '$wgWidgetPath', 'fullUrl' : '$fullUrl', 'assetId' : '$assetId', 'width' : $width, 'height' : $height, 'templateId' : '$templateId' } );
</script>
<!-- <button id="show">Get code for this content</button> -->
<a href="#" id="show"><img src="$imgSrc" /></a>
EOHTML
return $output;
return $output;
}
1;