Leaderboard
Popular Content
Showing content with the highest reputation on 10/01/2024 in all areas
-
Hey ProcessWire community! I'm excited to introduce RockCalendar, a new calendar module that brings powerful event management capabilities to your ProcessWire sites. Key features include: Full calendar view in the ProcessWire admin Easy event creation and management Drag-and-drop event scheduling Recurring events (SSE powered, needs RockGrid) Seamless integration with ProcessWire pages and fields I've created a detailed video walkthrough showcasing RockCalendar's features and installation process: Check it out and let me know what you think! I'm here to answer any questions you might have about RockCalendar. Download & Docs: https://www.baumrock.com/en/processwire/modules/rockcalendar/ Happy coding!4 points
-
3 points
-
@kongondo I recently bought my son a used M2 Air, which was not too expensive and is in pretty good condition and a lot faster than my getting-old 2019 Intel MacBook Pro. Have you ever considered the UNIX experience without all the hassle? Just my two pence... Personally, I am waiting for the M4 Mac mini: https://buyersguide.macrumors.com/#Mac_Mini And sorry for being somewhat off-topic, macOS is not Linux, but it feels similar in many ways and is a lot easier to tame.2 points
-
I've just released RockCalendar with a hopefully helpful intro video. I want to thank @monollonom and @BrendonKoz for all the input you gave here. If you want a free single site license for testing (and eventually reporting bugs π ) please write me a PM.2 points
-
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 here2 points
-
I really love LATTE (Template Engine by Nette) but here and there I still have problems with the syntax. I'm using RockPageBuilder by @bernhard and try to output the html for this module: https://processwire.com/modules/fieldtype-leaflet-map-marker/ In PHP this would be: <?php echo $map->render($page, 'YOUR MARKER FIELD'); ?> And in LATTE? π I tried this variants and more: {$map->render($page, 'map')} {$map->render($page, 'block->map')} {$map->render($page, $block->map)} Getting: Call to a member function render() on null in block #1158 (rockpagebuilderblock-map) Maybe this topic can be a collection point for smaller Latte syntax questions.1 point
-
My Linux adventure has come to a swift end! I don't know what it is with me and Linux! There's always something. I spent most of the weekend battling a 'Unable to access location Error mounting /dev/sdb1 at /media/username' error! Not sure if it is an Ubuntu 24.04 issue but it seemed to be related to Visual Studio Code. The other week, the system would hang and I would have to hard reboot it. I thought it was my updates (this was before Omakub round 2). This weekend, I couldn't access one of my drives. The system froze. I fixed it. It happened again, and again, and again. SO et al. threw up all sorts of reasons, ranging from opening a folder with a .git folder in VSCode (??!!!) to other myriad possibilities. In the end I gave up (tick tock, tick, tock) and back to Windows we are! This time I actually felt sad π. I really liked Omakub. I also really enjoyed developing in a Linux machine. All is not lost though! I really like DDEV and they suggested, if on Windows, why not give WSL a chance. So, I did and boy!π. The thing just works! WSL2 + VSCode WSL Extension + DDEV just rocks! Installing stuff with winget also makes me feel all nerdy and Linuxy! π€. All is well π.. Better get back to reality though; I mean, work's only delayed by a couple of months, sigh. ..π€«.1 point
-
That's a great idea, but I think it would be better placed in a dedicated thread π Haha, well... it had to have some name π Yeah that would be the concerns that I had... Let's wait a little for more feedback π Totally understandable. I've also thought about creating something like this totally open source, but this is not possible for several reasons. Thx for your input!1 point
-
I see... Makes sense. I just followed the instructions in the tailwind docs... This is all new to me. π1 point
-
I love it that you called it βRockCareβ, to rockfinity and beyond... π In all seriousness, IMHO I donβt think this is something worth developing for others to buy (nor as a free module). Everyone has their own set of requirements (and their own way of doing) and this would make it a very hard time on you to figure out a βone-size-fits-allβ solution. I would advise to save yourself this burden, knowing youβre already going on big endeavours with other modules (e.g. RockCommerce). However this is just me and you could definitely beta-test it with select users to see if they could adapt to your way of doing and in this case foresee a potential public release. In my particular case though, this is something I wanted to tackle for a while now, also with ProcessWire. But I know for sure that I would want to do it all by myself, as a way to experiment (and have fun like you said) but also to make sure itβs perfectly tailored for my usage. What would be nice though is having a thread (this one?) so people can share what they put in place (PW-based that is) to help them managing this aspect of their work. Not going as far as sharing a whole site-invoice profile, but something along the lines of the associated blog post π1 point
-
@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=2447431 point
-
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>1 point
-
Well, I did some more testing and found that the exec function is actually available. I added this code to my page: <?php $function_name = "exec"; if ( function_exists($function_name) ) { echo "$function_name is enabled"; } else { echo "$function_name is not enabled"; } ?> As you can see on the screenshot, the result is positive... Don't get me wrong: I am not trying to ask for your help in my specific case. I believe in your product and I want to help make it usable for as many people as possible!1 point
-
1 point
-
My internet persona was born in these sort of forums when I was a teen, and I think it'll die on this hill! I REALLY appreciate having a forum for ProcessWire! Wouldn't exaggerate to say it's one of the reasons I've found myself so comfortable in the community.1 point
-
I came back to the thread to share some experiences and they are very similar to what @sebibu is running into. Latte introduces a lot of challenges with scoping and augments how you interact with ProcessWire. This is most pronounced for me when working with different inheritance types provided by Latte. When working with `include` there is no scope so anything that is added using {include 'file_name.latte'} will have access to the parent variables. This includes $page and $wire. Unfortunately the limitations with Latte is that you can't define blocks inside them, they only take parameters in the {include} statement. This is fine for most applications, but if you have a reusable component, such as a modal where the markup for the modal stays the same but complex contents should be contained in that markup, it would best be served by using {embed} because you can define something like {block content}{/block}. So while variables are available in primary template files, using all available features in Latte starts to lock out ProcessWire. Files included using {embed} are isolated in scope, so anything you want/need available in that file must be passed as parameters or added as rendered content within a {block}stuff here{/block}. This can get laborious for developers that are used to having ProcessWire's global variables and functions available anywhere. From my experience, there are two options. {embed 'file_to_embed.latte', page: $page, wire: $wire, foo: 'foo', bar: 'bar } {block content}waddap{/block} {/embed} You can choose to add parameters to an {embed} file that provide ProcessWire's API. I'm not entirely a fan of this because it feels laborious and if we're just going to have to pass the ProcessWire API into Latte components to overcome the limited scope, then it's just an extra step that ends up adding additional parameters passed to components all over your templates very repetitiously. I'm also used to working around the concept of only providing objects the specific data they are supposed to work with like best practices for dependency injection containers. The second option is to add custom functions to Latte using a hook at runtime. This method allows you to declare functions that will be available globally within all types of Latte reusability methods. Here's an example of a hook file on my current project. I have a dedicated latte_functions_extension.php file where I can declare these in an organized way. <?php declare(strict_types=1); namespace ProcessWire; use Latte\Extension; final class CustomLatteFunctions extends Extension { public function getFunctions(): array { return [ // Latte templating paths 'definitions' => fn (string $file) => $this->createComponentPath('definitions', $file), 'embeds' => fn (string $file) => $this->createComponentPath('embeds', $file), 'imports' => fn (string $file) => $this->createComponentPath('imports', $file), 'layout' => fn (string $file) => $this->createPath('layouts', $file), 'partial' => fn (string $file) => $this->createPath('partials', $file), // Expose ModernismWeekSite.module.php as site() 'site' => fn () => wire('modules')->get('ModernismWeekSite'), // Ensure that wire() is available in all components 'wire' => fn (?string $property = null) => wire($property), ]; } /** * Creates a path for including a component * @param string $file Dot notation subdir and filename, * @return string */ private function createComponentPath(string $componentSubdir, string $file): string { return $this->createPath("components/{$componentSubdir}", $file); } /** * Creates a component file path for a given filename does not require .latte suffix * @param string $templatesSubdir Name of directory in /site/templates * @param string $file Name of .latte file that exists in the directory */ private function createPath(string $templatesSubdir, string $file): string { !str_ends_with($file, '.latte') && $file = "{$file}.latte"; return wire('config')->paths->templates . "{$templatesSubdir}/{$file}"; } } $wire->addHookAfter( "RockFrontend::loadLatte", fn (HookEvent $e) => $e->return->addExtension(new CustomLatteFunctions), ); I've defined a 'wire' function that will be available in every component with a parameter that allows you to use it like you would expect to such as 'wire('modules')'. I have a custom site module so I've exposed that as 'site()'. If you wanted to make it easier to work with modules in your templates and included files you could define a more terse 'modules' function: <?php final class CustomLatteFunctions extends Extension { public function getFunctions(): array { return [ // ... 'modules' => fn (string $moduleName) => wire('modules')->get($moduleName), ]; } } I feel that there is a tradeoff when using Latte in ProcessWire. There are some great features in Latte, but it requires introducing abstractions and feature management to make Latte act like ProcessWire, like manually defining functions. This just means that you'll have to keep a balance of complexity/abstraction vs. using as minimal enough of a approach to keep it sane. The other challenge here is that now there can be a deviation between where the native ProcessWire API is used in Latte and other places where it isn't. So some files will use $modules, and other files will use modules(), and it's not clear whether that's referencing the ProcessWire functions API, or whether it's leveraging Latte's custom functions extension feature. Something to keep in mind when determining how other files will be included/rendered in other files. In my case I have two examples that brought this challenge out for me today. Here's one // Native behavior provided by the module // Does not work everywhere due to scoping in Latte. This caused an issue when trying to embed forms // in a modal within a {block} {$htmxForms->render($page->field_name)} // With one level of abstraction using a custom function // Because this replicates how ProcessWire provides the wire() function natively, the usage feels // natural and predictable, especially for core behavior, but this introduces a lot of verbosity // that starts to make files pretty messy {wire('modules')->get('FormBuilderHtmx')->render($page->field_name)} // With two levels of abstraction in Latte via a custom function // This looks better and still adheres to the syntax of the ProcessWire functions API // The issue is that every native ProcessWire function has to be manually replicated in our custom // functions hook class. Managing this in the long term requires extra work and cognitive load {modules('FormBuilderHtmx')->render($page->field_name)} // With 3 levels of abstraction // This has restored the feel of the variables provided by the module, but again we have to track // And implement them on an as-needed basis to manage them within the context of usage in Latte {htmxForms()->render($page->fieldName)} The level of abstraction you choose depends on how much customization you want vs. how much extra work it will take to maintain simplicity by hiding complexity. The other functions, 'embeds', 'definitions', 'imports', etc. are to overcome the relative paths all over the place in Latte. // In my home.latte file {layout './layouts/main.latte')} {var $collapseNavOnScroll = true} {import './components/definitions/headlines.latte'} {import './components/definitions/event_activity_card.latte')} {block subnav} {embed './components/embeds/event_subnav.latte', eventPage: $page->eventPage()}{/embed} {/block} // ...etc // Becomes {layout layout('main')} {var $collapseNavOnScroll = true} {import definitions('headlines')} {import definitions('event_activity_card')} {block subnav} {embed embeds('event_subnav'), eventPage: $page->eventPage()}{/embed} {/block} // etc. // In RPB blocks {embed '../../../components/embeds/example.latte', content: $block->body()}{/embed} {embed embeds('example'), content: $block->body()}{/embed} This really helps when working with Latte templates that embed components that have nested embeds and imports because the functions are generating absolute paths that Latte can handle. With these functions, I don't have to think about relative paths anywhere. As for the directory structure that I chose that requires the different paths, here's what it looks like: /templates ...etc /components /definitions /embeds /imports ...etc I chose that method because Latte has many different ways of including, embedding, and importing code from other files. It made more sense to organize my code by how Latte treats it. It wasn't my first choice, but this overcomes confusion that I was experiencing when working with all of the files sharing the same components directory. Without this type of organization it can be challenging to because of scoping and how {embed}, {include}, {define}, and {import} behave differently. Some accept parameters, export values, or use blocks, but not all of them do. So having a "modal.latte" component file that provides a {block content}{/block} next to 'button.latte' that doesn't render anything and only exports items created using {define}, next to a file that is only added to a template using {include} that doesn't take parameters or provide blocks had me jumping between files a lot and slows down development checking to see that the file is being used correctly. Just sharing some of my experiences in case it helps anyone else out. If anyone sees anything here that can be done better or if I'm missing out on features that Latte has that don't require some extra steps, let me know!1 point
-
This <?php echo $map->render($page, 'YOUR MARKER FIELD'); ?> would be this {$map->render($page, 'YOUR MARKER FIELD')} Your error message means, that $map is NULL. That means $map is not available in your latte file for whatever reason. That means you are not struggling with latte syntax, you are struggling with PHP π π You can easily debug this via TracyDebugger: {bd($map)} {bd($page)} To help you with your specific problem I'd need more info in where you are trying to use this markup...1 point
-
@joe_g, you might be interested in this recently released module:1 point
-
When I was in school I had a PHP 4 book. A printed book made of paper. And a Macromedia Dreamweaver book too. When I started to learn webdev with Joomla! I consulted a lot with my former classmate. And occasionally asked something on a forum. When I thought about getting into Drupal I watched a lot of Youtube tutorials. When I started to learn PW the forum was my best friend and I spent hours here. And then the docs got better - I started to read those before going to sleep. And then I learned to read the source code and to find it interesting enough to do it instead of watching Youtube. When I started to learn htmx I had to join their discord. It was nice there and the answers came quickly. But I couldn't find anything by myself. When I needed to get a jumpstart on Laravel, I got my Laracasts account and started to read the docs again. When I need to get my head around some vue stuff I know not enough about I ask Cursor AI and it gives me quick answers most of which really help me to move forward. What's that all about? I do not know yet. Is that about I am old and TOO old to learn something on TikToc? Is that about our lives getting more digital, fragmented and quick? Is it about loosing local real-world in-person communications to around-the-globe communities and AI or making the world "be as one" through better means of communications and freedom of consciousness? Is it about each generation living in its own media and making it the part of the message? There is some room for interpretation here. But I've spent so much time in PW forms, and got so much out of it, and put so much of myself into it I tend to prefer it over "other stuff". I do not know if it is the forum principle itself, its size (not so big and cozy), the great people here or something else. Many times in the past I was even a bit angry on Ryan for him not push PW on every platform and occasion. For PW not grow fast enough and conquer the webdev world. But now I kind of think it is for the good. You can't be this and that in the same time, you can't be everything for everybody. And even if you could It probably wouldn't make you more happy. I do not know how to end this. No moral in the end. Just sending love to all yall here! Go see and join all pinkary, bluish and yellowish places wherever they are. And come back here to tell us about them π1 point
-
The idea behind the jobs forum is for anyone looking for paid development work to post their requirements in one place and for developers to get in touch with them. Any project can be posted, whether it's custom development work, website design, or complete installation and setup of a website. There are a few guidelines that are useful to bear in mind to help things go smoothly: Give a good amount of detail about the project so that prospective developers know roughly what will be involved. If a project requires an NDA for any reason, try and give non-specific details such as the type of development work involved (module development etc). Let people know how to contact you - if no contact details are given, people will most likely PM you on the forums here. If you have a requirement to work with a developer in the same country as you, please mention this to narrow the field of applicants. If you are happy mentioning a budget in the open, this is also fine but not required.1 point