Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/02/2023 in all areas

  1. Hey guys. Shouldn't the showcase section have a list by author feature? I just found myself wanting to send someone a link to the showcase of the sites I made in PW and there doesn't seem to be a way to do it. And while at it, how about mentioning which projects were featured on PW Weekly? We now have a quite large projects list there, and if the point is to show off the best work made with PW to legitimise it, we might as well bring out the best projects and make it cool to be featured. What do you think?
    3 points
  2. Here's one of my latest projects: https://petibol.pt/ Petibol develops and produces of all types of EPP (Expanded Polypropylene) and EPS components and packaging for various industries. This website is a collaboration between Supertiny and GOdesign. Super simple approach: The frontend is just SCSS and vanilla js "components" (no libraries), and pages are built with a blocks system based on a repeater field. Having tried a bunch of stuff between building this site almost a year ago and publishing it (Tailwind, AlpineJS, VUE...) it's pleasing to return to this site's code and compare the approach. Here I've basically set up Laravel Mix to compile SCSS, join and minify a bunch of <1kb js files. A BEM style approach to the styles so that I have a bunch of preset variables for typography, spacing and whatnot, and the JS files follow the same logic of identifying components like the hamburger or the parallax effect by looking for specific data-attributes and going from there. Super clean, performant, and couldn't be easier to pick up and maintain.
    3 points
  3. Hey everybody, I just uploaded a small textformatter module for wrapping tables with a div container in order to display responsive HTML tables in the frontend. TextformatterWrapTable Processwire wrap table module is a textformatter module for processwire CMS/CMF. It is wrapping markup tables with a div container. wrapping tables with div container simplifies the process of displaying responsive tables in the frontend. The css classes for the wrapper and the table are configurable. .table-responsive / .table by default the module produces the following markup: <div class="table-responsive"> <table class="table"> ... </table> </div> Link to Repository https://github.com/pmichaelis/TextformatterWrapTable
    1 point
  4. Looks professional, good work.
    1 point
  5. Have a look here https://stackoverflow.com/questions/53214116/intersectionobserver-callback-firing-immediately-on-page-load I made a codepen that does just that https://codepen.io/gebeer/pen/KKBMWzV?editors=1011 It uses getBoundingClientRect, though.
    1 point
  6. Have a look at https://htmx.org/docs/#websockets-and-sse Server Sent Events might be a solution for you.
    1 point
  7. No, it will create a single database table. If you use the table field on multiple pages, all records will go into the same database table, just with a foreign key connecting each record to its page. So perhaps you will make a Track template and add the Hotlaps field (Profields Table) to it. That way you don’t need a custom trackID column because that will just be the page’s ID. Because it’s a single database table you will still be able to figure out, for example, the car with the most hotlaps across all tracks, by just doing very simple custom SQL: $sql = <<<SQL select car, count(id) as hotlaps from field_hotlaps group by car order by count(id) desc SQL $query = wire('database')->prepare($sql); $query->execute(); $queryResults = $query->fetchAll(\PDO::FETCH_KEY_PAIR); A car will probably be a page, so you would use a Page Reference column in your table. The query above thus gives you a bunch of page ids you can convert to page objects like this: wire('pages')->getByIds(array_keys($queryResults));
    1 point
  8. Hello all, I wanted to share a proof of concept approach on how we can have an infinite scroll pattern without writing Javascript. We can achieve this with htmx. What you will get An overview page with a list of posts (PW pages). On initial page load 5 posts will be shown. When scrolling down and reaching the last post, another 5 posts will be loaded via AJAX in the background and appended after the last post until no more pages are found. Prerequisites You are using the delayed output strategy, with a _main.php appended. Just like using the default site profile when installing ProcessWire You are using markup regions, in my _main.php I have a div#content that will be used for the output of the posts Inside site/config.php $config->useMarkupRegions = true; Inside site/templates/_main.php <!-- main content --> <div id='content'> </div> For script loading I am using a custom $config->bodyScripts FilenameArray Inside site/config.php $config->bodyScripts = new FilenameArray(); Inside site/templates/_main.php before the closing </body> tag <?php foreach ($config->bodyScripts as $file) : ?> <script src="<?= $file ?>"></script> <?php endforeach ?> </body> PW page structure for this tutorial In the page tree I have a parent page "Posts" with template "posts". All child pages of that page have template "post" In the template "posts" settings in the "URLs" tab, check "Allow Page Numbers" and save. Needed for pagination. When viewing the page "Posts" all logic happens inside site/templates/posts.php site/templates/posts.php <?php namespace ProcessWire; // posts.php template file // add htmx js from site/templates/scripts $config->bodyScripts->add($config->urls->templates . 'scripts/htmx.min.js'); $limit = 5; $posts = $pages->find("template=post, limit={$limit}"); $lastPost = $posts->last(); $nextPageUrl = $page->url . $input->pageNumStr((int) $input->pageNum() + 1); $hxAttributes = array(); $hxAttributes[] = 'hx-get="' . $nextPageUrl . '"'; $hxAttributes[] = 'hx-trigger="revealed"'; $hxAttributes[] = 'hx-swap="afterend"'; ?> <?php if (!$config->ajax) : ?> <section pw-append="content" class="posts" hx-headers='{"X-Requested-With": "XMLHttpRequest"}'> <?php endif ?> <?php foreach ($posts as $post) : ?> <article class="post" <?php if ($post == $lastPost) echo implode(' ', $hxAttributes) ?>> <header> <h3><?= $post->title ?></h3> </header> </article> <?php endforeach ?> <?php if ($config->ajax) return $this->halt() ?> <?php if (!$config->ajax) : ?> </section> <?php endif ?> And that is all there is to it. Not a single line of Javascript, thanks to htmx. I followed the infinite scroll pattern from the official htmx examples. Now let's break the code down into easily digestible chunks // add htmx js from site/templates/scripts $config->bodyScripts->add($config->urls->templates . 'scripts/htmx.min.js'); This adds site/templates/scripts/htmx.min.js to our custom $config->bodyScripts FilenameArray so it will be loaded in _main.php. You can get the script here from unpkg.com. $limit = 5; $posts = $pages->find("template=post, limit={$limit}"); Sets our pagination limit to 5 and loads the correct set of posts. $lastPost = $posts->last(); Saves the last post of each set. We use this later to determine whether the htmx attributes should be rendered. $nextPageUrl = $page->url . $input->pageNumStr((int) $input->pageNum() + 1); We are building the link to the next "page" with the next set of posts. Will result in something like "/posts/page2", "/posts/page3" etc. $hxAttributes = array(); $hxAttributes[] = 'hx-get="' . $nextPageUrl . '"'; $hxAttributes[] = 'hx-trigger="revealed"'; $hxAttributes[] = 'hx-swap="afterend"'; Define our htmx attributes as an array. They will be added to every last post's HTML. Note the hx-get attribute which will be the URL for the AJAX call in the background. That request is triggered whenever the last post becomes visible inside the viewport while scrolling down. hx-swap afterend tells htmx to append the next batch of posts after the last post. <?php if (!$config->ajax) : ?> <section pw-append="content" class="posts" hx-headers='{"X-Requested-With": "XMLHttpRequest"}'> <?php endif ?> // and <?php if (!$config->ajax) : ?> </section> <?php endif ?> Renders the wrapping section tag only on initial page load which is a none AJAX request. Note the hx-headers='{"X-Requested-With": "XMLHttpRequest"}'. This adds an additional header to all AJAX requests with htmx. We need this header so ProcessWire understands that it is an AJAX request. Otherwise $config->ajax would always return false. See https://htmx.org/attributes/hx-headers/ for more info <?php foreach ($posts as $post) : ?> <article class="post" <?php if ($post == $lastPost) echo implode(' ', $hxAttributes) ?>> <header> <h3><?= $post->title ?></h3> </header> </article> <?php endforeach ?> Render each posts's HTML. If it is the last post, also render our htmx attributes. For brevity in this example I only output the post title. <?php if ($config->ajax) return $this->halt() ?> For AJAX requests stop execution of the template file and everything that follows. This prevents appending of _main.php for ajax calls. So we only get the desired HTML for the list of posts and no head, footer etc. Summary Compared to other approaches, htmx lets us control all our AJAX logic with a few html attributes. Really neat and concise. Easypeasy. I like that and will surely use an approach like this in future when infinite scroll is needed. What I like in particular is how easy this is implemented with ProcessWire's powerful pagination capabilities. If you have the same page structure, the code in site/templates/posts.php is working out of the box as is. I have this running on a standard PW multilang site profile with additions/amendments mentioned above under "Prerequisites". Here's a visual of the result:
    1 point
  9. This week I've been focused on a client project, building out this Reviews section (still a work in progress). There's a few hundred URLs within it, but it's just one page/template. The reviews are via ProcessWire's core comments (FieldtypeComments) field and primarily uses the FieldtypeComments find() method for filtering and sorting of comments/reviews. On this same site, this week Pete launched this very nice blog called Tailwinds, which he told me is using Tailwind CSS (and powered by ProcessWire). The name of the blog (Tailwinds) actually precedes the use of Tailwind CSS, but if you've got a blog named Tailwinds, Tailwind CSS certainly seems like the appropriate framework. 🙂 On the core dev branch we've had a few commits resolving issues and minor improvements, but not enough for another version bump this week. Have a great weekend!
    1 point
  10. Good idea, @Markus Thomas. Unfortunately these url hooks don't work in my use case because the redirect happens "below existing pages", as explained here: $wire->addHook('/existing-page/r', function($event) { return "Hello R"; // Not shown (contents from the "nearest parent page" is shown) }); $wire->addHook('/non-existing page/r', function($event) { return "Hello"; // Works });
    1 point
  11. This thread is for me to announce Padloper releases (until I find a better way to do it). Please use your download link (sent to your email) to get the latest Padloper version. Please don't post your bug reports on this thread. Instead, create a new thread for that in this support forum. Thanks. Releases Release Sunday 12 June 2022: Padloper 002 Features Add Import API (currently for product-related imports only). This allows you to import items (attributes, categories, products, generate variants from scratch, etc) into your padloper shop. Please see the Import API documentation. Rest of the World Shipping Zone is now fully functional. Configurable dynamically loaded product variants. This is useful for cases where a product contains lots of variants. Editing such a product will slow down the browser considerable as all children pages (variants) will be loaded as well. Bug Fixes Please see the bug fixes prior to today's release date referenced in the bugs and fixes thread. --- Release Thursday 14 July 2022: Padloper 003 Features Add Addons Feature. This allows you to extend the functionality of your shop by developing, adding and activating addons (mini apps). The forum announcement about this feature is here. Please see the Addons documentation and the related Addons API documentation. A short demo of the feature is available here. Bug Fixes Please see the bug fixes for today's release date referenced in the bugs and fixes thread. Release Sunday 24 July 2022: Padloper 004 Features Update FieldtypePadloperOrder schema to include details about selected shipping rate name and delivery times. Amend single order view GUI to show order shipping rate name and delivery times. See the request details here. Make a number of methods hookable - for extra validation of custom form inputs and custom determination of whether to apply EU digital goods tax. See the request details here. Release Tuesday 30 August 2022: Padloper 005 Features Amend inventory GUI to allow non-editing of locked variants (similar to products without variants). Bug Fixes Please see the bug fixes for today's release date referenced in the bugs and fixes thread. Release Friday 23 September 2022: Padloper 006 Features Make PadloperProcessOrder::getOrderCustomer hookable. This has various uses, e.g. allows to initially pre-fill customer details to the order checkout form during order confirmation. Can be used, for instance, in conjunction with LoginRegister module. See the request details here. Demo code is available here. Bug Fixes Please see the bug fixes for today's release date referenced in the bugs and fixes thread. Release Tuesday 27 September 2022: Padloper 007 Features/Enhancements Don' t show product properties settings in General Settings > Standards Tab if product property feature was not installed. Bug Fixes Please see the bug fixes for today's release date referenced in the bugs and fixes thread. Release Sunday 08 January 2023: Padloper 008 Features/Enhancements Fix bugs related to the demo starter projects. Bug Fixes Please see the bug fixes for today's release referenced in the bugs and fixes thread.
    1 point
×
×
  • Create New...