Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/26/2021 in all areas

  1. If you want to do something quickly, maybe gatsby is not ideal. Have a look at https://kit.svelte.dev/ or https://www.11ty.dev/. Those are two easy ones for creating static sites, and I would encourage you to have a look at them (particularly Svelte and SvelteKit) so you see what's new in the craft, but I'm sure you would find it as easy to get back on PW since there was no complexity added at all.
    2 points
  2. More generally, there is a selector for this exact thing: has_parent https://processwire.com/docs/selectors/#finding2
    2 points
  3. Have you tried: $page->find('template=event'); Should return all descendants of the current page.
    2 points
  4. There is a configurable limit on page numbers that you can increase from the default 999:
    2 points
  5. Cheers @elabx. I hope you are keeping well.
    1 point
  6. You're welcome ✌️ Svelte is also a great introduction to component based development, and the tutorial is great. React is a bit overwhelming at first because it feels so clunky, but it brings more job opportunities with it. If you still want to learn React after learning Svelte, at least you'll have already some of the shared concepts grasped.
    1 point
  7. find() in the end uses has_parent, so I don't think there's much difference. https://github.com/processwire/processwire/blob/master/wire/core/Page.php#L2222
    1 point
  8. Thanks @Rudy and @Pixrael! I wasn't aware urlSegment would not capture URL query strings. I went this route: if(!isset($_GET['publish_from']) || !isset($_GET['publish_until'])) { // output only on /events/ }
    1 point
  9. .. or you can use $input->get() check docs here: https://processwire.com/api/ref/wire-input/get/ if you want to learn how to use ulrSegments, read this: https://processwire.com/docs/front-end/how-to-use-url-segments/
    1 point
  10. Hey @Mantas, welcome to the forum and to ProcessWire ? To do so I just delete the following folders via FTP: /site/assets/cache/*/*.* /site/assets/sessions/*/*.* and truncate the table "caches" in the DB. After that you have to relogin and do a "module refresh" via "/processwire/module/?reset=1". That's the way I do it.
    1 point
  11. Yes 100%. I built and run a client-specific CRM/membership system for an arts organisation using Processwire. It started out relatively simple and has grown, but allowed us to build exactly what was needed and cut-out the over-complication of the many off the shelf systems they had already tried. Without PW's baked-in features development of this system would have taken an immeasurable amount of time longer.
    1 point
  12. Sure... If you haven't read deeply into htmx, the main premise is that the server is the single source of truth regarding both data and markup, i.e. whole application state. If we need to update either data or markup, the server handles that. We just need to tell it what action to take. Validation has to pass, of course, before the server will oblige ?. Below is a quick example that demonstrates updating the markup using htmx based on user actions. Only 'remove' locations is demonstrated in this example. I wasn't sure whether your app shows the user both their removed and added locations and whether they can reset the session to have all locations reloaded afresh. It doesn't matter much as it wouldn't change much of the logic in the example. Secondly, note that this example makes use of alpine.js and tailwind css just for the pizzaz. These are not required by htmx. To let ProcessWire recognise htmx requests, please refer to this thread. Depending on the approach you take from there, you might not even need a JavaScript file! In the example below, we do have a JavaScript file just because we want to use alpine.js (for notifications) and we need htmx to talk to alpine.js. We also need the JavaScript file to tell htmx to add XMLHttpRequest to its request headers so that ProcessWire's $config->ajax will understand the request. First, let's see a demo then we'll see how easy our work is using htmx. Just for this demo, I have included htmx (and alpine.js and tailwind css via their respective CDNs [in production, you want to purge your tailwind css ?]) in my _main.php. Inside the template I am using for this demo, I have the following code. Here, I have removed the tailwind classes used in the demo so we can focus on htmx. Note that you don't need a dedicated template file for this to work. It will work with any template. As long as htmx is loaded in the page view and your template (in this case, the current page's template) is listening to ajax requests. In the template file, the main htmx magic happens here: <?php namespace ProcessWire; $out = "<a hx-post='./' hx-target='#locations' hx-vals='{\"location_add_id\": \"{$page->id}\"}' hx-include='._post_token' hx-indicator='#locations_spinner_indicator'>Add</a>" . "<a hx-post='./' hx-target='#locations' hx-vals='{\"location_remove_id\": \"{$page->id}\"}' hx-include='._post_token' hx-indicator='#locations_spinner_indicator'>Remove</a>"; echo $out; Let's go through the htmx attributes: hx-post This tells htmx where to send its ajax request. In this case, we are sending it to the same page we are viewing (./) and are using POST. We could have used hx-get if we wanted to (GET). hx-target This tells htmx which markup to replace/swap. The default is to replace the markup of the element from which htmx was called. However, hx-target can be used to specify the element to replace. In this example, we are replacing the whole listing so we target its wrapper element which has the id locations. hx-vals This is optional but we need it in our example. We want to tell the server which location (ID) has been added/removed. If we had a form element, we could have used it for this instead. Since we don't have one, we are telling htmx to process the (JSON) value of hx-vals and send that together with its request. Note: the escape slashes are so we can have raw, valid JSON in the attribute as required by htmx. hx-include This is also optional but important in our case. It tells htmx to include input elements found via the selector in this attribute in its ajax request. In our example, we are telling htmx to include the CSRF token we set on the server together with its request. hx-indicator Also optional. Tells htmx to show/hide this element to show the user that something happened. In this case we use a spinner. We could have used a progress indicator as well, .e.g., if we were uploading a file. That's it really! No event listeners, no handlers! We can add (and I did add one), event listeners on htmx events in order to do something after the event. In this example, htmx fires a custom event which alpine.js is listening to in order to show notifications after the DOM has settled. The notification type (success, error, etc) and the message are all coming back from the server but not as JSON. The markup to update the page is also coming back from the server. htmx receives it and plugs it into the DOM per the hx-target (also see hx-swap) attribute value. In this example, we are updating the whole listing. If we wanted, we could update just the location that was removed, e.g. add it back but with some removed 'indicator', e.g. greyed-out. In this example we use anchor tags as htmx triggers. For htmx, it doesn't matter; button, div, p, li, whatever valid HTML element would work. You already have a backend logic that's working for you but I show an excerpt of mine here, for completeness. Inside my-template-file.php (the template file for the template for the current page, in this example), I have the following code: <?php namespace ProcessWire; if ($config->ajax) { // check CSRF if (!$session->CSRF->hasValidToken()) { // form submission is NOT valid throw new WireException('CSRF check failed!'); } // ................ more code // e.g. check removed locations in the session, etc // get previously removed locations (keeping things in sync) $removedLocations = $session->get('removedLocations'); // REMOVING LOCATION if ((int) $input->post->location_remove_id) { $mode = 'remove'; $notice = "Removed"; $id = (int) $input->post->location_remove_id; } else if ((int) $input->post->location_add_id) { // ADDING LOCATION $mode = 'add'; $notice = 'Added'; $id = (int) $input->post->location_add_id; } // ................ more code // e.g. check if we really have a page by that id, SET $noticeType, $options and update session 'removedLocations' etc // build final content //----------- // @note: buildLocationsCards() is a function that does what it says on the tin. We use it in both the ajax response here and also below, in non-ajax content, when the page loads // the $options array contains a key 'skip_pages_ids' with an array of IDs of locations (pages) that have been removed in this session. We skip these in buildLocationCards(). $out = buildLocationCards($page, $options); // @note - here we always return one input only // we use the values in this input in JS to pass event details to alpine.js to show the correct notification and the notification message. $out .= "<input type='hidden' id='location_notice' name='location_notice' data-notice-type='{$noticeType}' value='{$notice}'>"; echo $out; $this->halt(); } // NON-AJAX CONTENT BELOW.... That's all there is to it ?. I am happy to share the full code if anyone wants to play with this further.
    1 point
  13. https://github.com/chrisbennett-Bene/AdminThemeTweaker Inspired by @bernhard's excellent work on the new customisable LESS CSS getting rolled into the core soon, I thought I would offer up the module for beta testing, if it is of interest to anyone. It takes a different approach to admin styling, basically using the Cascade part of CSS to over-ride default UiKit values. Values are stored in ModuleConfig Module creates a separate AdminThemeTweaker Folder at root, so it can link to AdminThemeTweaker.php as CSS AdminThemeTweaker.php reads the module values, constructs the CSS variables then includes the CSS framework Can be switched on and off with a click. Uninstall removes everything, thanks to bernhard's wonderful remove dir & contents function. It won't touch your core. It won't care if stuff is upgraded. You won't need to compile anything and you don't need to touch CSS unless you want to. It won't do much at all apart from read some values from your module config, work out the right CSS variables to use (auto contrast based on selected backgrounds) and throw it on your screen. You can configure a lot of stuff, leave it as it comes (dark and curvy), change two main colors (background and content background) or delve deep to configure custom margins, height of mastheads, and all manner of silly stuff I never use. Have been developing it for somewhere around 2 years now. It has been (and will continue to be) constantly tweaked over that time, as I click on something and find something else to do. That said, it is pretty solid and has been in constant use as my sole Admin styling option for all of those 2 years. If nothing else, it would be great if it can provide any assistance to @bernhard or other contributor's who may be looking to solve some of the quirkier UiKit behavior. Has (in my opinion) more robust and predictable handling of hidden Inputfields, data-colwidths and showIf wrappers. I am very keen to help out with that stuff in any way I can, though LESS (and any css frameworks/tools basically) are not my go. I love CSS variables and banging-rocks-together, no-dependency CSS you can write with notepad.
    1 point
  14. https://pwgeeks.com/
    1 point
  15. The UserActivity Pro module in ProDevTools was upgraded this week so that it now uses the Javascript Beacon API, enabling quick and reliable identification of when a user has finished a particular activity. It also now keeps track of when an activity is visible to the user or the window is hidden (like minimized or in a different tab), and it is able to report how many unsaved changes a user has made. All of this is visible from the Access > Activity menu in the admin. On the core side, there have been minor updates, so no version bump this week. But there are still a couple new PRs and useful things to look at in the commit log. The plan for next week: Bernhard Baumrock has been working on a PR that makes it very simple to modify and recompile the CSS of our AdminThemeUikit module... like as simple as placing an admin.less file in /site/templates/ directory. I'll save the details for next week, but after using it a bit here I have to say it's very cool. It also makes it really simple to upgrade the Uikit version. Previously I'd been following the build process as outlined in the Uikit instructions and often found myself in a state of confusion with npm errors and strange dependencies, needing upgrades for unidentifiable tools and producing incoherent warnings that never went away and left me with little confidence in the process. Perhaps it was because I started all this back when Uikit 3 was still beta, but the result was that I didn't much like upgrading Uikit or recompiling our AdminThemeUikit CSS, and I don't think anyone else did either. It made it a little difficult for our AdminThemeUikit module to achieve its original mission of being a simple module that many would extend and build from. Well, Bernhard has found a way to skip over all that nonsense and made it much simpler for all of us, so that AdminThemeUikit can finally be what it set out to be. I look forward to integrating this PR hopefully this coming week and think it means a lot of good things for our admin. Also, huge thanks to Pete for upgrading our forums this week! It's a great upgrade.
    1 point
  16. @Hector Nguyen getcsv() does return an array, but it is an array representing and consuming the memory of just one line from a CSV file (i.e. the columns from 1 row). fgetcsv() is just a layer on top of the fgets() function, which reads one line at a time from a file, which is what makes it memory friendly. On the other hand, PHP functions like file() or file_get_contents() do read the entire file in memory, so they are not memory friendly, even if they are fast. @fedeb I think the best route to take for your groupID+start+end+sequence would be a custom Fieldtype. This would give you all of the benefits of having a repeater, and without any of the overhead. Custom fieldtype may sound complicated, but it's not at all. I've developed a module that can very easily be adapted for this need. See FieldtypeEvents which was created as an example to build exactly this sort of thing from. If you are interested in that route and have any questions, I'm happy to walk you through it.
    1 point
  17. @ryan I'm afraid not, fget() in PHP will return one string (a line) but fgetcsv() will return an indexed array. An array in PHP is not very friendly with big dataset because it's still saved into the memory! The main difference is in memory usage. In the first case all the data are in memory when you return the array. Because of no matter what, if you "returns" values, that will be save in memory. In the second case you get a lazy approach, and you can iterate the values without keeping all of them in memory. This would be a great benefit when memory is a constraint compared to the size of the sum of all your data. I've managed to import 4GB CSV file on the Shared VPS 1GB mem in seconds, the bottleneck of "yield" method now is your MySQL.
    1 point
  18. Fieldtype Compatibility Overview doesn't work Fieldtype PageTable inside Repeater or RepeaterMatrix Fieldtype Page + 3d Party module AdminPageEditLinks inside Repeater or RepeaterMatrix works Fieldtype RepeaterMatrix inside RepeaterMatrix Fieldtype Repeater inside Repeater Fieldtype Repeater inside RepeaterMatrix and the other way round Fieldtype Page inside Repeater or RepeaterMatrix Fieldtype PageTable inside Page and the other way round @Martijn (next post) thanks, updated list
    1 point
×
×
  • Create New...