This forum has moved, please join us on github discussions. We will keep these old posts available for reference. Thank you!

Apostrophe-pieces-submit-widgets: easy contact forms, event submissions forms and more

We’re pleased to announce that the apostrophe-pieces-submit-widgets module has been published.

With this module you can easily set up submission forms for any type of piece without writing a lot of new code.

Check it out here:

https://www.npmjs.com/package/apostrophe-pieces-submit-widgets

Enjoy!

1 Like

Hello, thanks for such a cool module. However in the module setup you say that the scene should be set to ‘user’. However, I’ve noticed that this sets the context of the whole site to user, even if you are not authenticated. This results in the CMS loading a bunch of scripts/styles that I want to be visible only to the user, i.e. remove float on certain elements that in the ‘anon’ mode should be floated (having them floated in user mode prevents the user from editing the widget).

Is this behavior a bug or intentional? In the latter case, how do I prevent the CMS from loading user assets in the ‘anon’ mode?

This is intentional, without those assets javascript and styles you need to use apostrophe schema driven forms are not available.

I think I see your point, though, about impacts on the layout. Can you be a little more specific about what to look for in checking that out?

The thing is that the scene parameter does not seem to apply only to the component in which it is set. Instead the scene is applied globally to the whole site. Meaning that all my components inherit this scene and render the ‘editor’ and ‘always’ style sheets even if the user is not logged in. The ‘anon’ style sheets are completely ignored, so I can’t even override the styles set by the editor style sheet.

I don’t mind the forms pulling some extra stuff and honestly I like the approach that you’ve selected, but it feels a bit weird that making the forms pull that extra stuff changes the behavior of other completely unrelated modules.

I’ve tried to debug it a bit and I think the issue is in the load method of the apostrophe-widget class, which sets the scene to the whole request. Would it make more sense to store the scene as a widget specific option and process it in each widget individually instead of writing it to the whole request?

UPD:

I’ve gone a bit further and did the following for a test:

  1. from the widgets load() method I removed the part that sets the scene to the request
  2. I extended the push method of apostrophe-assets so it also adds the name of the module that pushes the asset
  3. in the filterAssets method of apostrophe-assets I added a check that makes sure that if the module that loaded the asset has scene defined and it matches that of the asset, that the asset is added to the bundle:

var assetLoadingModule = self.apos.modules[asset.module];
var relevant = (asset.when === ‘always’) || (when === ‘all’) || (asset.when === when) || (!!assetLoadingModule && assetLoadingModule.options && assetLoadingModule.options.scene === asset.when);

Now I do get the apostrophe-scheme user assets referenced on the page without affecting any other module, but apos.schemas is still undefined and calling the populate method results in an exception.

UPD2:

I extended the pushCreateSingleton method on apostrophe-schemas and now the apos.schema is properly initialized in the browser, however, calling the below code in user.js of apostrophe-schemas throws an undefined exception on $el.findSafe even though the array-modal.js is loaded;

self.findSafe = function($el, sel) {
  return $el.findSafe(sel, '.apos-field');
};

Am I missing anything?

In a nutshell, Apostrophe provides a very binary mechanism for saying “this page is going to need all the Apostrophe stuff.” You are wishing it was more fine-grained, which is fair, but allowing Apostrophe-driven forms means that pretty much everything could come into play, including the modals for picking pieces to relate them to joins. The findSafe jQuery extension is just the tip of the iceberg.

Also, while your approach to selectively pushing just the stuff wanted by particular modules in particular situations is interesting, it won’t really work with apostrophe’s minification pipeline for production sites, and you don’t want a zillion assets loaded individually in production. This is part of why Apostrophe really only has two asset scenes, “anon” and “user,” and everything is pushed to “always” (needed in both anon and user) or “user”.

Widget editing is also part of what can be used in schema forms… so the floating would make sense… you see how messy this gets.

But if there are cases where we’re applying that floating to widgets that are not inside areas the current user can edit, then that’s a bug. Would love to hear more about those.

Based on the instructions, the “contacts-form” could be modified to create a User Registration page if they don’t want to use Twitter/Facebook, but it’s not clear how it would tie in to the Login module. Maybe this is done somewhere already and I haven’t dug far enough yet.

Oh, that’s an interesting thought. We don’t currently have a user registration module for 2.x.

Doing it with this module would probably work if you included username and password in the array of allowed fields, however you would still have to log in afterwards, and your email address would not get confirmed in the way that is typically a requirement for registration on websites.

I would be inclined to say registration should probably be a separate widget following a similar pattern, and should provide the usual “confirm by email” pattern, at least as an option, and log the user in automatically once that is done.

Thanks for clarifying that for me. Though I cannot agree with this design decision, I guess I have to accept it – you must have had a reason to implement it this way. There is one thing however that in my opinion does not work as you describe it: if I have scene set to user, the anon stylesheet is not pushed. Is that a bug or am I doing something wrong?

UPD:

Having checked apostrophe-assets even further I noticed that this is probably how it should be. I’ve managed to work around my issue by implementing a check in my module that tells my widget whether the data.user._edit is true. Is there a way to access this information on the backend when the request and thus the data variable is not available?

One approach is to scope your CSS overrides to a CSS class that’s present in your widget.

Keep in mind that what you’re doing here is leveraging Apostrophe’s own editing capabilities. Generally speaking it makes sense that that comes with Apostrophe’s styles and scripts, because that makes them work.

However I think we should consider something like supporting:

scene: { scripts: 'user', stylesheets: 'anon' }

Setting a special class in the edit mode is exactly what I ended up doing. However the property indicating whether the user is in the edit mode or not appeared to be very well hidden inside the data.user object (data.user._edit). What if there was a global read-only property available to widgets and indicating which mode the user is currently in? It think having this property would make apostrophe developers’ life much easier and give them (us) much more control over how to render the content.