Jump to content

psy

Members
  • Posts

    552
  • Joined

  • Last visited

  • Days Won

    6

Everything posted by psy

  1. @bernhard Normally I use MarkupSimpleNavigation and cache each 'page' menu with the appropriate 'active' class set. This menu is so small I decided only to cache the PageArray then output to the front end using a foreach loop and test to see if the page was 'active' and add the CSS class accordingly in the template. Wanted to bring it to attention in case it's a 'gotcha' for others working with custom page classes and cache. πŸ™‚
  2. Loving the custom page classes but I ran into an issue. I wanted to cache the main navigation items to save DB calls. Set up is: site/classes/HomePage.php site/classes/BasicPagePage.php and templates: basic-page.php home.php In _init.php: <?php namespace ProcessWire; // Get the nav items and save them to a cache /* This crashes with Error message: User Error Exception: Can't cache multiple page types together: HomePage, BasicPagePage (in /home/xxxxx/xxxxxx/wire/core/WireCache.php line 954) */ $menuItems = $cache->get('menuItems', 3600, function() { $pp = wire('pages'); $items = $pp->find("id=1|1028|1031|1029"); // Home, Gallery, Testimonials, Contact return $items; }); bd($menuItems); // Without saving to cache works fine $items = $pages->find("id=1|1028|1031|1029"); // Home, Gallery, Testimonials, Contact bd($items);
  3. @Warran Yes, yes and yes As in my original post, both the page & repeater matrix field use the 'body' field. It's a textarea with CKEditor + TextformatterVideoEmbed and the body content source code is the same
  4. Having strange issues with this one as well. The field is 'body' and it has the TextformatterVideoEmbed option. On the same page, I have the YT URL in the page's body field. It outputs the URL. Below it, I have a Repeater Matrix field with the same body field and content and it outputs the video. Any ideas? Edit: I have found a cause but not the fix. My code is: <?php $featured = false; if ($page->hasField('images') && $page->images->count > 0) { $featured = $page->images->last; $description = !empty($featured->description) ? $featured->description : $page->get("headline|title"); } // ... ?> <?php if (!empty($page->body)) : ?> <div class="main__body owllob"> <?php if ($featured != false) : ?> <img class="main__feature-img" loading="lazy" src="<?=$featured->width(300)->webp()->url?>" alt="<?=$description?>" /> <?php endif; ?> <?=$page->body?> </div> <?php endif; ?> When I include a 'featured' image and even though it renders separately to the body field, the YT URL does not convert. When I delete the image, it does and the video shows/plays as expected???
  5. Quick update... Finally figured out to get React/NextJS to work with a basic (minimal field types to convert to JSON) PW site. Giving self a pat on the back when I discovered Svelte πŸ’© Svelte felt (I'm a poet & didn't know it 😝) so much more like PW - JS, HTML & CSS with 'state management' and no shadow DOM. The only problem was routing. I'd spent far too long figuring out React/NextJS routing and Svelte offered no immediate solution. The old (like 2yrs) way of routing was called Sapper. Development on Sapper has ceased with all efforts now focussed on the new way, SvelteKit which is in pre-beta (😳 ). Anyhoo, went with SvelteKit and got it working. I've only scratched the surface on what's possible with React/NextJS and Svelte. Both offer Server Side Rendering (SSR) making the site SEO friendly & fast-loading. Given a choice, I'd choose Svelte every time. With both React/NextJS and Svelte using @Sebi's AppApi with customisation depending on the framework, I: created a home page that pulls the data from the PW home page created a 'slug' page that pulls the data from the PW page url and displays it in a component based on the PW page template as returned in the page JSON, and shows the correct route in the URL from a nav menu In both cases, the page layout is not a PW template but a conditional component file. Anyone else tried Svelte with PW? Your thoughts & comments welcome
  6. I'm running 3.0.175 on a dev site and all works as expected for editing admin templates & fields. Have you tried reverting to the PW default UiKit admin theme? Maybe something to do with the custom admin theme you're using
  7. Thanks for the suggestions. Putting it down to a 'who knows?' Nothing changed and all small images that failed yesterday uploaded fine today. That's net-life for you! LOL
  8. I've searched, and maybe missed, the solution. I have a 'normal' images field and uploading images with a file size greater than 10Kb is fine. Any image size smaller results in the never-ending spinner and no upload. No min/max width/height set on image uploads in admin, ie just the defaults. Any ideas on how to fix? Using: PW: 3.0.175 PHP: 7.3 Marking it as "Resolved" rather than "Solved" as it auto-magically fixed itself. No idea whether PW, PHP, or just an internet hiccough... All good now 🀞
  9. May not be @Sanyaissues' fault. I've had ProCache debug on and then unchecked the Debug checkbox to turn it off and debug stays on. Seems the empty checkbox isn't always respected. Just saying... Nice site πŸ™‚
  10. Thanks to @bernhard introducing me to Tabulator, I've used it in several projects too - both admin and frontend side. It's powerful & fast. Once you get your PW PageArray converted to json, it's just a matter of defining your columns, filters & CSS
  11. @JeevanisM have no answer to that question. It's one I'm asking myself. I truly hope I don't simply to win business, especially for clients who don't need it but are being lemmings and following the hype. I Googled the "benefits of REACT" and every SERP article was written by a JS developer who confused "benefits" with "features". Eg: "It manages state" is a feature, not a clearly defined benefit to the user
  12. I'm really hoping the "everything needs to be node/react/js" fad/hype dies off soon. Twice today on 'important' sites (one an airline booking site), the ajax/promise/whatever failed. Was left looking a never-ending spinner. Awkward as had no idea where my flight booking went. Don't get me wrong, JS is useful but like most things in life, please use in moderation
  13. The repeater parent is not the page that calls the repeater item. To get the page that it appears on, you need to use 'getForPage()'
  14. Yep, everything I had working with AppApi and REACT/NextJS broke with the PW 3.0.173 upgrade. Downgrading is a short-term option but limits future PW upgrade benefits
  15. Doing a little happy dance. Has only taken me a week to figure out how to match React/NextJS to work with @Sebi's amazing AppApi module with pages below the top level, ie routing. I'm sure many of you PHP/PW gurus would have figured it out sooner
  16. @Sebi Thanks for the quick response. I'd already gone past that point both in PW and Postman so the connection is good. I'd even written my own method in Examples to get a page by ID. Maybe not as sophisticated as yours but it too worked: <?php namespace ProcessWire; Class Example { public static function test () { return ['test successful']; } public static function getPageById($data) { $data = AppApiHelper::checkAndSanitizeRequiredParameters($data, ['id|int']); $p = wire('pages')->get("id=$data->id"); if(!$p->id) throw new \Exception('Page not found', 404); $response = new \StdClass(); // Hardcode any data you need that does not have an inputfield field in the admin $response->id = $p->id; $response->name = $p->name; $response->path = $p->path; // This retrieves all the admin input fields. Does not (yet) get page images or files, just single entry data $fields = $p->getFields(); foreach ($fields as $fld) { $fldName = $fld->name; $response->$fldName = $p->$fld; } return $response; } } This enabled me to get the page data into the NextJS client and embed in the 'template/component' as variables from any existing PW page. My next exercise was to delve into the NextJS router so that I could retrieve pages via their path and those paths would appear in the URL. Couldn't work it out in my own PW code (no surprises there!). It was then I installed your Twack module and used the Twack routes & TwackAccess.class.php at which point I ran into the issues mentioned above. I'm sure it's my lack of knowledge of REACT/NextJS rather than your code... Doesn't help when their doco doesn't match up with their examples in gitHub. Even so, it would great to use your TwackAccess classes rather than reinventing the wheel.
  17. Excited to be learning REACT/NextJS. It's so 'on-trend'. I can double my hourly rate, take 3x as long to deliver a website with 2/3 of the Google Lighthouse results and who doesn't love the spinner while the component content loads? Doing a well optimised PW site with minimal JS, fast page loads, accessibility, SEO and more built in is so old hat. And even better, with JS frontends, the code maintenance goes on and on. No end to revenue possibilities. FML
  18. I've read the doco, installed the module & Twack and no matter what I try when retrieving a page, all I get back is a successful Promise or worse, an error message about invalid json. Using React/Nextjs and the page is published, viewable & using the basic-page template. The authorisation is single JWT and the client JS code is: export async function PWPageByUrl(path) { // url is correct and returns a result, just not the one I was expecing const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/${process.env.NEXT_PUBLIC_API_VERSION}/page/${path}`, { headers: { 'x-api-key': process.env.NEXT_PUBLIC_API_KEY, 'authorization': process.env.NEXT_PUBLIC_TOKEN } } ) const data = await res.json() if (!data) { return { notFound: true, } } return { props: { data }, // will be passed to the page component as props } } On the PW server side as per doco with routes modified for v1, I have: I'm obviously missing something. Help to get it working as expected much appreciated. Thanks
  19. Once you've created your $year_overview PageArray, does the template use custom fields from the pages to generate the output? If so, it may be that the slowness is due to multiple calls back to the db during loops to get the custom fields' data. Try including the custom fields in the initial selector with 'auto-join' or using the new methods released by Ryan. https://processwire.com/blog/posts/find-faster-and-more-efficiently/#boost-performance-with-new-programmatic-autojoin-options
  20. It's a premium module but I believe Repeater Matrix will do exactly what you need. It's one of my 'must haves' on every site I create. It's part of the ProFields pack and I use other features on every site too, like Functional Fields . I'll be using the new Combo field as well. The time it saves me is well worth the investment not to mention the great support in the forum from other ProField users & Ryan himself. https://processwire.com/store/pro-fields/
  21. @Rudy & @Craig Thank you both πŸ™‚
  22. This is driving me nuts! What I want to do is get 'today' with a name, eg 'Tue', then create an array of week day names going backwards for a week, eg "Tue Mon Sun Sat Fri Thu Wed". My code is where $today is a timestamp for 'today': private static function _onlineWeek ($today, $progams) { $dt = wire('datetime'); $result = []; $dayNames = []; for ($i = 0; $i <= 6; $i++) { $daySeconds = $i * 86400; $dayTS = $today - ($daySeconds); $day = $dt->date('D', $dayTS); $dayNames[] = $day; } $result['labels'] = $dayNames; return $result; } The result is as follows starting with "Thu"???? array(1) { ["labels"]=&gt; array(7) { [0]=&gt; string(3) "Thu" [1]=&gt; string(3) "Wed" [2]=&gt; string(3) "Tue" [3]=&gt; string(3) "Mon" [4]=&gt; string(3) "Sun" [5]=&gt; string(3) "Sat" [6]=&gt; string(3) "Fri" } } Php dates are always a nightmare for me and this just doesn't compute in my brain. What am I doing wrong and suggestions on how to fix gratefully appreciated. Thanks in advance psy
  23. Hi @MoritzLost thanks for your reply. Obviously, I'm new to workbox and really appreciate the feedback πŸ™‚ Probably no reason other than when I did, I got lots of errors in the console. Precaching important pages is an excellent tip, as is auto-generating workbox-config.js in PW then including it in the service worker. This is my first successful attempt with Workbox after many, many failures trying to follow the docs. Just wanted to get it working. I especially struggled with the workbox-config.js generation using the CLI. The 'publish' directory cannot be '/' - which it is in PW and when when I could get it to generateSW with the publish directory as the root, it picked up loads of unnecessary files eg in /modules/, /assets/, etc. Seemed easier to create it manually than unpick the CLI's best guesses. For me, a nicely presented page with a logo & phone number is a better UX than the ugly browser default. At least the user can call if their internet is down.
  24. Around 3yrs ago I got excited about Progressive Web Apps (PWAs) and found a site that magically created an offline experience with a few clicks. It worked until it didn't. Had to backtrack and remove the PWA code on lots of sites due mainly to exceeded offline cache storage causing problems. My JS skills weren't, and still aren't, up to the level of expertise needed to rectify. I still did the manifest.json thing, reduced the network load wherever possible and got some great Google Lighthouse performance results by tweaking PW especially with ProCache. 3yrs is a long time in web life. If 1 dog year = 7 human years, then 1 web year must be 10+ human years. I delved back into PWAs recently and Google Workbox in particular. The biggest hurdle I had to overcome was Google's own Workbox docs. Forget the "Import" statements and the CLI easy PWA method recommended in the docs. They don't (or I could not get them to) work with ProcessWire. They're geared to web apps like React that have a build process that publishes to a directory eg 'app'. ProcessWire doesn't work that way. So here's what worked for me: Create a template. I called mine "offline" that may only have one page, no children and does not have a trailing slash at the end of the URL. Create a page, add fields as necessary, eg 'body' and apply the 'offline' template and save as a child of "Home" Change the page url to 'offline.html' - this is the default page name for Workbox. Easier to change this than fiddle around overriding the Google Workbox defaults. For extra comfort, I made the page name 'Unique' and 'Hidden' from lists and searches. Ensure the workbox service worker javascript is NOT appended to the offline.html page On all other pages append the following to the <body> tag. I'm using Regions so this goes in my <region id="regFooterScripts"> in _main.php <?php if ($page->name != "offline.html") : ?> <script> if ('serviceWorker' in navigator) { let scrUrl = '<?=$pages->get('/')->httpUrl?>sw.js'; window.addEventListener('load', () => { navigator.serviceWorker.register(scrUrl, {scope: '/'}).then(registration => { console.log('Service Worker registered: ', registration) }).catch(registrationError => { console.log('Service Worker registration failed: ', registrationError) }) }) } </script> <?php endif; ?> Next, by hook or by crook, get the workbox library into a directory of your PW project. You can use the CLI 'copyLibraries' feature. See https://developers.google.com/web/tools/workbox/modules/workbox-cli for more info. Do NOT use any of the other CLI features! You can also download the library from gitHub. Didn't go there so please don't ask for help. I used the CLI method & saved the files to site/templates/scripts/workbox. Now you can start building your sw.js file which is saved in root directory. Here's mine using the Google Workbox docs & recipes. The big thing to remember is NOT to "Import" anything despite what the docs say. When you configure workbox to use your local copy of the library, all importing is done for you by using the 'workbox' namespace. importScripts('/site/templates/scripts/workbox/workbox-v6.0.2/workbox-sw.js'); workbox.setConfig({ modulePathPrefix: '/site/templates/scripts/workbox/workbox-v6.0.2/', globIgnores: ['processwire/**.*'] // change according to your PW admin URL }); // Include offline.html in the manifest workbox.precaching.precacheAndRoute([ {url: '/offline.html', revision: null } ]); workbox.routing.registerRoute( ({url}) => url.pathname.startsWith('/processwire/'), // change according to your PW admin URL new workbox.strategies.NetworkOnly() ); workbox.recipes.googleFontsCache(); workbox.recipes.pageCache(); workbox.recipes.staticResourceCache(); workbox.recipes.imageCache(); workbox.recipes.offlineFallback(); These are all the basic workbox features & recipes including offline.html and will probably need updating as time goes by. Up to you to add/modify/delete as you like and outside the scope of this tutorial. Good luck & have fun with Google Workbox PWAs in ProcessWire sites.
  25. You can use padding/margins to tweak but first define your rows and columns so that they overlap where required. In the example below I have a text block partially overlapping an image. On small screens, the text overlaps at the bottom and on larger screens, the text is on the left and overlaps the image on the right.
Γ—
Γ—
  • Create New...