Recent Changes - Search:

Cookbook

PmWiki

pmwiki.org

NewGroupBox

Summary: Input box to create new wiki groups from predefined template pages
Version: 2008-04-28
Prerequisites: pmwiki 2.1
Status: stable
Maintainer:
Categories: Forms CMS

Questions answered by this recipe

How can I enter the name of a group into a form, and a new page in the new group is created? How can I create a newgroup from a set of predefined template pages?

Description

This script is based on NewPageBoxPlus, but reverses group and name, so the name entered will be the group name, with a default HomePage. The form can be defined to create other pages by specifying a base=Group.Name parameter.

Download newgroupbox.phpΔ and place it into the cookbook/ folder and add to a local customization file:

include_once("$FarmD/cookbook/newgroupbox.php");

Usage:

(:newgroupbox [parameter=value] [parameter=value] :)

Possible parameters to use inside the markup:

  • base=PageName -- creates new group page as NewName.PageName (PageName does not need to exist). Default is NewName.NewName. So if you want HomePage to be your new group page, set base=HomePage.
  • template=Group.PageTemplateName -- use Group.PageTemplateName as template for new page.
  • value="Create New Group" -- label or value for the inside of the field, which disappears when clicking the box. Default is empty: "".
  • size=number -- size of input box, default is 30.
  • label="Button Label" -- label for the button, default "Create a new group called:".
  • button=position -- use "left" or "right" to position button (default is "left").
  • focus=true -- adds onfocus and onblur javascript which will make any intial value disappear when clicking on the box. Default is "".

The following options are only enabled if user has 'edit' authorisation, or var set: $EnableAutoSave = true;

  • save=true -- automatically saves the new page, if it does not exist already.
  • autogroup=true -- automatically creates various group pages according to template pages. See below.
  • autopages=Templates.HomePage,Templates.Page1,Templates.Page2 -- set a list of template pages, which will automatically be created in the new group. Specify also a base=PageName as one of the new pages, so the form can redirect to that page after creating all the new pages. save=1 does not need to be specified, autogroup=1 and template= will be ignored.

Example:

(:newgroupbox base=Index template=Site.NewIndexPage :)

Entering "Name" will create a new page called Name.Index, prefilled with content from Site.NewIndexPage

(:newgroupbox base=HomePage autopages=Templates.HomePage,Templates.Page1,Templates.GroupHeader :)

Entering "Name" will create new pages Name.HomePage, Name.Page1, Name.GroupHeader and redirect to Name.HomePage.

Notes

AutoGroupPages

A number of new group pages can be created automatically using the parameter autopages=[List of template pages]. See parameter autopages= above.

Alternatively by adding the option autogroup=true a HomePage, GroupHeader and GroupFooter page is created automatically according to template pages in the Templates group, whenever a new group page is created. More or different pages can be added by redefining the $AutoGroupPagesFmt array. This feature can be combined with the save=true option to create new groups with several predefined pages instantly.

Make sure you set the variables in config.php before including the newgroupbox.php script.

Thanks Pm for providing the AutoGroupPages function!

So for instance to create groups with pages MyPage1, MyPage2, HomePage, GroupHeader and GroupFooter you add to config.php:

$AutoGroupPagesFmt = array(
    'Templates.MyPage1' => '{$Group}.MyPage1',
    'Templates.MyPage2' => '{$Group}.MyPage2',
    'Templates.HomePage' => '{$Group}.HomePage',
    'Templates.GroupHeader' => '{$Group}.GroupHeader',
    'Templates.GroupFooter' => '{$Group}.GroupFooter',
     );
  include_once("$FarmD/cookbook/newgroupbox.php");

and on the group launching page you put:

(:newgroupbox save=true autogroup=true:)

or for a different display style:

(:newgroupbox label=Go button=right value="Create new group" focus=true save=true autogroup=true:)

And create all five template pages in the Templates group with the relevant content to prepopulate your new group pages.

To have the function AutoGroupPages available generally, i.e. creating the default auto pages everytime a new page is created, not just through newpagebox, set in config.php

$EditFunctions[] = 'AutoGroupPages'; 
$EnableAutoSave = true;

Release Notes

  • 2008-04-28: Added filter to exclude non-url characters. Fixed Call-time pass-by-reference error.
  • 2007-05-19: Added check to stop overwriting a page defined with $AutoGroupPagesFmt
  • 2007-05-02: Fixed buggy action=PageUrl
  • 2007-01-25: Optimised code so HTML output is minimised. Hidden fields are only added when needed by the markup. Removed size default.
  • 2006-11-27: Added var SDV($EnableAutoSave, false);. Automatic saving of new group pages is now possible only if a) user is authorised at 'edit' level, or $EnableAutoSave = true;
  • 2006-10-28: Added $RecipeInfo
  • 2006-08-17: Added ability for autopages and autogroup to post changes to (All)RecentChanges. Tidied up code. Swapped key => value around in $AutoGroupPagesFmt.
  • 2006-08-05: Added parameter autopages= to set a list of template pages for automatic group creation.
  • 2006-08-01: Added support to create automatically a number of pages for a new group. See AutoGroupPages above.
  • 2006-07-31: Changed default group page from Group.HomePage to Group.Group. If a Group.HomePage shall be created, add parameter base=HomePage to markup.
  • 2006-05-01: changed HandleAction to newgroup to avoid possible conflicts with newpagebox script. Added call to SaveAttributes when save=true, which saves link targets.
  • 2006-04-11: initial release

If the recipe has multiple releases, then release notes can be placed here. Note that it's often easier for people to work with "release dates" instead of "version numbers".

Comments

This works great, Hans! FYI, I am working on a course instruction wiki that would feature multiple courses separated into groups. NewGroupBox offers authors the ability to create a new 'course' without having to know a whole lot about how groups are constructed. Being able to specify the template is even cooler. Since there are several different pages that need to be edited for a new course (sidebar, menus, etc.) the next thing I'd like to do is figure out how to have a single entry "Group" and a bunch of different buttons that open up edit windows for each page within that previously-nonexistent group. Anyhow, thanks again. -- JonHaupt

Jon, you could have one newgroupbox form to create an initial page from a template page. Use save=true in the newgroupbox, and populate the template page with newpagebox forms, each using a different template to create all the necessary standard pages in the target group. all templae pages can be in one location, for instance a Template group. -- HansB

Hmm yeah, that's a great idea, sort of a temporary group-creation page. I've sort of done this already by creating edit links within the sidebar once you're in these groups that lead to pages using templates, but I like the idea of having a course help screen of sorts. -- JonHaupt

Hi Hans. I reckon NewGroupBox should have a different action name from NewPageBoxPlus (both use $HandleActions['new'] which can lead to conflicts when using both scripts). On my site I've updated NewGroupBox to have an action named newGroup. It also needs to save the tags from template page (when save=true).

It is fixed now, and link targets get saved as well with save=true. -- HansB May 01, 2006, at 02:37 AM

Hans, would it be possible to make it default that the new page name is the same as the new group name? So that if, for example, I made a new group Foo, then the new page created would be Foo.Foo rather than Foo.HomePage? That's the usual default when making new groups from scratch and I hate to lose that functionality. -- Kathryn Andersen July 29, 2006, at 08:50 PM

Thanks for pointing this out! I changed the default now as to your suggestion. If HomePage shall be the default new group page one needs to add now base=HomePage to the markup. ~HansB

RecentChanges Hi, Hans: I notice that creation of new pages with "save=true" via any of these variations doesn't add an entry to any (All)RecentChanges. I have a strong preference for having as much activity as possible reported, in some way or the other (there are other recipes I'd like to use but can't due to this problem of "invisible" activity). This recipe is so terrific that I'll probably use it anyhow, but it would sure be nice if you could find a way to add a "save=true" transaction to (All)RecentChanges. Thanks! TeganDowling August 16, 2006, at 01:05 PM

(All)RecentChanges get updated on my (local) testsite. The script does call the function PostRecentChanges when save=true. So I don't know what is going on for you :-(
PS: The autogroup pages are (by design) (at the moment) not appearing in (All)RecentChanges ~HansB
of course, the autogroup method is what I was thinking of. So, you will/may have the autogroup method call PostRecentChanges eventually? - TeganDowling
I am working on it right now, I got it half working, for autogroup, but not for autopages... And I like to be able to disable it via a variable. Can you suggest a better name for $EnablePostRecentChangesForAutoGroupPages ? HansB

save=true It seems to make no sense to use "autogroup=true" without also using "save=true". Should you make autogroup=true automatically set save=true, as you did with autopages? Thanks again, TeganDowling August 16, 2006, at 01:18 PM

Perhaps. But autogroup=true does the automatic creation of certain group pages, whereas save=true saves the page specified with base= automatically. Without save=true this page would open to be edited by the user. There may be ocasions where this is desirable I thought, so better keep that option. ~HansB

Call-time pass-by-reference has been deprecated. Error with PHP 5. Easy to fix; edit line 126. Sam Wilson May 12, 2007, at 02:36 AM

I don't know what you mean nor what you suggesting to change. Can you explain please? HansB
In PHP it is not neccessary to pass (as parameters) references to variables; it is enough that the function being called marks the parameters as references. In this case: the function AutoGroupPages($pagename, &$page, &$new) (line 144 of version 2007-05-02) doesn't need to be called as AutoGroupPages($pagename, &$page, &$new) as it is in line 126, becuase PHP already knows that the second two parameters are references; the two ampersands can simply be dropped. (This applies to recent versions of PHP, > 5.0.5 I think, but I'm not sure about that.) Hope this helps. Sam Wilson May 12, 2007, at 08:44 PM

Oh, and another thing: User submitting form must have edit permissions on form page? I'm not quite sure if I've got this correct, but it looks to be (and my site was behaving this way) as if the person submitting the NewGroupBox form must have edit permissions on the page on which the form is, if autopages is set (if $EnableAutoSave is false, that is). Why should this be the case? I'm using NewGroupBox to let users create their own groups, but they don't have edit access to the Main group, so the way things are they can't create the new group. If that makes sense. Anyway, I've sorted it out by just removing the "OR CondAuth($pagename,'edit')" from line 20 where it's decided whether to do the autopages or not. Thanks for a great script, by the way! Sam Wilson May 12, 2007, at 09:32 PM

I am trying to use NewGroupBox to create a collection of pages for a new group. However, it always blanks out whatever page I name in the base parameter. I am unable to pre-populate that page with information from my template. Am I abusing this recipe, or missing some underlying concept? Travis Risner March 18, 2008 at 6:00 PM ET.

Hi - NewGroupBox works great until you start entering special characters (#$%^...) into the form. Note what happens in the following cases:

  • with the base set to 'Index', entering "Blee Blah &$^&" results in the new page 'BleeBlah/Index' (this is fine - the characters are just taken out)
  • however, if you enter "Blee Blah &$^& Blech", one is sent to the newly created 'Site.BleeBlah' -- everything is thrown into Site...

overtones99 April 26, 2008, at 03:32 PM

Fixed now. - HansB April 28, 2008, at 11:21 AM

Hi - i've modified a version of NewGroupBox for myself that implements Captcha. See below for the additions one would make to the code (highlighted in blue):

beware - some of the longer lines have been cut in half so that they wrap w/o making the page too wide -- if running into compile problems, you may need to restore some of the longer lines to their full length

 # add form function. The values for parameter defaults can be changed here
 function NewGroupBox($pagename, $opt) {
    global $ScriptUrl,
    // ao - added captcha global vars //
    $EnablePostCaptchaRequired, $CaptchaKey, $CaptchaName; 
// ao - call captcha image func - must call this here in order // for $CaptchaKey to get loaded with a value
    $CaptchaImage = CaptchaImage($pagename);

    $defaults = array(
    	#'size'   => '30',
    	'label' => FmtPageName(' $[Create a new group called:] ', $pagename),
    	'button' => 'left',
    );
    $opt = array_merge($defaults, ParseArgs($opt));
    $buttonHTML = "    <input class='inputbutton newpagebutton' type='submit' value='{$opt['label']}' /> \n";
    $onfocusHTML = "
      onfocus=\"if(this.value=='{$opt['value']}') {this.value=''}\" onblur=\"if(this.value=='') 
        {this.value='{$opt['value']}'}\" ";
    $out = "\n  <form class='newgroup' action='$PageUrl' method='post'>
    	<input type='hidden' name='n' value='$pagename' />
    	<input type='hidden' name='action' value='newgroup' /> \n".
    	($opt['value'] ? " <input type='hidden' name='value' value='{$opt['value']}' /> \n" : "").
    	($opt['focus'] ? " <input type='hidden' name='focus' value='{$opt['focus']}' /> \n" : "").
    	($opt['base'] ? " <input type='hidden' name='base' value='{$opt['base']}' /> \n" : "").
    	($opt['save'] ? " <input type='hidden' name='save' value='{$opt['save']}' /> \n" : "").
    	($opt['autogroup'] ? " <input type='hidden' name='autogroup' value='{$opt['autogroup']}' /> \n" : "").
    	($opt['template'] ? " <input type='hidden' name='template' value='{$opt['template']}' /> \n" : "").
    	($opt['autopages'] ? " <input type='hidden' name='autopages' value='{$opt['autopages']}' /> \n" : "").
    	($opt['button']=="left" ? $buttonHTML : "").
    	" <input class='inputbox newpagetext' type='text' name='name' value='{$opt['value']}' 
            size='{$opt['size']}'" .
    	($opt['focus']=="true" ? $onfocusHTML : "").
    	"/> \n" .
    	($opt['button']=="right" ? $buttonHTML : "").
//// ao - captcha markup ////
    	($EnablePostCaptchaRequired==1 ? "<br /><input type='hidden' name='captchakey' value='{$CaptchaKey}' />
    	Enter code: <em class='access'>".$CaptchaImage."</em> <input type='text' name='{$CaptchaName}' 
           size='5' class='inputbox' /> " : "").

    	"  </form>";
    	return Keep($out);  
}


 # handles action=new, i.e. what the form sends, sends new page to edit
 function HandleNewGroup($pagename) {
  global $Author, $EnableAutoGroupPages, $AutoGroupPagesFmt,
  $EnablePostRecentChangesForAutoGroupPages, $EnableAutoSave, $MakePageNamePatterns,
// added captcha global //
  $EnablePostCaptchaRequired;
//// ao -- CAPTCHA REDIRECT IF CODE FAILS -- FROM Cookbook/CommentBoxPlus //// //// Redirect to same page
    if($EnablePostCaptchaRequired AND !IsCaptcha()) Redirect($pagename);
//// Uncomment to Redirect to an error page that you create
    //if($EnablePostCaptchaRequired AND !IsCaptcha()) Redirect('{*$Group}.CaptchaFailed');
... and then the rest of the recipe remains the same ...
overtones99 April 28, 2008, at 03:46 PM

...

hi - i'm noticing that when i use newgroupbox to create a new group, the creation date for the new page is always incorrectly given as 31 Dec 1969... i'm currently using the following code (from the bottom of PageVariables to get the creation date:

         # add page variable  in format yyyy-mm-dd
         $FmtPV['$PageCreationDate'] = 'strftime("%Y-%m-%d", $page["ctime"])';

When i create a group the "natural" way - i.e. by typing a new group and page into the address bar and then saving the new page - i get the correct creation date...
is there a way to fix this?
thanks, overtones99 June 02, 2008, at 03:50 AM

ah, just figured this one out - it appears 'ctime' was added to NewPageBoxPlus, but not to NewGroupBox. here's what i added to the recipe in order to get a correct creation time:

  
  if (@$_REQUEST['save'] AND ($EnableAutoSave==1 OR CondAuth($pagename,'edit'))) {
     //if(PageExists($newpage)) Redirect($newpage, $urlfmt);
     if(PageExists($newpage)) Redirect($nameTakenErrorRedirect);  // my own code, different than newgroupbox
     if (@$_REQUEST['template'] && PageExists($_REQUEST['template'])) {
        $p = RetrieveAuthPage($_REQUEST['template'], 'read', false, READPAGE_CURRENT);
          if ($p['text'] > '') $new['text'] = $p['text'];
          $new['author'] = $Author;
        }
        $new['ctime'] = $Now;   // was included in newpageboxplus, but not in newgroupbox
          . . . and so forth

and then one must also add $Now to the global variables defined at the top of the function block...
overtones99 June 02, 2008, at 04:37 AM

...

passing http variables into NewGroupBox & NewPageBoxPlus not working

i recently appended to my 'Site.PageNotFound' an amended invitation to create the Page or Group the user was trying to reach. depending on whether it's the Page or the Group that's nonexistent, the link leads to an upload page where either NewGroupBox and NewPageBoxPlus are loaded. the link to this page has an http variable appended to it containing the Page (or Group), in the form: MySite/CreateNewGroup?v={*$Group}.

on the CreateNewGroup page, the http variable is passed into the NewGroupBox "value"-parameter via an http request (see EasyHttpRequests). the problem i was running into was that after hitting submit, nothing would happen - it would just redirect to the Uploads page, and no page or group would be created. if i deleted the default input of the variable, and re-typed it in manually and then submitted, it would successfully create and redirect me to the new group/page.

i discovered that the problem in this scenario is relieved by commenting out the following line (in both NewGroupBox & NewPageBoxPlus):

	if (@$_REQUEST['focus'] && $name==$_REQUEST['value']) Redirect($pagename);

it makes sense that one wouldn't want the user to accidentally create a page with the name of the default text; however, this precaution preempts one from successfully submitting http variables... i wonder if there's a clever and efficient way to permit the variables and prevent the default submission?

overtones99 June 29, 2008, at 05:37 AM

...

Notification when New Groups are Created

Hi. with the current setup, when a new group is created (let's assume it's NewGroup/Index), no notification is sent out, even if FoxNotify or Notify are enabled. One would assume that this would work:

     $FoxNotifyList[] = "notify=admin@mysite.net group=-CoreGroup name=Index format=#newgroupnotify";
       or
     $NotifyList[] = "notify=admin@mysite.net group=-CoreGroup name=Index";

these DO work if one creates the page manually, by navigating to the new group's address and saving the new Index page, but doesn't when using NewGroupBox.

So, in order to trigger a Notify reaction, add either of the following two lines (depending on whether you're using FoxNotify or the core Notify) directly after PostRecentChanges($newpage, $new, $new) :

	PostNotify($newpage, $newpage, $newpage);   # this activates core Notify
          or
	FoxPostNotify($newpage);  # this activates FoxNotify
  • note that this solution won't work for everyone - it works for me because once NewGroup is created, my users won't be editing NewGroup/Index directly (which would trigger the notification response everytime they edited that page, which would be annoying) -- rather, they'll be editing other pages that are then included via template into NewGroup/Index, and hence Index will never be edited... another solution may need to be figured out for a more traditional PmWiki site structure...

overtones99 September 16, 2008, at 07:34 PM

...

See Also

Contributors

Edit - History - Print - Recent Changes - Search
Page last modified on September 16, 2008, at 07:34 PM