-
Posts
6,314 -
Joined
-
Last visited
-
Days Won
318
Everything posted by bernhard
-
I've created an issue in the requests repo - please give it a thumb up to show demand for such a feature! https://github.com/processwire/processwire-requests/issues/396
- 4 replies
-
- module
- translation
-
(and 1 more)
Tagged with:
-
I've created an issue in the requests repo - please give it a thumb up to show demand for such a feature! https://github.com/processwire/processwire-requests/issues/396
- 19 replies
-
- multi-language
- i18n
-
(and 1 more)
Tagged with:
-
I've created an issue in the requests repo - please give it a thumb up to show demand for such a feature! https://github.com/processwire/processwire-requests/issues/396
- 12 replies
-
- 1
-
- translate
- multilanguage
-
(and 2 more)
Tagged with:
-
RockMigrations1 - Easy migrations from dev/staging to live server
bernhard replied to bernhard's topic in Modules/Plugins
Great update - working with access control got a lot easier today ?? Access Control ProcessWire has a powerful access control system. When using RM to create new templates and pages it is quite likely that you also want to create roles and define access for those roles on the new templates. The basics of access control can easily be done via RM - for more advanced topics you might need to implement custom solutions. PRs welcome ? Let's say we created an Events calender and we wanted to store all events (tpl event) under one page in the page tree. This page (tpl events) would only allow pages of type event. To manage those events we create a new role on the system called events-manager. $rm->migrate([ 'templates' => [ 'events' => [...], 'event' => [...], ], 'roles' => [ 'events-manager' => [ 'permissions' => ['page-view', 'page-edit'], 'access' => [ 'events' => ['view', 'edit', 'add'], 'event' => ['view', 'edit', 'create'], ], ], ], ]); On more complex setups you can use the API functions that are used under the hood directly. For example sometimes I'm encapsulating parts of the migrations into separate methods to split complexity and keep things that belong together together: /** * Migrate all data-pages * @return void */ public function migrateDatapages() { $rm = $this->rm(); // migrate products (having two custom page classes) // these have their own migrations inside their classes' migrate() method // where we create fields and the template that the class uses $product = new Product(); $product->migrate(); $products = new Products(); $products->migrate(); $rm->setParentChild(Products::tpl, Product::tpl); $rm->setTemplateAccess(Products::tpl, self::role, ["view", "edit", "add"]); $rm->setTemplateAccess(Product::tpl, self::role, ["view", "edit", "create"]); // same goes for all other data pages // ... } -
Funding ProcessWire / More community efforts
bernhard replied to pideluxe's topic in Wishlist & Roadmap
I'd be happy to be wrong with my opinion here ? I've put a lot of effort in setting up my infrastructure and it looks like finally I've found a good combination of all the puzzle pieces playing well together (Hosting+Server administration, GIT for version control, RockMigrations for Migrations, RockShell for all the maintanance and installation stuff to spin up a new pw instance, create db dumps and restores etc.). I just have the feeling that 90% are happy with the usual workflow: develop locally or directly on the server (I've done that myself for years) and then simply copy files over. That's something that any regular hosting provider supports... and my feeling is 80% of the remaining 10% are happy managing it on their own. If I'm wrong and anybody is looking for processwire hosting in DACH write me a PM ? -
PW 3.0.175 – Core updates: new DB scalability feature
bernhard replied to ryan's topic in News & Announcements
Crazy stuff - I hope I'll need this feature one day ? -
Funding ProcessWire / More community efforts
bernhard replied to pideluxe's topic in Wishlist & Roadmap
I'm not sure who would really pay for such a service. Most of PW users are tech-savvy, so I guess they WANT to have the control over their infrastructure (or choose any of the cheap hosting providers out there...). Installing PW is no problem for them. On the other hand people that dont want to handle any technical aspects (like hosting or installing PW) are likely more happy with one of the plug&play CMSs?! -
/site/modules/MyModule/MyModule.module.php /site/modules/MyModule/FieldtypeMyModule.module.php /site/modules/MyModule/InputfieldMyModule.module.php Then add FieldtypeMyModule and InputfieldMyModule to the "installs" array of MyModule.module.php and MyModule to "required" array of the fieldtype and inputfield.
-
Well, feel free to do so - I'll happily drink them with my friends once the pandemic is over ? http://paypal.me/baumrock Hooking the page edit form is a lot easier: $wire->addHookAfter("ProcessPageEdit::buildForm", function($event) { $form = $event->return; $page = $event->process->getPage(); if($page->template != 'yourtemplate') return; if($f = $form->get('yourfield')) { $f->notes = "Show allergens <a href='/link/to/allergens' class='pw-panel'>here</a>"; $f->entityEncodeText = false; } });
-
Funding ProcessWire / More community efforts
bernhard replied to pideluxe's topic in Wishlist & Roadmap
That did not work in 2014 - maybe it works in 2021 - wow, time flys ? https://processwire.com/talk/topic/7400-instant-processwire-dev-hosting-lightningpw/ -
Interesting idea. I've had a look. There is no way of doing this via PHP, but it's quite simple to do via JS: $(document).ready(function() { pwPanels.addPanel($("#pw-masthead a[href=/your/admin/link/url]")); }); Note that this will not work for json loaded links. You'd need to intercept the click event and init the panel on the fly, see https://github.com/processwire/processwire-requests/issues/176
-
Your link to my example is wrong - I guess you mean this one ? The main advantage of using constants is not about being able to change names (as that happens almost never) but to get better structure into your code and also get additional information that you do not get from regular strings or object properties. And I'm using it a lot with array syntax but you are absolutely not limited to that! And you cal of yourse always use class constants in strings: $pages->find("template=".Foo::tpl); But here are some very simple examples why I'm using that approach in the first place. Imagine you wrote code 1 year ago and look at it to fix a bug or add a feature. Compare those two: // example migration $rockmigrations->createField("type", ['type' => 'text', 'collapsed' => 2]); // example find $pages->find("template=animal,type=1|2,category=3|4|5"); // example migration $rockmigrations->createField(Animal::field_type, [ 'type' => 'text', 'collapsed' => Inputfield::collapsedBlank, ]); // example find $pages->find([ "template" => Animal::tpl, Animal::field_type => [Animal::type_cat, Animal::type_dog], Animal::field_category => [ Category::small, Category::medium, Category::large, ], ]); Or with better syntax highlighting: Imagine you had to answer these questions: where (to which pages or logical parts of your app) does the "type" field belong to? which animal-categories am I listing with my page find operation? what is the collapsed state of my Inputfield? Which of the two code bases above would you want to manage? ?
-
yes, just set visible=false http://tabulator.info/docs/4.9/columns#visibility
-
100% recommendation for tabulator! I'm using it all over now in several projects and I'm finally very happy. Having tried datatables, aggrid and tabulator I can say that I've tried a lot of them and tabulator is IMHO the best overall - and it's MIT ? The custom filter you are talking about should be easy. If you need help just give me a shout ?
-
You can think of it like this: Fieldtype = responsible for storing/sanitizing data Inputfield = responsible for UI/markup That's why it is very simple to create an inputfield. A very basic inputfield could just output "hello world" without any connection to the DB or other business logic. It's not exciting to avoid the DB, but if its not necessary because you use the Inputfield just for presentation then you can simply save time/effort that is not needed ? On the other hand using Inputfields instead of plain HTML has the benefit that you get a UI component that every PW user is familiar with and that you can control like any other Inputfield (setting columnWidth, toggling, label, icon, ...). See https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/#adding-your-first-field-inputfieldmarkup The name INPUTfield can be a little confusing at the beginning, but after time it made a lot of sense for me and I could not think of a better wording now.
-
Note that when using id="date" you may only use one date on one page. I'm not using HannaCode at all, maybe you can use PHP to generate an unique id? <?php $id = "date_".uniqid(); ?> <p id="<?= $id ?>"></p> ... document.getElementById("<?= $id ?>").innerHTML = datum;
-
Custom Classes for Page objects - The Discussion
bernhard replied to szabesz's topic in API & Templates
I have never claimed anything different. That's why I think several of your statements sound like you did not get what I was trying to say even though you say you did. But it does also not sound like you want to hear another explanation so we can leave it with that ? Using custom page classes is great with or without using my technique ? -
Custom Classes for Page objects - The Discussion
bernhard replied to szabesz's topic in API & Templates
You must have something else going on. I just tried it with a custom HomePage class in site/classes/HomePage.php <?php namespace ProcessWire; class HomePage extends Page { public function ready() { bd('ready!'); } } And in ready.php $p = new HomePage(); $p->ready(); And it properly dumps "ready!" to the tracy bar ? -
Custom Classes for Page objects - The Discussion
bernhard replied to szabesz's topic in API & Templates
Sure ? That does simply mean that the hook runs only for cats (template=cat) and it only runs for pages that have no ID yet, meaning it runs only when the page is created (before it is saved the first time). That means we only set the page name before the first save and then leave it untouched on every following save. Edit: I renamed the method to "onCreate" to make it more obvious! -
Custom Classes for Page objects - The Discussion
bernhard replied to szabesz's topic in API & Templates
But I was ? And I tried to explain why... IMHO not That's what I was trying to explain. I'm using custom page classes in an object oriented way (similar to PW modules). And that's great because you have all your code pieces in one place - namely in one single php file of your custom page class. Let's say we build a webpage about cats. Step one: Create a custom page class and place it in /site/classes <?php namespace ProcessWire; class Cat extends Page { } Now all cats in our system are of type "Cat", and that's great! Now we want a custom headline for every cat on our frontend based on the title field, easy: <?php namespace ProcessWire; class Cat extends Page { public function headline() { if(!$this->title) return "This cat has no name"; return "Details for Cat '{$this->title}'"; } } In your template <h1><?= $page->headline() ?></h1> And that you'll do for any kind of business logic your application needs. Now what if we wanted to manage thousands of cats and we wanted every cat have a unique 4-letter page name instead of one based on the title (to prevent ugly suffix urls like catname-1, catname-2 etc)? We could do that easily with a hook. In the past one might have put the hook into ready.php and after time your ready.php grows and grows and grows and some day you totally lose control over your hooks and over your software. Not if you place them where they belong: Into the page class to the cat object: <?php namespace ProcessWire; class Cat extends Page { public function init() { $tpl = "template=cat"; $this->addHookAfter("Pages::saveReady($tpl,id=0)", $this, "onCreate"); } public function headline() { if(!$this->title) return "This cat has no name"; return "Details for Cat '{$this->title}'"; } public function onCreate($event) { $page = $event->arguments(0); $page->name = $event->pages->names()->uniqueRandomPageName(4); } } That's how you'd attach a hook in an autoload module, and that's what I suggest: Structure your custom page class just like an autoload pw module. Apply the same principles and your code will get better readable, better understandable and better maintainable. Now the only problem ist, that init() of the page class does not get called like it gets called in an autoload module. Neither does ready(). But it's simple to overcome this - just place this in init.php $cat = new Cat(); $cat->init(); This triggers the init method of your cat on INIT of PW and it attaches all hooks of your cat page class as if they where placed in init.php; The same technique can be used for ready() in ready.php; That does load one instance of cat into memory though. That's a little overhead. IMHO it's worth the overhead, but I can only guess that the overhead is very small... Maybe one could also use loaded() for that, I don't know and I'd have to investigate on this. Maybe someone can try and share their findings ? -
This is something where PW is a little... special. The problem is that it decides wheter a page is viewable or not from the existance of /site/templates/yourtemplate. That means you don't have those files under control of your module. Copying the file on install is not ideal as well, because you end up getting a static copy that will not update on updates. You could of course copy your files also on every update, but that approach has 2 other problems: Development gets complicated because you need to copy back and forth your files while testing them. And second you might modify the template file in /site/templates because you (or someone else) thinks that this is the correct file and on the next update you lose your changes. Or you have the file under control of git and you get conflicts there... To solve all that problems I have introduced the includeViews() method in RockMigrations: https://github.com/BernhardBaumrock/RockMigrations/blob/636cf1eca8f8f54683551ddea08ebc576c160124/RockMigrations.module.php#L305-L339 It will create a file in /site/templates/foo.php and you can happily code in /site/modules/YourModule/views/foo.php <?php namespace ProcessWire; // DONT CHANGE THIS FILE // it is created automatically via RockMigrations include($config->paths->root.'site/modules/YourModule/views/foo.php');
-
Custom Classes for Page objects - The Discussion
bernhard replied to szabesz's topic in API & Templates
I don't understand what you mean by "frontend" page classes ?