Jump to content

PW web app; page permissions; saving custom fields; custom forms


Recommended Posts

Dear All,

I have to say that although the docs on PW are a bit scarce, the extremely helpful forum posts are great. Kudos to a responsive community! My MODX refugee status may soon be a thing of the past. :-)

After spending most of the day reading forum posts, etc, and experimenting, I have a few questions.

I'm building a website which will have a few public facing pages, but will mostly consist of member pages, where each member can only view and work with pages that they own. They will login, and then be redirected to their account home page, which will not have a url, but be assembled by a controller template and simply displayed with a generic url. (I think that's possible.)

The web app will be designed to lead them through a very lengthy series of forms that will have post processing hooks for things like calcluations. They'll have a "dashboard", i.e. an account page where they can click on various links to work with their data.

* PAGE PERMISSIONS:

I read a number of posts about page permissions, but it occurred to me that one way of doing it would be to create a data field attached to each of their pages that would be post-processed to save their user id in that page. So, I tried it out, and it seemed pretty solid. I'd love input on this, especially in case if I'm missing something or reinventing the wheel. Here's what I did:

I created an integer field called "page_owned_by_user_id", and added that to a basic page template, as a test. I manually typed in a user id of a test user in an article page that used that template (in action, it would be automatically added).

I then modified the basic page template with the following test code:

$user_id               = $user->id;
$page_owned_by_user_id = $page->page_owned_by_user_id;

if ( $page_owned_by_user_id != $user_id )
      {
      echo "Sorry: You can't view this page.";
      exit;
      }

 

I could of course place that in a function, e.g. "check_user_perms" and then just run the function. I would also add code to allow the viewing of public facing pages. Does this seem like an efficient method? It worked well, in my test, and simply added two id fields (pages_id and data) to a "field_page_owned_by_user_id" custom table.

* SAVING CUSTOM FIELDS:

Am I correct in thinking that if a page has a template attached to it, that the field group will allow one to automatically save all the custom fields into their various tables, if one uses the PW save function in code? Is this still true even if I use a "main.php" type of controller, as long as I use the page id in the save function? Also, see a twist on this question, below.

* CUSTOM FORMS:

I've considered trying to alter the admin templates for the above web app, but it's starting to seem more flexible for me to simply use the API, from a controller template file, and then build a whole series of links and forms, based on the user_id that I would capture after their login.

If that's true, then my question revolves around the task of building forms, and then saving the data, post processing the data and doing a variety of calculations, with field updates, as well as creating many new pages that would normally be in relational child tables.

In other words, any particular data entry form might be primarily from one template/field group, but it might also, in post process, assemble a series of field values that would go in child tables.

The "data tables" will of course be created in advance. The run time scripts will just save new data records, or edit or delete records.

I'm under the impression now that the function of creating a whole series of pseudo relational data tables is accomplished in PW by first creating the fields (whether reusable or not) and then creating a template with a field group for each particular set of fields, and finally creating ONE page for each pseudo data table (template / field group) that would serve as the parent "page container" for all the records.

(Assuming that those records needed to be viewed. I think that if they don't need to be viewed, I wouldn't need the parent page. Is that correct?)

Thus, I would save a data set collected from the forms to a new page under that parent container page, and use the template/field group that I had created for the corresponding pseudo "table."

Then, if I had to add data to a "child table", I would create a new record (i.e. save a new page), using a child template, and manually include the parent id in that child record.

Is the above anywhere close to correct?

Is it correct that doing all of the above with the PW framework API would be far easier than trying to twist the CMS app into shape to fulfill all those functions? I'm thinking that it might be, because of all the form customization and hooks.

However, if the PW CMS admin backend would be quicker, I'm all ears!

* ONLY ONE URL:

I'm also hoping that I can do all of this from a main.php type of controller file so that the user never sees any urls except something like /account/. I'm considering this for security, to not provide urls, like "/account/john_smith/". Except for public facing pages.

Is that possible? I'm not sure about this, because I'll need some paginated record functions, to list pages under a parent page, but it looks like it might be possible.

* EDITING FIELDS

Finally (well, at least for this post), am I correct that building my forms to edit a record would be most quickly accomplished by grabbing the fields of a data record "page" using the $page variable, and then populating the edit fields?

I've been using a Perl framework/app that I wrote that uses data dictionary files to define the attributes of each data field, including size, type and even list and checkbox/radio values. I then create an HTML template that includes tags for each field, like :!:first_name:!:, that then gets replaced in a loop with the newly populated values coming from the data record. This is done for the various modes of view, add, edit and update, so it's very flexible, and allows one to design the look and feel easily.

Does PW have anything close to that, or do I need to build those looping routines to replace tags with field values and attributes, by hand?

Thank you all for your very helpful responses!

Peter

Link to comment
Share on other sites

It's hard to say without knowing the exact app requirements and the types of data you wish your users to work with but the custom app approach seems like the way to go. Everything you describe seems pretty doable as well. You've already wrote a big post but if you could shed some light on what functionality and types of data a logged in user would typically work with we could come up with some suggestions of how to structure your app.

Link to comment
Share on other sites

Dear Sinnut,

Thanks! Let me think about how to briefly decribe that. I know my post above wasn't brief, so I don't want to overwhelm folks.

I think that one of my major questions is the ease of modifying the admin templates, including the edit functions, version coding things with the API.

For example, I would want to have a highly customized look and feel, with lots of hooks, etc, in the view and edit modes for any particular page.

I got the impression that trying to modify the CMS would be more work than going straight to the API. Part of this is because I don't know PW enough.

My business partner wanted to build all of this as a WordPress plugin, but I thought that might be a real wrestling match, and was thus grateful to find PW.

I'm impressed with the API of PW, but I wanted to especially get feedback about the Admin/CMS, in case I was missing something major about its flexibility.

Thanks!

Peter

Link to comment
Share on other sites

Does this seem like an efficient method? It worked well, in my test, and simply added two id fields (pages_id and data) to a "field_page_owned_by_user_id" custom table.

I think this seems like a fine method. There are some users/access modules that you might find helpful, particularly the Page Edit Per User module, that does something very similar to what you are doing. Though your application sounds pretty comprehensive and involved, so you may find any of these modules more as starting points or educational examples rather than complete solutions. 

Am I correct in thinking that if a page has a template attached to it, that the field group will allow one to automatically save all the custom fields into their various tables, if one uses the PW save function in code?

Yes. 

Is this still true even if I use a "main.php" type of controller, as long as I use the page id in the save function? Also, see a twist on this question, below.

I don't understand the question. But it shouldn't matter where you save the page from. The save() function should always behave the same way. 

(Assuming that those records needed to be viewed. I think that if they don't need to be viewed, I wouldn't need the parent page. Is that correct?)

The idea of a "parent page" is purely for structure and doesn't have anything to do with whether a page is viewable. Well, except for access control. If the parent's template defines access and the child's template doesn't, then the child page inherits access from the parent page. 

Is the above anywhere close to correct?

I think so, but you are writing about something in-between working directly with an SQL database and working with ProcessWire, so there is some ambiguity there–I don't follow everything you are saying. 

Is it correct that doing all of the above with the PW framework API would be far easier than trying to twist the CMS app into shape to fulfill all those functions? I'm thinking that it might be, because of all the form customization and hooks.

The API is how you accomplish everything from the code side in ProcessWire. When you know how to put the API to work, you can really automate quite a lot, and accomplish almost anything. 

I'm also hoping that I can do all of this from a main.php type of controller file so that the user never sees any urls except something like /account/. I'm considering this for security, to not provide urls, like "/account/john_smith/". Except for public facing pages.

What would you use to intercept actions then? GET/POST vars? I don't think there's any problem with using URLs. Avoiding URLs doesn't improve security in any manner I can think of. You'd want access protection either way. Requests that make changes to a database should be POST based, and requests to present information should get GET based (whether using URLs, URL segments or GET variables). 

Is that possible? I'm not sure about this, because I'll need some paginated record functions, to list pages under a parent page, but it looks like it might be possible.

ProcessWire includes helpers for doing pagination. Here is more about pagination

Finally (well, at least for this post), am I correct that building my forms to edit a record would be most quickly accomplished by grabbing the fields of a data record "page" using the $page variable, and then populating the edit fields?

Yes. Though most likely you'll call it something other than $page, since $page is the API variable for the currently viewed page. 

Does PW have anything close to that, or do I need to build those looping routines to replace tags with field values and attributes, by hand?

ProcessWire doesn't use a tag-based system, but of course they are very easy to implement for your own use. You might want to look at an existing tag engine like Twig or Smarty. Though if your needs are simple, a preg_match_all() with str_replace() is a reliable way to implement a simple tag engine. However, you may want to evaluate whether a tag engine is really necessary. PHP can do the job faster. So it really comes down to whether writing ":!:first_name:!:" over "<?=$first_name?>" is worth the overhead of a tag engine. 

One other thing I want to mention overall, is that this sounds like a completely custom application that may potentially be better suited to a full blown framework like Laravel. ProcessWire is both a CMS and a CMF, so it'll certainly do just fine with anything you can throw at it. But I'm questioning whether you need a CMS at all here, as it really sounds like more the territory of a dedicated framework. Personally, I would still build it in ProcessWire because that's what I work in. But you'll find a support system more focused on developing larger custom applications of this sort when working with a dedicated framework. You may still find ProcessWire to be a better fit for what you are doing, but do look at dedicated frameworks just in case. 

  • Like 2
Link to comment
Share on other sites

Dear Ryan,

I really appreciate your comprehensive answers! I was hoping you'd take a stab at it. :-)

I briefly looked at Laravel, and while it looks fascinating, as Mr. Spock would say, I feel much more kinship with ProcessWire. I will actually be building some public facing web pages, so the CMS will come in handy. And... as a MODX refugee, I believe that I've found its replacement for building "regular" websites, including some of my own, as well as clients'.

I've already started to build a small magazine site with PW, to get my feet wet, and I'm really enjoying myself. I'm also very encouraged by the fact that there are a number of MODX refugees here. (I wonder how many?) I used to think that MODX was the cat's meow in terms of flexibility and power, but I think now that PW might just beat the pants off MODX. We shall see...

I'm taking the structure of one my MODX websites, and looking at all the functions and items, like templates, snippets and chunks, to see how I can replicate or improve those same things, using PW. I'll report on that. It might be useful to come up with a MODX to ProcessWire Cheat Sheet (unless it's already here and I've missed it). I might write a first draft...

I think after I build this first website, I'll be a bit closer to understanding how I can use PW to build my membership web app.

Thank you again for your answers!

Peter

  • Like 1
Link to comment
Share on other sites

I've already started to build a small magazine site with PW, to get my feet wet, and I'm really enjoying myself. I'm also very encouraged by the fact that there are a number of MODX refugees here. (I wonder how many?) I used to think that MODX was the cat's meow in terms of flexibility and power, but I think now that PW might just beat the pants off MODX. We shall see...

Peter,

There's quite a number of us here (including me). Most(?) are no longer refugees though; we have found a new home in PW and are here to stay! :). IMHO and with lots of respect for MODX, PW is not the next best thing after MODX....PW is the best thing...

I'm taking the structure of one my MODX websites, and looking at all the functions and items, like templates, snippets and chunks, to see how I can replicate or improve those same things, using PW. I'll report on that. It might be useful to come up with a MODX to ProcessWire Cheat Sheet (unless it's already here and I've missed it). I might write a first draft...

Good idea. Been planning to do one but never got round to it. I'm no PW guru but I think:

  • MODX Snippets: In PW, you can replicate these in Template Files. Even more exciting, the capabilities of many MODX Snippets including the "main" MODX Snippets such as Ditto/getResources and Wayfinder are in-built in PW. The powerful PW API variables $page and $pages will do all (or most) of what you will require from Snippets. Other Snippet functionalities are provided by various PW modules. You can spice these up with some native PHP for even more advanced functionality. But $page and $pages will usually get you what you want.
  • MODX Chunks: These you can have as "includes" in your Template Files, i.e. use PHP to include them in your Template Files. You can also replicate Chunks using PW Fields. Fields can be reused, etc.

Looking forward to your MODX to PW cheat sheet! :)

Cheers,

/k

  • Like 1
Link to comment
Share on other sites

Dear Kongondo,

Thanks for your tips about snippets and chunks.

One thing that MODX did well, (I think, although it might have affected performance: I'm not sure) is that you could place snippet calls, template vars, and chunk tags directly into the body field of a page, in TinyMCE.

I used them both in templates, of course, so that's easy to replicate in PW.

But they're also useful in the articles. For example:

- a chunk that has a Javascript encoded email address, placed anywhere in an article field, e.g. "{{pfb.email}}.

- a template var (a custom field in PW), containing code that TinyMCE would choke on, like a form, or an Amazon-buy snippet of code, or anything.

I used [*code01*] 02,03... fields to place those items directly into the article body text. Note that I didn't want to have to mess with TinyMCE's settings too much, to allow raw code.

- I didn't place snippet calls in articles very often, but once in a while, I would add a special Ditto call in the middle of an article, that might show "the last ten headlines". It was easier to place that Ditto call in the middle of the article instead of trying to create a special template, to split the article in two places.

===

So, in PW, I'm planning to:

- store the chunks in fields/pages, and noted that one could do a loop replace on the chunks, from the template. That seems fine.

- I guess I'll do the same with the template vars (i.e. custom fields). Only the code* fields would be used, and looped over in template. The other fields would just be used in templates directly, as normal.

=> I'm wrestling with the snippets, however. If I had to migrate one particular client to PW, he would want a ditto call in the middle of an article.

I guess I could use a tag, and then run a function at that spot, from the template. I think I could run the function based on the tag name, e.g. 'ditto123'.

What are your thoughts about the above?

Thanks!

Peter

Link to comment
Share on other sites

Dear DaveP,

Thanks for those two links. For email, I've been using this utility:

http://w2.syronex.com/jmr/safemailto/

The ShortCodes module seems to be designed for use in templates, unless I'm missing something.

I need to parse the tags inside the body field. But maybe I could adapt that.

Best regards,

Peter



Dear Diogo,

Thanks! I must have missed that module.

So much to learn; so little time. :-)

Peter

Link to comment
Share on other sites

Dear Kongondo,

Thanks for your tips about snippets and chunks.

One thing that MODX did well, (I think, although it might have affected performance: I'm not sure) is that you could place snippet calls, template vars, and chunk tags directly into the body field of a page, in TinyMCE.

I used them both in templates, of course, so that's easy to replicate in PW.

But they're also useful in the articles. For example:

- a chunk that has a Javascript encoded email address, placed anywhere in an article field, e.g. "{{pfb.email}}.

- a template var (a custom field in PW), containing code that TinyMCE would choke on, like a form, or an Amazon-buy snippet of code, or anything.

I used [*code01*] 02,03... fields to place those items directly into the article body text. Note that I didn't want to have to mess with TinyMCE's settings too much, to allow raw code.

- I didn't place snippet calls in articles very often, but once in a while, I would add a special Ditto call in the middle of an article, that might show "the last ten headlines". It was easier to place that Ditto call in the middle of the article instead of trying to create a special template, to split the article in two places.

===

So, in PW, I'm planning to:

- store the chunks in fields/pages, and noted that one could do a loop replace on the chunks, from the template. That seems fine.

- I guess I'll do the same with the template vars (i.e. custom fields). Only the code* fields would be used, and looped over in template. The other fields would just be used in templates directly, as normal.

=> I'm wrestling with the snippets, however. If I had to migrate one particular client to PW, he would want a ditto call in the middle of an article.

I guess I could use a tag, and then run a function at that spot, from the template. I think I could run the function based on the tag name, e.g. 'ditto123'.

What are your thoughts about the above?

Thanks!

Peter

@Peter

Have the solutions suggested by Diogo and DaveP worked for you? Yes, you cannot (should not even?) place "snippets" (PHP) in text areas. I think the tag parser module would help here.

Expounding on the issue of chunks, looking at the wiki tutorial on creating a settings page (plus this post), such a strategy can be used to exclusively manage chunks, i.e. creating a chunks template (without a template file) and a chunks page (hidden but published). I suppose you know this already but I thought to post this here for others/reference...The beauty with PW is that the chunks can contain all sorts of data due to the wealth of fields PW offers. You can even get fancy and group related chunks using FieldSets.

/k

  • Like 1
Link to comment
Share on other sites

"You can also replicate Chunks using PW fields". Can you give me an example of this ? Thanks.

Pwired,

See my post (#11) above. I refer to this tutorial. The same principle can be used to use fields as chunks. MODX defines chunks as bits of static text which you can reuse across your site. In PW, chunks do not have to be text. They can be images, for instance. Based on that tutorial, the basics are:

  1. Create the fields you will need to hold chunk data. Choose from the different field types and settings as you require. Also for each field, fill in other helpful information such as field label. You can go further and add settings such as maximum length of field, placeholder text, etc. Example chunks could be a text field to hold contact information, company slogan, some footer text, etc.
  2. Create a chunks template. Call it chunks_template :) or whatever you fancy. Don't associate it with any template file. Edit and save the chunks_template to add the fields you have created to use as chunks. In the settings, you may wish to disable the "May Pages using this template have children?". Later, once you have done #3 below, you can also disable the "Can this template be used for new pages" setting.
  3. Create a chunks page that will be exclusively used to hold your chunks. You can call it "chunks". Let this page use your chunks template in #2 above. Mark the page as hidden but publish it. You will be able to access/use the chunk fields but this page will not appear in menus.
  4. Use PW API to grab and spit out your chunks where you want them to appear in your site (see examples in the wiki tutorial). For instance, assuming you named your chunks page "chunks" and have a contact information field called "contact_info" as one of your chunks field, you could grab and display this using the following code in your template file(s) associated with your other pages (i.e. other template files and not the chunks template ;)):
<?php echo $pages->get("/chunks/")->contact_info; ?>

Using this method, true to the philosophy of chunks, you can edit once and update all instances of the chunks. Even better, you edit everything in one place (page).

You can do other fancy things such as:

  • use Fieldset fields to group your chunks by "category" in your chunks page. E.g. contacts category, site meta information category, etc.
  • Use PHP if statements to display chunks on certain pages and not others, on certain days, seasons, etc. The possibilities are endless.
  • Do things like this to explode and display chunk data entered as a delimited list.

Note: these other "fancy" things are not limited to using fields as chunks in this way....they are just examples

Hope this helps :)

Cheers

/k

  • Like 5
Link to comment
Share on other sites

.......

The MarkupShortCodes module seems to be designed for use in templates, unless I'm missing something.

I need to parse the tags inside the body field. But maybe I could adapt that.

Peter, i think you are missing something because that module in essence allows for exactly what you are after. You can define shortcodes for basically any combination of html/php/js you wish. The whole power of raw php and PW API is at your fingertips. After you have defined your shortcodes they can be used in any text field in the PW admin, including tinymce/ckeditor fields just by using [tagnamehere] . An example from Nico:

<?php

//Template code
$shortcode = $modules->get('MarkupShortcodes');

$shortcode->add('config.urls.root', function($atts){
	return $config->urls->root;
});

$shortcode->add('config.urls.templates', function($atts){
	return $config->urls->templates;
});

$shortcode->add('url', function($atts){
	return $page->url;
});

$shortcode->add('id', function($atts){
	return $page->id;
});

echo $shortcode->render($page->body);
//end template code.

// the shortcodes can then be used in a textarea/tinymce (in this case the body field) with [config.urls.root] , [url] etc.

?>

Read carefully through this http://processwire.com/talk/topic/1819-markupshortcodes/ , you'll get the hang of it.

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...