sebibu Posted April 4 Share Posted April 4 Thanks to all three of you! Learned something new again. I'm on PHP8 and because the $page object should be existent on every page, this should be sufficient and works great: <body n:class="$page->category?->value"> ?? 1 Link to comment Share on other sites More sharing options...
bernhard Posted April 4 Author Share Posted April 4 Just now, sebibu said: Thanks to all three of you! Learned something new again. Me too, thx ? I have to get used to these new nullsafe operators ? Link to comment Share on other sites More sharing options...
sebibu Posted April 4 Share Posted April 4 Directly another question.? To save the editor the trouble of entering a dropdown field, I would like to determine the value of a dropdown field in the next (and probably only) pagetree-upper page having a template with template-id e.g. = 50. Is this also possible only with Latte or do I have to determine the value in PHP first?? Thx!? Link to comment Share on other sites More sharing options...
bernhard Posted April 4 Author Share Posted April 4 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. 1 Link to comment Share on other sites More sharing options...
MarkE Posted April 18 Share Posted April 18 I do love Latte, but one little thing is puzzling me at the moment: namespaces. I am using custom page classes for all my 'business logic' - e.g a method getEmailHash() in the custom page class called in the Latte script with $page->getEmailHash(). The class has the namespace ProcessWire. It seems that I always need to specify the namespace in the method - i.e. $page->ProcessWire\getEmailHash(). Is there a way of avoiding this? Link to comment Share on other sites More sharing options...
bernhard Posted April 18 Author Share Posted April 18 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 ? 1 Link to comment Share on other sites More sharing options...
MarkE Posted April 18 Share Posted April 18 (edited) 3 hours ago, bernhard said: If you have a look at the RockFrontend Site Profile you'll see that it should work without namespaces: It works for me too in a similar context - i.e. when calling it to output: i.e in {$page->foo()} - but not when called in a variable declaration - ie. {var $foo = $page->foo()} That's when I seem to need {var $foo = $page->ProcessWire\foo()}. Odd. EDIT - Correction: The issue occurs not with page classes but just with functions defined in init.php (which is in the ProcessWire namespace. Edited April 18 by MarkE Correction Link to comment Share on other sites More sharing options...
nurkka Posted July 25 Share Posted July 25 I am using latte (not with RockFrontend yet, but "standalone" - I can't integrate RockFrontend in my current project yet, but hopefully in the next one), and I noticed that if I make errors in the .latte-file, the latte engine outputs a 500 Server Error, although I wrapped the latte call in a try/catch-block. My code in ProcessWire template: templateContent = '{func($var)}'; // contains an undefined function call $params = []; try { $output = $latte->renderToString( $templateContent, $params ); } catch (\Exception $e) { wire()->log->save('latte_errors', $e->getMessage()); } When testing the same latte markup in the latte sandbox https://fiddle.nette.org/latte/#0b4eb6af74 , it displays an appropriate error message. So there must be a way to catch the error, but I can't find it. Or can this only be done with PHP-features (which I do not know yet), or has ProcessWire any features to catch the errors? Does anyone know how to do it? Link to comment Share on other sites More sharing options...
nurkka Posted July 25 Share Posted July 25 I found the solution – of course right after posting ? One simply has to wrap the latte markup into {try} ... {/try} {try} {func($var)} {/try} And if you want to log the errors, you can do the following: $loggingHandler = function (\Throwable $e, \Latte\Runtime\Template $template) { wire()->log->save('latte_errors', $e->getMessage()); }; $latte->setExceptionHandler($loggingHandler); 1 Link to comment Share on other sites More sharing options...
da² Posted July 25 Share Posted July 25 2 hours ago, nurkka said: try { $output = $latte->renderToString( $templateContent, $params ); } catch (\Exception $e) { wire()->log->save('latte_errors', $e->getMessage()); } Probably here you should catch Error too: catch (\Exception | \Error $e) I use similar code with Twig, rendering an error template if any error. class Twig { public static function render(string $name, array $parameters = []): void { if (NoticeManager::hasNotice()) $parameters['rfroNotices'] = NoticeManager::render(); $parameters['templatesUrl'] = wire()->config->urls->templates; $parameters['homePage'] = wire()->pages->get('/'); $parameters['buildVersion'] = BUILD_VERSION; $parameters['buildDate'] = BUILD_DATE; /** @var TemplateEngineFactory $twigEngine */ $twigEngine = modules('TemplateEngineFactory'); try { echo $twigEngine->render( $name, $parameters ); } catch (Exception|Error $e) { // Catching everything if (wire()->config->debug) // If debug, throw the error with stack trace throw new Error("{$e->getMessage()}\n{$e->getTraceAsString()}"); wire()->log->error($e); $parameters['errorPage'] = wire()->page->path; try { // Try to render my error template, that shows something nicer for users. echo $twigEngine->render('error', $parameters); } catch (Exception|Error) { // It may happen, rarely, that the error is located at a lower level in my Twig structure (inheritance...), // so I display a very basic template that uses no code and can't fail. echo $twigEngine->render('error-safe', $parameters); } } } } Link to comment Share on other sites More sharing options...
FireWire Posted September 17 Share Posted September 17 @bernhard Using latte causes all stack traces to disappear. I'm getting unhelpful messages and no exception logging. I've tried to add an exception handler using a RockFrontend hook, but no dice. Getting some single line messages that aren't useful. Using Latte's {trace} at the top of a file rendered this: Attempting to hook and manually throw a WireException doesn't work. The hook is firing, but Latte is not responding to the example I took from the documentation. Any experience with this? Link to comment Share on other sites More sharing options...
bernhard Posted September 18 Author Share Posted September 18 Same here, let's have a meeting! 1 Link to comment Share on other sites More sharing options...
bernhard Posted September 22 Author Share Posted September 22 Hey @FireWire Thx for the great meeting, I created a question in the Nette forum: https://forum.nette.org/en/36655-how-to-get-useful-debug-screens-for-latte-file-errors#p227620 1 Link to comment Share on other sites More sharing options...
FireWire Posted September 22 Share Posted September 22 @bernhard Well that's fantastic, I already forgot to do that since jumping back to work on my project 😵💫 many thanks! 1 Link to comment Share on other sites More sharing options...
bernhard Posted September 23 Author Share Posted September 23 Hey @FireWire please grab the latest version from the dev branch 😎😍 Note that you even have tabs for latte/php to show both the latte file and the compiled php file!! I got so used to these unhelpful error messages on a white screen that I didn't even think of looking into it. Thx a lot! This improves the dev experience a lot! 2 1 Link to comment Share on other sites More sharing options...
FireWire Posted September 23 Share Posted September 23 @bernhard I've never been so excited to see errors in my code! Thank you! 2 Link to comment Share on other sites More sharing options...
palacios000 Posted September 30 Share Posted September 30 I am so grateful to @bernhard and @FireWire for all the excellent tips and tutorials on how to use better tools to code better website (Latte + PageClasses). Thanks a lot guys for you hard job, I've learned a lot from you. After this little intro of gratitude, I have a question on how you would use the templates available in Latte in conjunction with PW templates. I am referring to templates or block in latte, here https://latte.nette.org/en/template-inheritance#toc-definitions so for example I can crate a button tag inside a .latte file, like "components.latte" and import these bits of code, or "function" inside other .latte files. All this is very nice and useful. But now my question is: is it possible to import a latte block inside a normal processwire.php template? In other words: if I'm in // templates/blog-post.php <?= $rockfrontend->render('components/blog.latte', [// How can I fetch the block tag?]) ?> // templates/components/blog.latte {define tagLabel} <span class="... font-mono">{$tag}</span> {/define} Thanks 1 Link to comment Share on other sites More sharing options...
bernhard Posted September 30 Author Share Posted September 30 13 minutes ago, palacios000 said: I am so grateful to @bernhard and @FireWire for all the excellent tips and tutorials on how to use better tools to code better website (Latte + PageClasses). Thanks a lot guys for you hard job, I've learned a lot from you. Great to hear that 🙂 16 minutes ago, palacios000 said: But now my question is: is it possible to import a latte block inside a normal processwire.php template? Maybe, but I don't think so. Why would one want to do that? Link to comment Share on other sites More sharing options...
palacios000 Posted September 30 Share Posted September 30 1 hour ago, bernhard said: Maybe, but I don't think so. Why would one want to do that? I'm using {define xxxx} to define pieces of code I'm using in different parts of .latte files, like buttons, svgs, modals, lists and so on. But it's not possible to import for example a svg icon I defined already in latte directly in a processwire template file. There are solutions to import these bits of code, but they're not as elegant as ideally $rockfrontend->render('components-file.latte', ['component-name' => ['variablename' => 'variablevalue']]; Link to comment Share on other sites More sharing options...
dotnetic Posted October 1 Share Posted October 1 19 hours ago, palacios000 said: I'm using {define xxxx} to define pieces of code I'm using in different parts of .latte files, like buttons, svgs, modals, lists and so on Why don't you use include or import? I managed to do all component/partial stuff with `include` in a project, which will be the base now for future projects. For example I have a heading.latte component and can include it and submit parameters to it like so: {include 'partials/heading.latte', title: $page->title, class: 'md:text-7xl text-primary break-words'} and my heading.latte looks like this {var $headingLevel = $headingLevel ?? 'h1'} {* Default to h1 if not defined *} <h1 n:tag="$headingLevel" class="font-bold font-heading leading-tight uppercase {isset($class) ? $class : 'text-7xl'}">{$title|noescape}</h1> 2 Link to comment Share on other sites More sharing options...
dotnetic Posted October 1 Share Posted October 1 21 hours ago, bernhard said: 21 hours ago, palacios000 said: But now my question is: is it possible to import a latte block inside a normal processwire.php template? Didn't read that correctly. Each variable you define in your .php file should be available as a variable in latte files so you could use it there. Maybe I don't understand your question completely, but in a PHP file you can just do echo $rockfrontend->render("partials/card.latte", $child); like you described here 19 hours ago, palacios000 said: There are solutions to import these bits of code, but they're not as elegant as ideally $rockfrontend->render('components-file.latte', ['component-name' => ['variablename' => 'variablevalue']]; 2 Link to comment Share on other sites More sharing options...
bernhard Posted October 1 Author Share Posted October 1 @palacios000 Please also have a look at the discussion here: https://processwire.com/talk/topic/30449-questions-and-syntax-latte-template-engine-by-nette/?do=findComment&comment=244743 1 Link to comment Share on other sites More sharing options...
bernhard Posted Sunday at 10:03 AM Author Share Posted Sunday at 10:03 AM I've mentioned several times that one reason why I love latte is that LATTE == PHP (almost) This tool shows what I mean: https://php2latte.nette.org/ @FireWire Link to comment Share on other sites More sharing options...
Recommended Posts