-
Posts
6,312 -
Joined
-
Last visited
-
Days Won
318
Everything posted by bernhard
-
PolishWire - very nice ??
- 32 replies
-
- 3
-
- pl-PL
- translation
-
(and 2 more)
Tagged with:
-
DOMiD Labs – Microsite for a museum-related project
bernhard replied to schwarzdesign's topic in Showcase
Sure ? <html> <head> <?php echo $rockfrontend->scripts('head') ->add('/wire/modules/AdminTheme/AdminThemeUikit/uikit/dist/js/uikit.min.js') ->add('//unpkg.com/alpinejs', 'defer') ->addIf('/path/to/debug.js', $config->debug) ->render(); echo $rockfrontend->styles('head') ->add('/wire/modules/AdminTheme/AdminThemeUikit/uikit/src/less/uikit.theme.less') // add all styles (CSS/LESS) inside /site/template/sections ->addAll('sections') ->render(); ?> </head> <body> <?= $rockfrontend->render("sections/header.latte") ?> <?= $rockfrontend->render("sections/main.latte") ?> <?= $rockfrontend->render("sections/footer.latte") ?> </body> </html> I've used that module (RockFrontend) for several projects now and I'll release it soon. If you or anybody else wants to try it out and give me some feedback write me a PM! -
Hey @Jan Romero thx for that post ? I've never really understood how such things work and when to use what syntax. When to send a body, when json etc.; Some 3rd party API docs use php://input others use $_GET... Do you have some pointers to make me understand better what's going on and where to use what? Up until now I've managed to get everything working, but sometimes it was just try and error. For example how did you know to use application/x-www... and why are you using URLSearchParams as body? Thank you!
-
Hi @Erica welcome to the forum! you should definitely care about those two. Where are you hosting your site? Is it a very cheap/limited shared host? Maybe one of these posts are helpful? I guess your host does not support all necessary functions and echo's out some error/warning before it comes to session_name and ini_set. That output could then produce the headers already sent warning... That one should not be a big problem, but it should also be easy to fix:
-
RockMigrations1 - Easy migrations from dev/staging to live server
bernhard replied to bernhard's topic in Modules/Plugins
can you try to create the field manually and then copy and paste the field code from the first tab? -
As I've never used redis I had to do some research what it is and what it does... Here's a good video that gives you a quick overview: Would be interesting to hear why/where/when one could use this module and what benefit one would get vs. using WireCache ?
-
What do you mean? Is this how it should be? Or is this what you think has to be? If you want it to have a dummy title, @Studio Lambelet has shown the solution. If you think it must be like this: No, you can leave the title empty and the user has to fill the field on the first edit. You can even do this with my technique. Simply add those fields to the redirect url: $event->session->redirect($p->editUrl()."?fields=title,your_upload_field"); <?php $wire->addHookAfter("/createpage/{parentID}", function($event) use($parent) { // access control $parent = $event->pages->get((int)$event->arguments('parentID')); if(!$parent->editable()) return; // create new page $p = new Page(); $p->parent = $parent; $p->template = 'your-child-template'; if($parent->template == 'your-parent-a') $p->title = 'Dummy text for parent A'; elseif($parent->template == 'your-parent-b') $p->title = 'Dummy text for parent B'; $p->save(); // redirect to page editor $event->session->redirect($p->editUrl()."?fields=title,your_upload_field"); });
-
You could also add a simple URL hook that creates the page and then redirects to its page editor: <?php // site/ready.php // get the parent page $parent = $page->get("/your/parent/page"); // add hook if the parent is editable // adjust access control to your needs if($parent->editable()) { // add hook to create page $wire->addHookAfter("/createpage", function($event) use($parent) { $p = new Page(); $p->parent = $parent; $p->template = 'your-child-template'; $p->save(); $event->session->redirect($p->editUrl()); }); } And on the frontend: <a href="/createpage">Create new Page</a>
-
RockMigrations1 - Easy migrations from dev/staging to live server
bernhard replied to bernhard's topic in Modules/Plugins
Hey @BlindPenguin I've added support for translatable options fields in RockMigrations. It was quite tricky but should work now. I'd be happy if you could do some testing and tell me if everything works as expected. <?php $rm->createField("tmp_opt", "options", [ 'label' => 'testing options field migration', 'options' => [ 1 => 'one|Label for Option one', 2 => 'two|Label for Option two', 3 => 'three|Label for Option three', ], 'optionLabels' => [ 'german' => [ 'Beschriftung für Option eins', 'Beschriftung für Option zwei', 'Beschriftung für Option drei', ], ], ]); -
DOMiD Labs – Microsite for a museum-related project
bernhard replied to schwarzdesign's topic in Showcase
Hi @MoritzLost that's interesting! I've recently fallen in love with latte and there I have the same issue. I didn't think of that until know as I've not been using it on a multilang site yet. Your approach with the table field is interesting, especially the fact that it creates rows automatically from code and populates a default value. Though I'm not sure if I really like that approach or not. I think if the default value is changed by the client and a developer looks into the code and tries to change the wording there this might lead to unexpected results as that change would not have any effect since the new value will not be written to the translations? On the other hand having the msgid has the benefit that if you change the wording in the initial language you don't lose the relation to the translation which would be the case in PW's internal system... There's always a pro and con ? Anyway.. it's not really a big issue for me since I'm always using custom page classes and I can easily add a method there that returns a translatable label, eg $page->buttonLabel() -
Page[s]::trash(template=foo) vs Page[s](template=foo)::trash
bernhard replied to DrQuincy's topic in API & Templates
Glad it helped. Happy hooking - it's a lot more fun if you understand what's going on ? -
Page[s]::trash(template=foo) vs Page[s](template=foo)::trash
bernhard replied to DrQuincy's topic in API & Templates
The part in the braces tells PW to apply a selector. The position where you add this selector tells PW where to apply the selector. And that "WHERE" depends on the hook and it's structure. In your example you hook Pages::saveReady, which looks like this: That means the object is the "Pages" class and the method is the "saveReady" function. As you can see above on line 2287 that method takes one argument: The "Page" object that is being saved. That means: In the HookEvent $event, the object will be the "Pages" class. Try that with tracy: bd($event->object) In the HookEvent, you'll have one argument and that will be the "Page" object being saved. Try bd($event->arguments(0)) You could also use $event->arguments('page') because the first argument of saveReady() is $page. If it were $foo you could do $event->arguments('foo') If you apply a condition like Pages::saveReady(template=foo) that means that you apply the selector "template=foo" to the first argument of the saveReady method which is the "Page" object (on line 2287) that is referenced as $page. What you are doing when using Pages(template=foo)::saveReady is that you apply the selector "template=foo" to the "Pages" class, but the Pages class is not a single Page object and therefore has no template! Hope that makes sense ? -
Page[s]::trash(template=foo) vs Page[s](template=foo)::trash
bernhard replied to DrQuincy's topic in API & Templates
That are good and important questions if you want to understand hooks ? Pages::trash() is a hook that you attach to the method "trash" of the "Pages" class (that's the file /wire/core/Pages.php). In that file you'll find the method ___trash() which indicates that it is hookable. You'll also find helpful comments on top of that method in the code. The same concept applies to Page::trash() where the hook is attached to the method trash() of the "Page" class (which is the file /wire/core/Page.php) and represents a single page object. See my link in the signature "afraid of hooks" - does that answer your question? -
Hey @Pete thx for sharing. Have you seen my new language module? For me it sounds like it could help you so I'd be happy to hear your thoughts...
-
You don't even need any external libraries to realize that, because ProcessWire's default admin theme uses UIkit and UIkit has the sortable component that does exactly what you need: https://getuikit.com/docs/sortable#group I thought of building such a module the other day... I'll send you a PM...
-
In general I'd say no, that's not a bad practice. Pages are built for storing data and they are built to scale. And they are built to work with all the nice things we have in PW world that are a pain to build with plain SQL database structures (like children/siblings/parent references and page reference fields in general).
-
Data is fetched via cron every night and then PW pages are created so that the client can enrich those pages with data that is not part of the API but is helpful on the website (eg a PDF sheet for the car or the point of contact): API-Fields are read-only. If a car is created by the cron and the point of contact is empty, the client gets a link to directly edit this page and select the POC ? If cars are sold, the cron automatically trashes those pages on the website. Ah... I forgot a nice detail! They have a custom branded PDF viewer:
-
RockMigrations1 - Easy migrations from dev/staging to live server
bernhard replied to bernhard's topic in Modules/Plugins
No, if you just do a createField it will just update the field's label and it will not touch its values. You could do something like this: <?php // site/migrate.php /** @var RockMigrations $rm */ $rm = $this->wire->modules->get('RockMigrations'); $rm->createField("yoursettingsfield", "options", [ 'label' => 'Your field label', 'tags' => 'MyWebsite', // values are populated manually on the live system ]); Push that to the live system, populate values, pull DB to dev. RockMigrations works in a way that it only sets properties that are listed in the migration config. That means if you REMOVE properties, it will most likely not remove those values from the DB. That's why the template migrations have a special property "fields-" additional to "fields": <?php ... $rm->setTemplateData('yourtpl', [ 'fields' => ['foo', 'bar', 'baz'], ]); // this will NOT remove field baz from template yourtpl $rm->setTemplateData('yourtpl', [ 'fields' => ['foo', 'bar'], ]); // this WILL remove field baz from template yourtpl $rm->setTemplateData('yourtpl', [ 'fields-' => ['foo', 'bar'], ]); // but I prefer doing such things like this as it's more verbose and clearer $rm->setTemplateData('yourtpl', [ 'fields' => ['foo', 'bar'], ]); $rm->removeFieldFromTemplate('baz', 'yourtpl'); Of course you can also do conditional migrations like this one where I had to migrate from this structure /rockmails /rockmails/mail1 /rockmails/mail2 ... to this one: /rockmails /rockmails/templates /rockmails/templates/tpl1 /rockmails/templates/tpl2 ... /rockmails/mails /rockmails/mails/mail1 /rockmails/mails/mail2 ... The migration creates the new root data page (/rockmails - tpl=rockmails_root), then it creates the mails and mail template and fields, then, if the old mailspage exists (/rockails - tpl=rockmails), it moves the old mailspage from PW root to the new datapage (/rockmails/mails) and it renames it from rockmails to mails (as it lives in /rockmails/mails now and /rockmails/rockmails would be weird) and when done we call the root->migrate() again to revert the setTemplateData from line 200 --- If you find something out regarding to the options field please let me know. I'm happy to merge PRs ? -
https://www.autohaus-bendel.at/ Highlights/Features: New Logo and matching Backend using module AdminStyleRock Very good google- and performance-ratings thx to UIkit and ProCache Flexible content pages (using private module RockMatrix) Cars are fetched automatically from an austrian cardealer API and converted into ProcessWire pages with a custom filter page: https://www.autohaus-bendel.at/fahrzeuge/ Forms with honeypots and live validation (using private module RockForms based on nette forms) Web-Coach The client gets automated reminders if he does not add new content to the website. Thx @wbmnfktr Bendel Web Coach The last news entry was created 21 days ago. There must be something new that will interest your clients ;) > To the website > Create news entry Animated page transitions using barba.js Migrations and deployment using RockMigrations. Debugging using TracyDebugger. ?
- 10 replies
-
- 17
-
DOMiD Labs – Microsite for a museum-related project
bernhard replied to schwarzdesign's topic in Showcase
Beautiful site as always ? Do you have some details on that one? -
RockMigrations1 - Easy migrations from dev/staging to live server
bernhard replied to bernhard's topic in Modules/Plugins
Hi @BlindPenguin glad to hear that ? It does not really matter as the migrate() method uses createField() and setFieldData() etc behind the scenes. What might make a difference is that migrate() makes sure that all fields and all templates exist before it sets their data. That means you can reference fields and templates from within that migrate call and they can even reference each other without creating an infinite loop! It depends. Of course you can. RockMigrations does not care. At the moment RockMigrations can't do that. What's interesting is that even the core field export does not export translations of an options field. So I'm not sure if that is possible at all at the moment. For a real world use (aka quickfix) you could just create the field via RockMigrations, push the migration to the live system (which will create the field), then translate your options and then pull the DB changes to your dev environment (manually). If you need a 100% automated solution you could use pages and a page field to select the option (that's the way we did it before the options field even existed). Does that help?