by
KK » Sat Jul 18, 2015 11:14 pm
While we are on the topic of cloning existing pages, allow me to post a solution that I created for a client recently.
He actually wanted to clone *all* the existing pages of a particular template.
As a first step of doing that, the solution created a tag named
cms:clone_page which when used in the context of a page-view would create a copy of the page. As the final step we used this tag in a 'staggered' manner as we do in CSV importer (
viewtopic.php?f=5&t=8803) to run the tag through all existing pages without the risk of running out of memory or timing out.
I think you'll find the first step (i.e. the cms:clone_page tag) useful.
Following is the full solution I proposed -
Please copy and add the following in your 'couch/addons/kfunctions.php' file (if the file is not present, you'll have to rename 'kfunctions.example.php' to 'kfunctions.php').
- Code: Select all
$FUNCS->register_tag( 'clone_page', clone_page_handler );
function clone_page_handler( $params, $node ){
global $CTX, $FUNCS, $DB;
if( count($node->children) ){ die("ERROR: Tag \"".$node->name."\" is a self closing tag"); }
// get page_id (return if used in any other context except page)
if( $CTX->get('k_is_page') ){
$page_id = $CTX->get('k_page_id');
$template_id = $CTX->get('k_template_id');
}
else{
die("ERROR: Tag \"".$node->name."\" can be used only in the context of a page to clone e.g. in a page-view or within cms:pages block");
}
// get page object
$pg = new KWebpage( $template_id, $page_id );
if( $pg->error ){
die( "ERROR: Tag \"".$node->name."\" - " . $pg->err_msg );
}
// and clone it
$DB->begin();
$cur_time = $FUNCS->get_current_desktop_time();
$rs = $DB->insert( K_TBL_PAGES,
array(
'template_id'=>$pg->tpl_id,
'page_title'=>$pg->page_title . '-Copy',
'creation_date'=>$cur_time,
'modification_date'=>$cur_time,
'publish_date'=>'0000-00-00 00:00:00',
'page_folder_id'=>$pg->page_folder_id,
'access_level'=>$pg->access_level,
'comments_open'=>$pg->comments_open,
)
);
if( $rs!=1 ){ $DB->rollback(); die( "ERROR: Tag \"".$node->name."\" - " . "Failed to insert record in K_TBL_PAGES for clone" ); }
$cloned_page_id = $DB->last_insert_id;
$res = $pg->_create_fields( $cloned_page_id, $pg->page_title, 1 );
if( $FUNCS->is_error($res) ){ $DB->rollback(); die( "ERROR: Tag \"".$node->name."\" - " . $rs->err_msg ); }
$DB->commit();
return;
}
The code above makes available a new tag named
cms:clone_page that if you can use to clone existing pages.
For example, if we place the tag above within a cms:pages loop that is fetching all your existing product pages, we'll get a clone of all those pages - e.g.
- Code: Select all
<cms:pages masterpage='products.php'>
<cms:clone_page />
</cms:pages>
However, the code above risks running out of memory or timing-out if the number of pages you have are large.
So, we'll use the 'staggered' technique (described here for the csv importer -
viewtopic.php?f=5&t=8803) to create a 'cloner' script that can work with any number of pages.
I'm attaching a very minimally modified version of the csv importer that automatically loops through your pages and clones them as it goes along. All the cloned pages will be in 'unpublished' state but will have all the data of the original pages.. You can then edit them as you wish
Please make sure to change the 'masterpage' parameter of the cms:pages within it to point to the products template.
Hope it helps.