-
Posts
17,109 -
Joined
-
Days Won
1,649
Everything posted by ryan
-
It sounds like you've got a good idea here, but I'm not sure that I understand? Are you talking about identifying what delegate inputfield class a Page inputfield uses? The ones you mentioned (checkboxes, radios, asmselect, etc.) fit that description. But I'm not clear about why you want to retrieve that or where you are showing it. It could also be that it's the end of the work day here and all my caffeine has long worn off. I might need to come back to this and read again in the morning.
-
Getting the Parent of selectable page(s) via the API
ryan replied to adrian's topic in API & Templates
In this case I think it's because the Inputfield keeps a copy of the parent ID rather than an instance of the page. The term 'parent' already has another meaning with Inputfields as one Inputfield can be a parent of another (like a Fieldset being a parent of a Text field, or the like). -
New PW Project - notification and approving page changes?
ryan replied to FuturShoc's topic in General Support
ProcessWire will do all of this, but Pete is right that you'd have to do it from the API side rather than click to setup. Probably what I will do is build some more formal workflow modules in upcoming versions of PW that do it out of the box but also give you a good starting point to modify from. Currently it's fairly trivial in ProcessWire to setup a workflow for approval of new pages to be published. But setting up the workflow for approval of modifications to already-published pages takes much more on the API code side. -
Nick--Thanks for using FormBuilder. I've updated your access so you can now see the Form Builder board. See this guide in the Form Builder board which may answer some of your questions, or let me know if you have any questions.
- 7 replies
-
- formbuilder
- form
-
(and 3 more)
Tagged with:
-
Thanks--It looks like there are two issues there I missed. I will take a closer look and attempt to fix these tomorrow morning.
-
Check the template of the page which will be added
ryan replied to doolak's topic in Modules/Plugins
Another approach you might take is to copy ProcessPageAdd.module to /site/modules/ProcessPageAddDoolak.module. Edit the file, and rename the class to be the same too. Then go to Modules > Check for new modules, and add your version of it. Go and edit the 'Add' page (Which is here: Admin > Page > Add). Change the 'Process' field from ProcessPageAdd to ProcessPageAddDoolak. Now you have full control over the page adding process. -
@doolak, it's working for me here, but I found it may depend where you are displaying the value. If you are using it for something on the admin side (where output formatting is off by default) it may not have worked. I just updated it to force the output formatting. Try it again with the latest and let me know if it works now?
-
@mindplay.dk: Separation of concerns, single responsibility principle, and so on -- I get it. You seem to think we're designing these things without understanding of these principles, and that couldn't be further from the truth. I'll also assume that you understand what I was stating before, that we've tried to adopt enough flexibility so that a developer can choose to adopt these principles, while still using the module interface. But we don't want to enforce that upon everyone because it would be counterproductive design. Why? There are principles, context, audience and goals. Our context is not the same as that of the Symphony framework, for example. Our audience has crossover, but is not the same. Most module cases are relatively tiny components. We have a project goal of making module development as simple and bulletproof as possible... something that might encourage web developers to take an interest in exploring their own module development. Part of that is an original design requirement of being able to share and communicate simple modules as 1 file / 1 class, when one chooses to (as many do). The ability to be super-simple and self contained like this encourages growth for the entire ProcessWire module ecosystem. We derive a lot of benefit from this, and that was the goal. It's not at the expense of the underlying principles unless you choose to make that sacrifice yourself. Don't develop your big module using the same strategy as your small module. We don't have many implied strategies for big modules and what's probably lacking most is just the documentation to explain when and why you might take one approach over another. Don't think I'm making any claims of perfection with any bit of code or design. There is always room for improvement in anything, in any project, in any system, in any file, in any class, in any method, and so on. The definition of a bad coder is someone that thinks they've got it all figured out or something is beyond improvement. I am very far from that. As most here know, I'll defend that which is worth defending and agree on things that aren't. But there's a lot more thinking behind the design than you often assume. I feel strongly about the decisions behind our current module system, and that they were the right ones. I also have an open mind. If someone proposes something better that understands not just the principles, but the context, audience and goals too, then I welcome it.
-
Wow this looks great Teppo! I can't wait to try this one out tomorrow.
-
This is due to the way strtotime() interprets dates. It interprets dates with slashes as US-style mm/dd/yy and dates with hyphens or periods as dd-mm-yy.
-
You might find the attached LazyCronTest.module helpful. This basically just demonstrates LazyCron in action. Install this module after LazyCron is installed, and it'll record a log entry every 5 minutes (or so) to /site/assets/logs/lazytest.txt. That's assuming the site is getting non-cached pageviews so that LazyCron gets a chance to run. LazyCronTest.module <?php class LazyCronTest extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Lazy Cron Test', 'version' => 100, 'summary' => 'Tests lazy cron by writing to a log file in /site/assets/logs/lazytest.txt', 'singular' => true, 'autoload' => true, ); } public function init() { $this->addHookAfter('LazyCron::every5Minutes', $this, 'lazyTest'); } public function lazyTest($event) { $seconds = $event->arguments[0]; $log = new FileLog($this->config->paths->logs . 'lazytest.txt'); $log->save('LazyCron 5 minute test - ' . date('Y-m-d H:i:s') . " - $seconds seconds"); } } Here's an example of the log file it generates: 2013-02-02 11:19:02:LazyCron 5 minute test - 2013-02-02 11:19:02 - 356 seconds 2013-02-02 11:24:04:LazyCron 5 minute test - 2013-02-02 11:24:04 - 302 seconds 2013-02-02 11:31:52:LazyCron 5 minute test - 2013-02-02 11:31:52 - 468 seconds 2013-02-02 11:37:22:LazyCron 5 minute test - 2013-02-02 11:37:22 - 330 seconds 2013-02-02 11:43:14:LazyCron 5 minute test - 2013-02-02 11:43:14 - 352 seconds 2013-02-02 11:49:13:LazyCron 5 minute test - 2013-02-02 11:49:13 - 359 seconds 2013-02-02 11:54:37:LazyCron 5 minute test - 2013-02-02 11:54:37 - 324 seconds 2013-02-02 12:00:07:LazyCron 5 minute test - 2013-02-02 12:00:07 - 330 seconds 2013-02-02 12:05:07:LazyCron 5 minute test - 2013-02-02 12:05:07 - 300 seconds 2013-02-02 12:12:42:LazyCron 5 minute test - 2013-02-02 12:12:42 - 455 seconds 2013-02-02 12:18:35:LazyCron 5 minute test - 2013-02-02 12:18:35 - 353 seconds 2013-02-02 12:23:37:LazyCron 5 minute test - 2013-02-02 12:23:37 - 302 seconds 2013-02-02 12:30:54:LazyCron 5 minute test - 2013-02-02 12:30:54 - 437 seconds 2013-02-02 12:36:22:LazyCron 5 minute test - 2013-02-02 12:36:22 - 328 seconds 2013-02-02 12:41:57:LazyCron 5 minute test - 2013-02-02 12:41:57 - 335 seconds 2013-02-02 12:50:48:LazyCron 5 minute test - 2013-02-02 12:50:48 - 531 seconds 2013-02-02 12:56:58:LazyCron 5 minute test - 2013-02-02 12:56:58 - 370 seconds 2013-02-02 13:03:03:LazyCron 5 minute test - 2013-02-02 13:03:03 - 365 seconds 2013-02-02 13:15:03:LazyCron 5 minute test - 2013-02-02 13:15:03 - 720 seconds 2013-02-02 13:26:03:LazyCron 5 minute test - 2013-02-02 13:26:03 - 660 seconds 2013-02-02 13:31:46:LazyCron 5 minute test - 2013-02-02 13:31:46 - 343 seconds 2013-02-02 13:37:37:LazyCron 5 minute test - 2013-02-02 13:37:37 - 351 seconds Notice how the number of elapsed seconds is always more than 5 minutes (and sometimes a lot more). That's just because it has to be triggered by a PageView. In most cases, this is okay because a lack of pageviews usually means there's nobody there to see what was updated anyway.
-
Twig is a nice template engine. I'd like to explore the possibilities of expanding upon what porl started with that module sometime. Though ProcessWire will always be based on a PHP API, but I'd like us to have a simple integration method for supporting other template engines for the people that want them.
- 74 replies
-
- template engine
- twig
-
(and 8 more)
Tagged with:
-
Awesome work Wanze! Thanks for posting it. I'm also thrilled to see the awesome things people are doing with the blog profile as a base.
-
Soma, I'm not totally sure I understand just because I've not seen buttons look like that before. I could probably figure it out by digging a little deeper in the code, but I'm trying to get through a large queue of messages in a short amount of time (they dont' give me much on the weekend!). If there's a code change you think would be worthwhile in the core CSS, let me know what to change (post code here or pull request, etc), and I'll make it.
-
It wouldn't be from PW's cache unless you aren't logged in, and you are using cache features. But it's not much of a mystery when you encounter that. I'm guessing it's not the case in your instance. Lots of the *AMP installs (like MAMP) come with a PHP cache built-in. It's certainly possible that could cause something like you've mentioned. But personally, I've not experienced any unexpected behavior like you are describing, and I'm literally using PW all day every day. Check and see what PHP cache you might be using, just in case.
-
Suggestion for PW theme or future development
ryan replied to PHPSpert's topic in Wishlist & Roadmap
Nik's AfterSaveActions module is also a great time saving optimization for when you are creating pages, templates, fields. I was using it just yesterday on a site where I needed to add a hundred or so pages via copy/paste (the content was too inconsistent in order to automate it with something API-driven). I set my 'after save action' to 'create another sibling page', and it probably cut the time it would have taken in half. -
That's a good idea. Though I'd still be nervous about it. Something to think about adding though... One way you can override things on your own is to edit the Fieldtype module file that you want to convert from. So if you've got a float that you want to convert to a string, edit /wire/modules/Fieldtype/FieldtypeFloat.module and add the following function to it (temporarily): /** * Return Fieldtypes that are compatible with this one (i.e. ones the user may change the type to) * * @param Field $field Just in case it's needed * @return Fieldtypes|null * */ public function ___getCompatibleFieldtypes(Field $field) { $fieldtypes = new Fieldtypes(); $fieldtypes->add($this->fieldtypes->get('FieldtypeText')); return $fieldtypes; } If the Fieldtype you are editing already has that function, that you could just modify it according to what you need.
-
Check the template of the page which will be added
ryan replied to doolak's topic in Modules/Plugins
For the most part, you only want to hook into Process modules if you are manipulating something on the admin interface side. Process modules don't get used for anything else. So if a page is added from some other method in the API, your ProcessPageAdd hook would never get called. Instead, you'd want to hook Pages::added to get a $page that was just added. Or you'd want to hook into Pages::saveReady if you wanted to get it before it was added. If using saveReady, you'd just confirm that it's a new page being added by it not having a $page->id (already existing pages will have a $page->id). If you find you still need to hook ProcessPageAdd, tell me more about what you are trying to do and I can add an appropriate hook. public function init() { $this->pages->addHook('added', $this, 'hookPageAdded'); $this->pages->addHook('saveReady', $this, 'hookSaveReady'); } public function hookPageAdded(HookEvent $event) { $page = $event->arguments[0]; $template = $page->template; // here's your template } public function hookSaveReady(HookEvent $event) { $page = $event->arguments[0]; if(!$page->id) { // new page about to be added $template = $page->template; // here's your template } } -
getting current $page in a Inputfield or Fieldtype module
ryan replied to Martijn Geerts's topic in Module/Plugin Development
Nearly all built-in Fieldtype functions are passed a copy of the $page and $field being edited. So you pretty much always have a copy in your Fieldtype. For example, every Fieldtype has this function: /** * Return a new Inputfield, ready to be used * * @param Page $page Page being edited * @param Field $field Field that needs an Inputfield * */ public function getInputfield(Page $page, Field $field) { // $page is the Page you want } Since there is only 1 copy of any given Fieldtype in memory at once, you don't want to keep any copies of $page outside of the individual functions because the same Fieldtype instance might get called several times for different pages within the same request. Inputfields are different: They aren't supposed to know anything about the page being edited, because Inputfields are used for far more than just pages. There will be multiple instances of the same Inputfield in memory at once. Basically, there is a new instance of it for every single input that's needed. Unlike Fieldtypes, Inputfields don't get reused for multiple fields of the same type. Since Inputfields aren't supposed to have a $page context, they don't already have a copy of it anywhere. However, if you need one, you can pass it a copy from your Fieldtype's getInputfield method, shown above: /** * Return a new Inputfield, ready to be used * * @param Page $page Page being edited * @param Field $field Field that needs an Inputfield * */ public function getInputfield(Page $page, Field $field) { $inputfield = wire('modules')->get('InputfieldSomething'); $inputfield->set('editPage', $page); // give it a copy of $page being edited return $inputfield; } Now InputfieldSomething can access the $page from $this->editPage. This is what FieldtypeRepeater does for InputfieldRepeater, btw. -
When you change a field's type, it doesn't keep the configuration settings for the old one around. That's because the new one may have very different settings or may conflict with the new one. So it's safest to start fresh on this. Tags is one that could feasibly stick around, so maybe we'll find a way to do that in the future, but for now we reset the field's settings when you change it's type.
-
I've updated it so that it can now support using formatted values before concatenation--like you would want with dates. Grab the new version (1.0.1). Then, in your format string, just specify an exclamation point after any field names you want to use the formatted version for. For example, "title, date!" rather than "title, date".
-
What I've extracted is that you don't like statics. You've set a goal of avoiding statics at all costs. And that's fine--I understand your reasons. I'm middle of the road on statics--I avoid them, but not at all costs. There is a reason they don't appear in PW's public API. But if they are the best fit for a given situation, given all factors, then I'd consider it a bad choice to use something else. We've got very good reasons for using them where we do. I hope you can understand why we wouldn't abandon an interface that works very well for us just because one person doesn't like statics. What I wrote in my previous message was that I support your ideas, but as an alternative method of configuration, not as a replacement. Step out of the ivory tower and propose something tangible and realistic. Use some code. For instance, I understand you'd like to have a separate class to handle configuration. I like this idea for many situations. So how would you formalize that in code? What specific methods would be in the ModuleConfig interface or abstract base class? How would you propose relating the configuration class to the module class? I'd suggest that it could be done by an agreed-upon class name, like "Config[ModuleName] implements ModuleConfig", or a module's getModuleInfo() could specify it's configuration class in it's info array. But maybe there's more ideas too. Get some momentum going here and maybe we'll have something we can commit to the code base now rather than later. I understand why it matters in many situations. But this distinction does not matter in ProcessWire modules. Can you think of any instance where it does? We go out of our way to keep these considerations away from those actually using the module. I don't yet know much about Laravel, so can't knock it or praise it. But I was turned off by the syntax I was seeing in the examples. Though I can find plenty to like after a quick look too. But it does seem like a lot of people are treating Laravel as God's greatest gift to PHP. So far I don't understand. Maybe there's something to learn here, even if there is some to dislike as well. While I don't hate statics like you do, I do agree in general -- I don't much like seeing them in APIs. That's why you don't seem them in ProcessWire's API.
-
In real usage, ^= and $= just aren't that useful when paired with a fulltext index, because fulltext indexes store words, not partials. I actually cant think of any situation where the old fulltext implementation for those is worthwhile. I dont think anyone was using them, as a result. The %^= syntax is far more useful. But I don't want to have something as cryptic as %^= and %$= being part of our official set of operators... Would rather leave it as undocumented and eventually deprecate it, and let ^= and $= take the behavior. That's really how they were supposed to behave in the first place. So that change you linked was my attempt to correct the behavior of those.
-
You should also be able to retrieve them via just $field->tags or $template->tags
-
There isn't a page like this that exists in the system unless you are an admin and can view user accounts in Access > Users. However, you certainly could create a template on your front-end that does something similar. You can iterate all users by: foreach($users as $user) { // ... } You can retrieve any user by: $u = $users->get(123); // user ID; or... $u = $users->get('ryan'); // user name Here is the $user API which shows you what you can do once you've located the user you want to display.