diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt
index 09ab89df3..e8dcbee40 100644
--- a/docs/changelog/7.x.x.txt
+++ b/docs/changelog/7.x.x.txt
@@ -18,6 +18,10 @@
- Added migration utility for Gallery
- Removed old .tmpl files from upgrades. ALL templates in upgrades must now
be in Packages!
+ - add: widgetize asset macro. called like so: ^Widget(assetId, width,
+ height, templateId); where assetId is the asset of the widget to
+ templatize and templateId is the template for the widget itself. If
+ templateId isn't specified, uses ajaxInlineView.
7.4.20
- fix: Assets with no committed versions may be left as orphans when parent is purged
diff --git a/lib/WebGUI/Asset.pm b/lib/WebGUI/Asset.pm
index d88eaf6ad..4e6f5ad11 100644
--- a/lib/WebGUI/Asset.pm
+++ b/lib/WebGUI/Asset.pm
@@ -2575,6 +2575,65 @@ true.
sub isValidRssItem { 1 }
+#-------------------------------------------------------------------
+=head2 www_widgetView ( )
+
+Returns the view() method of the asset object suitable for widgetizing.
+
+=cut
+
+sub www_widgetView {
+ my $self = shift;
+ my $session = $self->session;
+ my $style = $session->style;
+
+ return $session->privilege->noAccess() unless $self->canView;
+
+ my $templateId = $session->form->process('templateId');
+
+ if($templateId eq 'none') {
+ $self->prepareView;
+ }
+ else {
+ $self->prepareWidgetView($templateId);
+ }
+ $self->_outputWidgetJs;
+ return $self->view;
+}
+
+#-------------------------------------------------------------------
+
+=head2 prepareWidgetView ( )
+
+Prepares the widget view for this asset. Specifically, sets up some JS to
+ensure that links selected / forms submitted in the widgetized form of the
+asset open in a new window.
+
+=cut
+
+sub prepareWidgetView {
+ my $self = shift;
+ my $templateId = shift;
+ 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 {
+ my $self = shift;
+ 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';
+ $session->output->print("");
+ $session->output->print("");
+}
1;
diff --git a/lib/WebGUI/Macro/Widget.pm b/lib/WebGUI/Macro/Widget.pm
new file mode 100755
index 000000000..457bdc293
--- /dev/null
+++ b/lib/WebGUI/Macro/Widget.pm
@@ -0,0 +1,120 @@
+package WebGUI::Macro::Widget;
+
+#-------------------------------------------------------------------
+# 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
+# this software.
+#-------------------------------------------------------------------
+# http://www.plainblack.com info@plainblack.com
+#-------------------------------------------------------------------
+
+use strict;
+
+#-------------------------------------------------------------------
+sub process {
+
+ # get passed parameters
+ my $session = shift;
+ my $assetId = shift;
+ my $width = shift || 600;
+ my $height = shift || 400;
+ my $templateId = shift || 'none';
+
+ # Get location for CSS and JS files
+ my $conf = $session->config;
+ 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",{
+ 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';
+
+ my $output = <<"EOHTML";
+
+
+
+
+
+EOHTML
+
+ return $output;
+}
+
+1;
diff --git a/www/extras/gear.png b/www/extras/gear.png
new file mode 100755
index 000000000..5da45a433
Binary files /dev/null and b/www/extras/gear.png differ
diff --git a/www/extras/wgwidget.js b/www/extras/wgwidget.js
new file mode 100755
index 000000000..ff4ee4ab6
--- /dev/null
+++ b/www/extras/wgwidget.js
@@ -0,0 +1,40 @@
+var WebGUI = {
+
+ widgetBox : {
+
+ parentNodeId : null,
+ url : null,
+
+
+ widget : function( url, parentId, width, height, templateId ) {
+ if(url == "") {
+ return "";
+ }
+
+ if(width == undefined) {
+ width = 600;
+ }
+ if(height == undefined) {
+ height = 400;
+ }
+
+ this.url = url + "?func=widgetView&templateId=" + templateId;
+
+ this.parentNodeId = parentId;
+
+ this.markup = "";
+ this.markup += "";
+
+ return this.markup;
+ }
+ }
+}
diff --git a/www/extras/widgetLinkTargets.js b/www/extras/widgetLinkTargets.js
new file mode 100755
index 000000000..52593eec7
--- /dev/null
+++ b/www/extras/widgetLinkTargets.js
@@ -0,0 +1,19 @@
+var WebGUI = {
+ widgetBox : {
+ function retargetLinksAndForms() {
+
+ // get all the elements, change their target appropriately
+ var allLinks = document.getElementsByTagName('a');
+ for(var i = 0; i < allLinks.length; i++) {
+ allLinks[i].target = '_blank';
+ }
+
+ // same for