Pierre-Luc Posted June 17, 2014 Share Posted June 17, 2014 I’m seeking for your advice. I want to create a module that will allow generating unique IDs to fill different fields (in my specific case page names) according to different templates. Here’s the workflow I’m looking at: User creates a rule through Configuration -> Field generator that, given a template, will generate an ID. Here’s a mockup: I’d like if the page name could be automatically set right when the page is created. Also, what do I need to care about when updating the page, is there a risk it can be overwritten and is there a way to prevent that at all. They need to be permanent. I’d just like to know if it’s possible. I’ve begun looking at the different hooks, but there’s an overwhelming amount of them and I’m not sure where to begin. Would appreciate your input. 1 Link to comment Share on other sites More sharing options...
Soma Posted June 17, 2014 Share Posted June 17, 2014 This is in core. You can skip add page process and have name given automatic. Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 17, 2014 Author Share Posted June 17, 2014 This is in core. You can skip add page process and have name given automatic. Where is it? Could you provide a link to documentation, I didn’t find it. Link to comment Share on other sites More sharing options...
Soma Posted June 17, 2014 Share Posted June 17, 2014 I may responded too soon without reading carefully on mobile (not seeing screenshot). But there's a template setting only when the children template in family setting is selected. http://processwire.com/api/modules/process-template/ I'm not sure how to archive something you outlined for fields or what the exact need here for this is. But then I'm not sure there's already similar modules, though maybe not on different fields for different templates. Link to comment Share on other sites More sharing options...
Soma Posted June 17, 2014 Share Posted June 17, 2014 Maybe some hooks could be around fields or forms, Inputfield::render() Fieldtype::wakeupValue() ProcessPageEdit::buildForm() I'm not sure. Link to comment Share on other sites More sharing options...
netcarver Posted June 17, 2014 Share Posted June 17, 2014 @Pierre-Luc Take a look at the CryptoPPP library module which has a couple of generator routines (genKeys() and num2string()) that do almost all of what you'll need for this. Something like... $output = CryptoPPP::num2string(CryptoPPP::genKeys(), $length, $charset); ...where your $length and $charset choices are controlled by your form entries. All you need to do, apart from loading the library module, is check that the $output has not previously been generated if you really want to guarantee that it is unique. (The genKeys() routine is a pretty good pseudo random number generator but, as with all random number generators, its output is not guaranteed unique.) 4 Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 17, 2014 Author Share Posted June 17, 2014 @Soma I’ll look into it, it looks like I could simply add some way to make PW aware that it can use a random string generator instead of the date or title. @netcarver I already have a function that I reuse on every project for this, but I’ll look at your code thanks! 1 Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 17, 2014 Author Share Posted June 17, 2014 I found the code that generates the page name (/wire/core/Pages.php). I’m contemplating making the changes in core and make it more flexible. Thoughts? if(!$page->name) { // auto-assign a name if possible $format = $page->parent()->template->childNameFormat; $pageName = ''; if(strlen($format)) { if($format == 'title') { if(strlen($page->title)) $pageName = $page->title; else $pageName = $this->_('untitled'); } else if(!ctype_alnum($format) && !preg_match('/^[-_a-zA-Z0-9]+$/', $format)) { // it is a date format $pageName = date($format); } else { // predefined format $pageName = $format; } } else if(strlen($page->title)) { $pageName = $page->title; } else { // no name will be assigned } if(strlen($pageName)) { // make the name unique $pageName = $this->wire('sanitizer')->pageName($pageName, Sanitizer::translate); $numChildren = $page->parent->numChildren(); $n = 0; do { $name = $pageName; if($n > 0) $name .= "-" . ($numChildren+$n); $child = $page->parent->child("name=$name, include=all"); // see if another page already has the same name $n++; } while($child->id); $page->name = $name; } } Link to comment Share on other sites More sharing options...
Craig Posted June 17, 2014 Share Posted June 17, 2014 I don't think you will need to touch the core at all here. The code you mentioned is part of the ___setupNew() function. The underscores prefix mean it's hookable. This means you can create a module with your own function that runs before, after or to replace that one. You can find out about how to do that here: API - Hooks. 1 Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 17, 2014 Author Share Posted June 17, 2014 Thanks Craig, I’ve looked into it more closely. I have basic functionality running already, I think I’m gonna have a lot of fun with these hooks! Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 18, 2014 Author Share Posted June 18, 2014 For those interested, here’s the working proof of concept. https://www.youtube.com/watch?v=x4PedafmKas I have decided to use parent ID instead but I’ll implement template support soon. Should have something ready to release within a few days. 5 Link to comment Share on other sites More sharing options...
netcarver Posted June 18, 2014 Share Posted June 18, 2014 Nice. Some aspects are similar to the URL shortening module. Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 18, 2014 Author Share Posted June 18, 2014 That’s right, it’s a bit similar and can most probably used for short urls, but I wanted it for different things and flexible enough. I often have to implement comments, ratings and other things over which I don’t have control on the page name, and I didn’t want to use automatic naming or dates or have to code that every time, just a generic, automatic random string. With this module, I don’t have to worry about it, just make a new page, set title and other fields and it just works by itself, don’t even have to set $page->name! Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 18, 2014 Author Share Posted June 18, 2014 For those who want to try it, I have uploaded the project on GitHub. https://github.com/plauclair/FieldGenerator I strongly recommend you don’t use it in production for now. It runs correctly without problems, but the module doesn’t have an uninstall method yet. Since it creates system templates and fields, you won’t be able to delete those without going through a big hassle. Currently it also doesn’t have an administration panel, you’ll need to go (in tree) to Admin > Setup > Field generator, and create a new page using the fieldgenerator template. Page title has no effect apart from helping you remember what the rule is. 3 Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 19, 2014 Author Share Posted June 19, 2014 Just made a few commits to master. There is now an uninstaller, and the installer makes a few checks before trying to create things. https://github.com/plauclair/FieldGenerator It’s only missing the Setup panel now. Link to comment Share on other sites More sharing options...
Soma Posted June 19, 2014 Share Posted June 19, 2014 @pierre-luc, there's no reason/need to make fields and template system flag. Edit: Technically you don't need to "Process implements Module", abstract Process already implements Module. Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 19, 2014 Author Share Posted June 19, 2014 Thanks Soma, I just happen to have seen just that in apigen (class implements module). The reason I am using the system flag is that since the template and fields are required by the module which is part of the system, and that none of those templates or fields should be changed or removed by the user unless the module is uninstalled, it made more sense to make it system to prevent that. Does that make sense? Link to comment Share on other sites More sharing options...
Soma Posted June 19, 2014 Share Posted June 19, 2014 I know what it does. Just is it really required to to use template and fields for such a config? Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 19, 2014 Author Share Posted June 19, 2014 It could very well be implemented using a database table but why go that way when PW makes all those calls free? Link to comment Share on other sites More sharing options...
Soma Posted June 19, 2014 Share Posted June 19, 2014 Also as long as a template or field is in use you can't delete it anyway. Link to comment Share on other sites More sharing options...
Soma Posted June 19, 2014 Share Posted June 19, 2014 It doesn't have to be a db table. Modules have already a config interface you could use. No problem if you don't. Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 19, 2014 Author Share Posted June 19, 2014 I’ve seen that, but it didn’t seem so flexible to store some kind of repeaters that I can easily loop through. Sure I could implement all config through json but to be honest that sounds way more of a pain than required. I really wish there was more documentation about creating modules, especially best practices. Link to comment Share on other sites More sharing options...
Soma Posted June 19, 2014 Share Posted June 19, 2014 Yes agree. It's a lot easier to pull off with pages. I'm not sure about best practice here. Pages of course seems like a good option. Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 20, 2014 Author Share Posted June 20, 2014 Getting ready for release, it’s ready to test. I just committed version 0.9.0 which adds the setup panel. https://github.com/plauclair/FieldGenerator You can see it in action here: I would really appreciate that you submit bug reports on GitHub if you find anything. 2 Link to comment Share on other sites More sharing options...
Pierre-Luc Posted June 21, 2014 Author Share Posted June 21, 2014 I moved the topic to https://processwire.com/talk/topic/6727-field-generator/. This was initially only a question about how do I approach this, it’s useless now. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now