From d1db12d1e4f82455e3f5a7e85ac70e2ddfcbfa6e Mon Sep 17 00:00:00 2001 From: Colin Kuskie Date: Mon, 20 Apr 2009 21:18:24 +0000 Subject: [PATCH] Finish export code. Make the list of assets templatable, since the user can see it. Beginnings of export collateral tests. --- .../root_import_storymanager.wgpkg | Bin 3552 -> 3753 bytes docs/upgrades/upgrade_7.7.3-7.7.4.pl | 21 +++--- lib/WebGUI/Asset/Wobject/StoryArchive.pm | 69 ++++++++++++------ lib/WebGUI/Help/Asset_StoryArchive.pm | 24 ++++++ lib/WebGUI/i18n/English/Asset_StoryArchive.pm | 42 +++++++++++ t/Asset/Wobject/StoryArchive.t | 32 +++++++- 6 files changed, 153 insertions(+), 35 deletions(-) diff --git a/docs/upgrades/packages-7.7.4/root_import_storymanager.wgpkg b/docs/upgrades/packages-7.7.4/root_import_storymanager.wgpkg index 8e515142a05fb2cecb08530a7703b832064380c8..42da609410d90d251f0c4524365a714b28ad65bd 100644 GIT binary patch literal 3753 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 a?ir1E82+Gv2Muge1OErnOR|UnS^xlhwrite(< 'Story/Edit', defaultValue => 'E3tzZjzhmYoNlAyP2VW33Q', }, + keywordListTemplateId => { + tab => 'display', + fieldType => 'template', + label => $i18n->get('keyword list template'), + hoverHelp => $i18n->get('keyword list template help'), + namespace => 'StoryArchive/KeywordList', + defaultValue => '0EAJ9EYb9ap2XwfrcXfdLQ', + }, archiveAfter => { tab => 'display', fieldType => 'interval', @@ -202,16 +210,23 @@ sub exportAssetCollateral { $reportSession->output->print('
'); } - my $keywordObj = WebGUI::Keyword->new($session); + # open another session as the user doing the exporting... + my $exportSession = WebGUI::Session->open( + $self->session->config->getWebguiRoot, + $self->session->config->getFilename, + undef, + undef, + $self->session->getId, + ); + + + my $keywordObj = WebGUI::Keyword->new($exportSession); my $keywords = $keywordObj->findKeywords({ asset => $self, limit => 50, ##This is based on the tagcloud setting }); -##export session: do we need it? -##Need to find 50 assets per keyword and make a link list. -##In export mode, tagCloud should call the callback instead of using the func - + my $listTemplate = WebGUI::Asset->new($session, $self->get('keywordListTemplateId'), 'WebGUI::Asset::Template'); foreach my $keyword (@{ $keywords }) { ##Keywords may not be URL safe, so urlize them my $keyword_url = $self->getKeywordStaticUrl($keyword); @@ -224,39 +239,45 @@ sub exportAssetCollateral { '      ' . $message . '
'); } - # open another session as the user doing the exporting... - my $exportSession = WebGUI::Session->open( - $self->session->config->getWebguiRoot, - $self->session->config->getFilename, - undef, - undef, - $self->session->getId, - ); - - my $selfdupe = WebGUI::Asset->newByDynamicClass( $exportSession, $self->getId ); - # next, get the contents, open the file, and write the contents to the file. my $fh = eval { $dest->open('>:utf8') }; if($@) { - WebGUI::Error->throw(error => "can't open " . $dest->absolute->stringify . " for writing: $!"); $exportSession->close; + WebGUI::Error->throw(error => "can't open " . $dest->absolute->stringify . " for writing: $!"); } - $exportSession->asset($selfdupe); $exportSession->output->setHandle($fh); - my $contents; - # chunked content is already printed, no need to print it again - unless($contents eq 'chunked') { - $exportSession->output->print($contents); + my $storyIds = $keywordObj->getMatchingAssets({ + startAsset => $self, + keyword => $keyword, + isa => 'WebGUI::Asset::Story', + rowsPerPage => 50, + }); + my $listOfStories = []; + STORYID: foreach my $storyId (@{ $storyIds }) { + my $story = WebGUI::Asset->newByDynamicClass($session, $storyId); + next STORYID unless $story; + push @{ $listOfStories }, { + title => $story->getTitle, + url => $story->getUrl, + }; } - - $exportSession->close; + my $var = { + asset_loop => $listOfStories, + keyword => $keyword, + }; + my $output = $listTemplate->process($var); + my $contents = $self->processStyle($output); + $exportSession->output->print($contents); # tell the user we did this asset collateral correctly if ( $reportSession && !$args->{quiet} ) { $reportSession->output->print($reporti18n->get('done')); } + $fh->flush; + $fh->close; } + $exportSession->close; return $self->next::method($basepath, $args, $reportSession); } diff --git a/lib/WebGUI/Help/Asset_StoryArchive.pm b/lib/WebGUI/Help/Asset_StoryArchive.pm index 611157351..ed3aa84e4 100644 --- a/lib/WebGUI/Help/Asset_StoryArchive.pm +++ b/lib/WebGUI/Help/Asset_StoryArchive.pm @@ -65,6 +65,7 @@ our $HELP = { { 'name' => 'templateId', }, { 'name' => 'storyTemplateId', }, { 'name' => 'editStoryTemplateId', }, + { 'name' => 'keywordListTemplateId', }, { 'name' => 'archiveAfter', }, { 'name' => 'richEditorId', }, { 'name' => 'approvalWorkflowId', }, @@ -73,6 +74,29 @@ our $HELP = { }, + 'keyword list template' => { + title => 'view template', + body => '', + isa => [ + { namespace => "Asset_Template", + tag => "template variables" + }, + ], + fields => [], + variables => [ + { 'name' => 'asset_loop', + 'variables' => [ + { 'name' => 'title', + description => 'asset title' }, + { 'name' => 'url', + description => 'asset url' }, + ] + }, + { 'name' => 'keyword' }, + ], + related => [] + }, + }; 1; diff --git a/lib/WebGUI/i18n/English/Asset_StoryArchive.pm b/lib/WebGUI/i18n/English/Asset_StoryArchive.pm index 0a6d60bf1..21531acfc 100644 --- a/lib/WebGUI/i18n/English/Asset_StoryArchive.pm +++ b/lib/WebGUI/i18n/English/Asset_StoryArchive.pm @@ -87,12 +87,30 @@ our $I18N = { lastUpdated => 0 }, + 'keyword list template' => { + message => q|Keyword List Template|, + context => q|Label in the edit screen and template.|, + lastUpdated => 0 + }, + + 'keyword list template help' => { + message => q|The Template used to render the list of assets matching a keyword when this StoryArchive is exported.|, + context => q|Hoverhelp in the edit screen and template.|, + lastUpdated => 0 + }, + 'editStoryTemplateId' => { message => q|The GUID of the template used to add or edit Story assets.|, context => q|Template variable|, lastUpdated => 0 }, + 'keywordListTemplateId' => { + message => q|The GUID of the template used to render list of assets matching a keyword when this StoryArchive is exported.|, + context => q|Template variable|, + lastUpdated => 0 + }, + 'archive after' => { message => q|Archive Stories After|, context => q|Label in the edit screen and template.|, @@ -255,6 +273,30 @@ our $I18N = { lastUpdated => 0, }, + 'asset_loop' => { + message => q|A loop containing up to the first 50 assets that match the keyword.|, + context => q|Template variable.|, + lastUpdated => 0, + }, + + 'asset title' => { + message => q|The title of this asset.|, + context => q|Template variable.|, + lastUpdated => 0, + }, + + 'asset url' => { + message => q|The title of this url.|, + context => q|Template variable.|, + lastUpdated => 0, + }, + + 'keyword' => { + message => q|The keyword for this list of assets.|, + context => q|Template variable.|, + lastUpdated => 0, + }, + }; 1; diff --git a/t/Asset/Wobject/StoryArchive.t b/t/Asset/Wobject/StoryArchive.t index 68ed2c435..f3c9dfcd2 100644 --- a/t/Asset/Wobject/StoryArchive.t +++ b/t/Asset/Wobject/StoryArchive.t @@ -18,7 +18,10 @@ use strict; use lib "$FindBin::Bin/../../lib"; use Test::More; use Test::Deep; +use File::Copy qw/mv/; +use File::Path; use Data::Dumper; +use Path::Class; use WebGUI::Test; # Must use this before any other WebGUI modules use WebGUI::Test::Maker::Permission; @@ -58,7 +61,7 @@ $canPostMaker->prepare({ fail => [1, $reader ], }); -my $tests = 37 +my $tests = 38 + $canPostMaker->plan ; plan tests => 1 @@ -492,6 +495,33 @@ cmp_deeply( 'rssFeedItems' ); +################################################################ +# +# export Collateral tests +# +################################################################ + +my $exportStorage = WebGUI::Storage->create($session); +WebGUI::Test->storagesToDelete($exportStorage); +my $basedir = Path::Class::Dir->new($exportStorage->getPath); +$exportStorage->addFileFromScalar('index', 'export story archive content'); +my $assetDir = $basedir->subdir('mystories'); +my $assetFile = $assetDir->file('index.html'); +mkpath($assetDir->stringify); +mv($exportStorage->getPath('index'), $assetFile->stringify); +$archive->exportAssetCollateral($assetFile, {}, $session); + +my $exportedFiles = $exportStorage->getFiles(); +cmp_bag( + $exportedFiles, + [qw/ + keyword_roger.html mystories.rss mystories + keyword_foxtrot.html mystories.atom + keyword_echo.html + /], + 'exportAssetCollateral: correct files exported, including dummy directory' +); + } #----------------------------------------------------------------------------