Jump to content

bernhard

Members
  • Posts

    5,717
  • Joined

  • Last visited

  • Days Won

    270

Everything posted by bernhard

  1. I'm doing exactly that in RockFrontend: https://github.com/baumrock/RockFrontend/blob/e2b0beb70427c39ade99dc36547a370dd091f59f/RockFrontend.module.php#L2338
  2. hit the wrong button - please delete this post ๐Ÿ™‚
  3. Hi @Christophe Unfortunately we don't have Code Intellisense or autocomplete in latte files at the moment ๐Ÿ˜ž See https://github.com/smuuf/vscode-latte-lang/issues/5 You are adding the method "listchildren()" to your ParentPagePage, nowhere else. That means you can all this method only on pages that have the template "parent-page". Why should it do that? You are calling a method of an object. If that does not exist it is expected to throw an error. You CAN do what you describe though. Sometimes it is useful and I'm doing that as well. You could add that method to your DefaultPage.php and there return an empty sting. That would make $page->listchildren() return "" by default, which means it does not throw an error. For some page types you can then implement a different logic: DefaultPage.php --> listchildren() { return ""; } FooPage.php extends DefaultPage --> listchildren() { return "foo!"; } BarPage.php extends DefaultPage --> listchildren() { return "BAR"; } // in any template echo $page->listchildren(); That it totally up to you. Same with regular ProcessWire templates. It's up to us devs how we organise things and everybody does it differently. I can only say what I came up with and what works great for all kings of projects (from very simple to very complex ones): layout.latte for main markup /site/templates/sections/... for all sections /site/templates/partials/... for all partials Details: layout.latte --> holds the html markup skeleton of the page, eg: <html> <head>...</head> <body> <header>...</header> <main>...</main> <footer>...</footer> </body> </html> Then all my template files are usually empty (like home.php, basic-page.php, foo.php, bar.php). Next, I divide my design into sections. A section is a portion of the page that goes from the very left to the very right and has an undefined height/content. You can then add those sections to your main markup file like this: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {include "sections/content.latte"} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> This is often all I need, because I build all the available sections in RockPageBuilder and then I can simply add them to the pages as I need them. But it works without RockPageBuilder as well. You then just need to code all your page layouts depending on the page template. If all those pages share the same breadcrumbs and content-footer it could look like this: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {if $page->template == 'foo'} {include "sections/content-foo.latte"} {elseif $page->template == 'bar'} {include "sections/content-bar.latte"} {else} {include "sections/content.latte"} {/if} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> You could also use a dynamic approach: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {include "content/" . $page->template . ".latte"} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> It's just regular PHP inside the latte tags, so you could also do is_file() checks etc: <html> <head>...</head> <body> <header> {include "sections/topbar.latte"} {include "sections/navbar.latte"} </header> <main> {include "sections/breadcrumbs.latte"} {var $file = "content/" . $page->template . ".latte"} {if is_file($file)}{include $file}{/if} {include "sections/content-footer.latte"} </main> <footer> {include "sections/footer.latte"} </footer> </body> </html> Obviously you'd need to create those files. Here I'm placing them into a new folder called "content", which would be /site/templates/content/foo.latte for example. Next, partials: If you have repeating markup inside your sections you can outsource them into the partials folder. For example let's say you want to show a blog overview page that shows all single blog items as cards. You'd have a section like "blog-overview.latte" like this: // blog-overview.latte <div uk-grid> <div n:foreach="$page->children() as $item"> <div class="uk-card"> <h3>{$item->title}</h3> <p>{$item->teaser()}</p> </div> </div> </div> This example is very simple and if you only use your cards here, then it's easier to leave them here. If you are using the exact same cards on two or three places then you can create partials for them: // blog-overview.latte <div uk-grid> {foreach $page->children() as $item} {include "partials/card.latte", item: $item} {/foreach} </div> // /site/templates/partials/card.latte <div> <div class="uk-card"> <h3>{$item->title}</h3> <p>{$item->teaser()}</p> </div> </div>
  4. If you have a look at the RockFrontend Site Profile you'll see that it should work without namespaces: https://github.com/baumrock/site-rockfrontend/blob/3c6dcc3d6a73432f4a98f5d47bec9858fa1fbd23/templates/sections/footer.latte#L17 https://github.com/baumrock/site-rockfrontend/blob/3c6dcc3d6a73432f4a98f5d47bec9858fa1fbd23/classes/HomePage.php#L27 I have no idea why the syntax you mention would work. I've never seen adding a namespace on the method call of an object ๐Ÿ˜ฎ
  5. Thx @Christophe that's some good questions ๐Ÿ™‚ I've updated the profile to hopefully answer all of them: https://github.com/baumrock/site-rockfrontend/commit/be55adae28ffe6a7aac83944284820f17afdaabf You don't need to use tailwind. If you don't want to use it just remove the _tailwind.css file. If you find anything happening that should not be let me know and I'll fix it.
  6. Someone could create a topic in the forum, maybe in the tutorials section, eg "how to fix request appears to be forged". And we could then simply add a link to that topic to the error message.
  7. Have you tried on another browser or in the incognito mode? Maybe you just need to clear your cookies.
  8. Hi @HarryWilliam and welcome to the forum! E-Commerce is a huge topic and there are many ways how to do it - unfortunately or luckily ... Option 1: Payment Buttons or Links Very simple solutions are payment buttons that Platforms like Paypal offer. You can see an example here: https://www.boukal.at/work/catalogues/catalogue-do-you-also-have-pretty-motifs/ Another option would be payment links that payment providers like stripe or mollie offer: https://www.mollie.com/gb/products/payment-links Pro: Very easy to implement Con: You have to manage different buttons/links for different products on your own, place them in your markup (for example with a textformatter), keep them up do date and you have very limited possibilities for customisations (like different options etc). Option 2: SaaS Shop integration The next option would be to add one of the SaaS solutions to your PW site. One option would be to use Snipcart, which is very simple to add to your site, at least in theory: https://snipcart.com/blog/processwire-ecommerce-tutorial Pro: Easy setup, working shop out of the box, they maintain and develop the product continuously and long term (hopefully) Con: You usually pay for it per purchase and/or you have a monthly fee. Snipcart for example costs at least 20$ per month if your sales are < 1000$. That's 240$ each year. https://snipcart.com/pricing Con: You need to add products to your SaaS shop. That means you can either not manage products directly from within your ProcessWire backend or you need to develop a bridge that keeps products in sync. Con: Using a SaaS Shop means you are locked to the features that this shop provides. In PW we have this module, but I'm not sure whether it's still maintained or will see any updates in the near future. Option 3: A custom PW shop This is maybe the most advanced solution. The benefits are that you get a fully integrated solution. You can manage all your products, all your users, all your orders etc. directly from within your PW backend. You can add hooks wherever you want and you can customise everything to make it work 100% the way you or your client wants. Imagination and your skills are the limit. The con is that it will likely be a more complex setup, as you need to understand the basic workflows of E-Commerce and you need to setup everything the way you want. As far as I know we only have Padloper 2 by @kongondo at the moment. I don't know the price, though, because the shop is down at the moment. I'm developing RockCommerce at the moment and it will hopefully be released during this year. The basic version is already done and you can see it in action on my website baumrock.com where I use it to sell my commercial modules, for example RockForms. As you can see on my website it can already be used to sell single products. It comes with a checkout (live example) but it has no cart functionality at the moment. But it already has a nice Dashboard with filters and charts, at least ๐Ÿ™‚ Also, it can already create fully automated and 100% customisable invoices directly from within PW/PHP (using RockPdf) - which is something that not all shopping carts do for you, keep that in mind when evaluating those products! Thanks to the integration into the PW system it can send 100% custom emails to your customers, where you can make sure that you comply to your local legislation (for example in Austria we need to attach terms of service to that email): In this example it's a nice looking mail because I use RockMails, which is another module in the pipeline ๐Ÿ™‚ But as it is 100% ProcessWire you can simply send an email with some lines of code as well: $m = new WireMail(); $m->from('office@your-company.com'); $m->to('your@client.at'); $m->subject('Thank you for your oder!'); $m->body('Congrats, you are now a ProcessWire hero!'); $m->send(); So while it is not yet 100% it can already be already a great option! If you want to get notified about the release you can subscribe to my monthly developer newsletter: https://www.baumrock.com/en/rock-monthly/ I'm quite sure there are 100 more options, but I tried to give an overview ๐Ÿ™‚
  9. Thx @incognito.ms it's fixed in v5.4.2 ๐Ÿ™‚ https://www.baumrock.com/en/releases/rockpagebuilder/
  10. I'm not sure I understand ... For one request you can store your variable wherever you want (and where it is allowed), for example you can set $config->foo = "Foo!" somewhere and later you can access that runtime property. On the next request $config->foo will be null again unless you set it somewhere. Until PHP8.2 it was possible to use $wire for that as well, eg $wire->foo = "Foo!", but since PHP8.2 setting dynamic properties is deprecated.
  11. Hi @netcarver thx for the suggestion. Could you please explain why that would be useful and what that has to do with RockPageBuilder? I'm afraid I don't understand ๐Ÿ™‚ FYI @ everybody else: Next release will have improved debugging for Ajax endpoints thx to a request by @netcarver ๐Ÿ™‚๐Ÿ˜ https://www.baumrock.com/en/processwire/modules/rockfrontend/docs/ajax/
  12. $session->myVariable = "MyValue"; // or wire()->session->myVariable = "MyValue"; It will be available for the session of the user and will only be available/editable by the server side.
  13. Thx @adrian that's great and it works ๐Ÿ˜Ž๐Ÿ˜๐Ÿš€ @netcarver Check out the latest dev version! https://github.com/baumrock/RockFrontend/commit/876d421376dfbc3e026610d7dc06cc3362937602
  14. Hey @adrian Today @netcarver requested to make RockFrontend's livereload work on tracy error pages - which is something that has been annoying for myself for a long time: https://github.com/baumrock/RockFrontend/issues/25 The problem is I've really tried hard to do so, but I can't find a way to modify the markup of the rendered page ๐Ÿ˜ž LiveReload in RockFrontend works simply by having this markup on the page: <script> var LiveReloadUrl = '{$this->wire->config->urls->root}'; var LiveReloadSecret = '$secret'; console.log('Loading LiveReload'); </script> <script src='$src'></script> Any ideas how we can get this working? I even tried using Debugger::$customBodyStr = "TEST"; and similar, but that doesn't seem to do anything at all, though I see you are using it in your module? I'm totally lost here and hope you have a simple solution to finally get rid of these annoying manual reloads on error pages ๐Ÿ™‚ Thx in advance! PS: This is actually the same request as this one just with different wording: https://processwire.com/talk/topic/29555-why-is-it-so-complicated-to-add-custom-panels/ I mentioned in that post that I got it working, but I can't find the working version any more of I just thought it was working but it actually didn't... PPS: I'm talking about these pages:
  15. Hi @incognito.ms thx for using RockPageBuilder ๐Ÿ™‚ This is just a shortcut for this: $page->rockpagebuilder_blocks->render(); That means it will render the default RockPageBuilder field that you get when installing RPB. If you add additional custom RPB fields (lets say "foo" and "bar"), you can simply render them like this: $page->foo->render() $page->bar->render() So you could have a 3 column layout like this: <div id="left"> <?= $page->foo->render() ?> </div> <div id="main"> <?= $rockpagebuilder->render() ?> </div> <div id="right"> <?= $page->bar->render() ?> </div> https://www.baumrock.com/en/processwire/modules/rockpagebuilder/docs/blocks/#rendering-blocks Does that help?
  16. RockPageBuilder has the concept of "Widgets". You can turn every "Block" (similar to a repeater matrix element) into a widget with one click. Then on any other page you can add a widget block and select the original item to be displayed. This is handy for situations where you want to reuse content elements across your site, but want to manage the content at one central place. An example could be a "contact us" element or a "donate now" element where you'd maybe want to display that element on hundreds of pages but want to change the phone number or bank account only once. A RockPageBuilder block can be text but also just an image field. So having an image block, uploading an image and then turning it into a widget would make the use case that you describe possible. As always this comes with a downside. It would then not be possible to show different versions of that block. All would be 100% identical. You could build the same concept on your own with RepeaterMatrix as well. After all it's just a page reference field and an some additional logic to not render the reference directly but render the referenced source. Actually that can get quite tricky, but that's another story ๐Ÿ˜„ So as always in ProcessWire it's up to you how you do what you need and it depends on the exact use case what is the best solution. There is no one-size-fits-all solution for what you describe and I think as @wbmnfktr mentioned uploading images multiple times might be the most native solution and is often really not bad and comes with other benefits.
  17. Thx, I've updated the first post and the thread title!
  18. Hi @netcarver thx, this feature has been moved to RockSettings. Could you please let me know where you found the outdated info, so I can remove it?
  19. Hi @netcarver thx for helping to improve RockFrontend ๐Ÿ™‚ Done in the latest commit on the dev branch ๐Ÿ™‚ This pops up as soon as you add {alfred(...)} somewhere in your markup and the module is not installed. I've also added a note in the docs.
  20. Great to hear that ๐Ÿ™‚ This is interesting. I've never really had the need for that - maybe because RockPageBuilder is doing that for me and I don't need it at all on frontend editing - but I'm wondering if a module setting could make sense. I could think of a checkbox "trigger frontend reload on page save", or maybe a config setting. A config setting could have a page selector that checks if the saved page matches the selector and only reloads if it's true. But I'm also wondering how that feature would be used and by whom. Would it be a developer thing? Or could it maybe also be useful for regular site editors? So far Livereload was really only intended for local development, but the technique has been quite reliable and should work with any infrastructure as SSE + JS is available everywhere...
  21. I don't understand the question and it's probably a bit offtopic for a "why I love latte" thread ๐Ÿ˜‰ But you can use regular PW API inside Latte. That's why latte is so great, it parses templates to regular PHP so you can do anything that PHP can do. Though this should be used with caution, as you should also try to keep your latte files clean, so whenever you need more complex logic use custom page classes and put the logic there in a custom method, so you can do {$page->my_custom_dropdown_value()} for example. If it's simple you can do {$page->parent->dropdown_value} instead.
  22. Thx @Entil`zha I've added a warning to the docs which will be visible soon on my website. Could you please change the topic title to [solved] ... ? Thx and have fun using RockPageBuilder ๐Ÿ™‚
  23. Me too, thx ๐Ÿ˜„ I have to get used to these new nullsafe operators ๐Ÿ™‚
  24. Hi @Entil`zha, sorry for the trouble! Do you have frontend editing permission? It looks like you don't, so ProcessWire will not load jQuery and all the suff necessary for the modal to pop up.
ร—
ร—
  • Create New...