Summary: Talk page for NewGroupBox.
Users: +2 (View / Edit)

This space is for User-contributed commentary and notes. Please include your name and a date along with your comment.


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

5/1/2017 Pierre : But if i want that the newpage is NameGroup.NameGroup ? Thanks

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 //
//// 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[] = " group=-CoreGroup name=Index format=#newgroupnotify";
     $NotifyList[] = " 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
	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

It would be better to have the default group created to be NewName.{$DefaultName}. This is because it would comply with the existing wiki settings.

simon May 10, 2015, at 03:43 PM

Lambda group name

I've got an interesting problem where, when I create a new page, say with the intended name of "NewTest" the name comes out as "Lambda2341ewLambda2341est/HomePage"

The code I am using is (:newgroupbox value='new workspace (typically your name)' base=HomePage button=right size=32 focus=true template='Workspace.Template' save=true label='New workspace':)

Has anyone else had this problem?

Could it be because of the "/e" in the following

# add markup (:newgroupbox:)
Markup('newgroupbox', 'directives',
  "NewGroupBox(\$pagename, PSS('$1'))");

Petko advises (via the mailing list)

Instead of the code on line 108-109 of newgroupbox.php, it could use something like:

$group = PPRA($MakePageNamePatterns, $requested_sanitized_name);

or possibly call MakePageName().

With the changes required for PHP 5.5 compatibility, the core $*Patterns arrays contain some Lambda function names to be evaluated. Recipes using these patterns directly (rather than calling core functions like MakePageName) could do it one element after another, and use preg_replace() for strings or preg_replace_callback() for function names.

Or, use the helper function PPRA($array, $str) which does exactly that:

simon May 13, 2015, at 12:08 AM

Talk page for the NewGroupBox recipe (users).