Leaderboard
Popular Content
Showing content with the highest reputation on 12/09/2022 in all areas
-
This is one of those rare weeks where I've got a lot of projects in progress, but all are in the middle, none are at a convenient Friday conclusion for this weekly update. In progress are some core updates, Pro module updates, other module updates, and a client project that's keeping me busy. So I don't have anything new or interesting to report this week, but I like to still check in and say hello, and let you know I'm not running low on coffee or anything like that. ? I hope that you have a great weekend!17 points
-
I wouldn't rely on this regex for mobile detection. There's a great library for that: https://github.com/serbanghita/Mobile-Detect You can simply copy the MobileDetect.php to site/templates/inc/MobileDetect.php. (If you prefer, you could install it via composer) And then include it in _init.php and use it like include_once('./inc/MobileDetect.php'); function isMobileDevice() { $detect = new \Detection\MobileDetect; return $detect->isMobile(); }5 points
-
Thanks very much @gebeer. I was uncertain how to manually install third-party scripts as I am not comfortable with Composer right now. I appreciate this explanation!3 points
-
Answering my own question in case it is helpful to anyone else. I am using Processwire and Rockfrontend. I was able to get a custom mobile detection to work using PHP by adding a custom function to _init.php (and taking care to comment out the PW namespace as per RF repo documentation). <?php // namespace ProcessWire; // Optional initialization file, called before rendering any template file. // This is defined by $config->appendTemplateFile in /site/config.php. // Use this to define shared variables, functions, classes, includes, etc. function isMobileDevice() { // Get the user agent string $userAgent = $_SERVER['HTTP_USER_AGENT']; // Check if the user agent matches any common patterns for mobile devices if (preg_match('/android|iphone|ipod|blackberry|iemobile|opera mobile|palmos|webos/i', $userAgent)) { return true; } else { return false; } } Then I was able to call the function in the normal way with Latte: {if isMobileDevice() == 'true'} ?3 points
-
@gebeer The period "." is an allowed character in page names, so it's fine to have URLs ending with ".html" ... you would just make the page name end with ".html". You'd probably want to turn off trailing slashes for the templates used by those pages as well. If all URLs end with "index.html" then ProcessWire will take care of those redirects for you automatically, i.e. "/about/index.html" automatically redirects to "/about/" (unless there is literally a page named /about/index.html). If you want to migrate away from using the .html extension, converting things like /about.html to /about/ throughout the site, then it could be done with a redirect rule in the .htaccess file. If you want to have PW respond to either /about.html or /about/ in the same way, then the most direct way might be to add a $_SERVER['REQUEST_URI'] = str_replace('.html', '/', $_SERVER['REQUEST_URI']); at the top of your /index.php file. Though make sure you've got a <link rel="canonical" ... /> tag in your <head> so that search engines don't consider the about.html and /about/ two different URLs.2 points
-
Thanks for your response @wbmnfktr … I am aware that these things can be done with css/js … I was more interested in trying something outside my familiarity with php. Here's a follow-up question: how can I write a custom function and access it in a template file in Processwire? Inside of _init.php I have added a user-agent regex for mobile detection <?php namespace ProcessWire; // Optional initialization file, called before rendering any template file. // This is defined by $config->appendTemplateFile in /site/config.php. // Use this to define shared variables, functions, classes, includes, etc. function isMobileDevice() { // Get the user agent string $userAgent = $_SERVER['HTTP_USER_AGENT']; // Check if the user agent matches any common patterns for mobile devices if (preg_match('/android|iphone|ipod|blackberry|iemobile|opera mobile|palmos|webos/i', $userAgent)) { return true; } else { return false; } } So why do I get: Call to undefined function isMobileDevice() when trying to access this function with inside of a .latte template: {if isMobileDevice()} I might be missing something very simple. This is some new territory for me. With thanks,2 points
-
I am using mobile detect to switch between different markups on mobile / desktop. For example on mobile I am using a different image format than on desktop devices. It would be much easier to make use of css media queries but in that case I do not want to load images that I do never display on a particular screen width. $imgFormat = 'title-img'; if ($deviceCheck->isTablet()) { // Tablet $imgFormat = 'title-img-tablet'; } --- and then: <img data-srcset="<?php echo $image->size($imgFormat)->srcset() ?> [...] Another example is the usage of html data attributes that vary on mobile/desktop devices: When using an animate on scroll plugin like aos.js you put your animation properties inside these data attributes. On desktop you might want animation A with duration X while on mobile you want animation B with duration Y. I set those properties via the mobile detect queries. <div class="feature-item-icon" data-aos="flip-right" data-aos-delay="<?= (!$deviceCheck->isMobile() && !$deviceCheck->isTablet()) ? $key*250 : '250'?>" data-aos-offset="200"> <img class="img-fluid" src="<?=$icon->url?>" alt="Feature Icon"/> </div> The major drawback is: the detection is server side. It is not responsive like css media queries where you see new properties instantly when switching through the breakpoints. Instead you have to reload the page to get the new values. In most cases this is no problem though.1 point
-
Hey guys could you please help me: Why would one detect mobile/desktop on the server side? Isn't that a thing for the frontend and with ProCache you can't use tools that rely on PHP. So could you please share some background? Thx ?1 point
-
Hi all, we are moving a site from TYPO3 to PW. The old site has all URLs end in .html. Is there a simple way to achieve this in PW without breaking things like urlSegments, pagination etc. ? It might be doable with a hook to Page::path but I think that will break urlSegments. Maybe instead of trying to achieve that goal it might be better to implement redirects. Has anyone done this before? Would be great to hear your opinions/experiences.1 point
-
Maybe a mutagen issue? Do you have mutagen enabled? Did you try stopping (or even deleting) the ddev project and then starting it again?1 point
-
This is the same UX issue I always encounter with "ProFields: Page Table" (aka FieldtypePageTable) as well. So far, I have only solved it for Page Table, but I guess you could do something similar in your case as well. I used JavaScript for the admin to clone the button, like this: /* * Adds a clone of the PageTable field's Add New button to the top of the table */ function clonePageTableAddButton() { $(".InputfieldPageTableButtons").each(function () { $myButtons = $(this); $myTableContainer = $myButtons.closest(".InputfieldPageTableContainer"); //Only add button when Table is not empty (length != 0) and no button has been added already (length < 2) if ($myButtons.closest(".InputfieldPageTableContainer").find(".AdminDataTable").length != 0 && $myTableContainer.find(".InputfieldPageTableButtons").length < 2) { $myButtons.clone().prependTo($myTableContainer); } }); } I also had to solve the issue what crops up when the Page Table is updated via ajax calls, so I had to implement a little bit more what I posted above, but if repeatable fields are not updated via ajax, then probably something no too complex to code should be enough to clone the button after the DOM is ready to be manipulated. Hope this helps.1 point
-
@r.loeber, I'm not sure why the "Default value" option that is available for most Page Reference inputfield types isn't available for Page List Select, Page List Select Multiple and Page Autocomplete, but I made a module that extends default value support to these inputfields:1 point
-
I don't know if this is the right place, it's not really a tutorial, just a tip based on notes I wrote myself in a recent project to get it straight in my own head. I thought it might be useful for others in a similar situation. Scenario: Create a search function that will search for keywords "foo" and "bar" in multiple fields, but the keywords do not have to be adjacent, in order, or even all in the same field. For eample, the selector must match if "foo" is in "field_a" and "bar" is in "field_b" -- so long as both keywords are present somewhere, the page match is valid. It is possible to just split the terms and do multiple queries on each field separately and then combine the results into a single PageArray for pagination (I believe there is a module that helps with this). However, I wanted to see if it was possible to do a basic version with a single query. Not The Solution: The following selector does not work when keywords appear separately in different fields (operator '~=' - contains all the words): $selector = "title|field_a|field_b~=foo bar"; What the selector is saying: FIND BOTH "foo" AND "bar" IN title OR FIND BOTH "foo" AND "bar" IN field_a OR FIND BOTH "foo" AND "bar" IN field_b In this case, both "foo" and "bar" have to be in the same field (but not adjacent or in order) to match. The Actual Solution What we need to use is "named selectors" to let us match each individual keyword separately while still using one selector. Using the same example as before: $selector = "selector1=(title|field_a|field_b~=foo), selector2=(title|field_a|field_b~=bar)"; What the selector is saying at its most basic level: FIND BOTH selector1 AND selector2 Or, to expand on this, it is saying: (FIND "foo" IN title OR field_a OR field_b) AND (FIND "bar" IN title OR field_a OR field_b) Crucially, "foo" and "bar" do not have to be in the same field to match. Practical Method In this example code, I am actually allowing the search for phrases (using "quoted text") as well as individual terms, so a person could enter... "foo bar" baz ... and it will keep "foo bar" together aa one term and "baz" as a separate term and match them as an exact phrase. // Keywords obtained from $input->get and cleaned (multiple spaces removed)/sanitized etc. $keywords = '"foo bar" baz'; // Split into individual search terms by space (preserve spaces in quoted text) $terms = str_getcsv($keywords, " "); // array("foo bar", "baz") // Build up named selectors $ns = ""; // named selectors string $i=1; // named selector count foreach ($terms as $term) { // operator '*=' - contains the exact word or phrase $ns .= ", ns{$i}=(title|field_a|field_b*=" . trim($term) . ")"; $i++; } //$ns = ", ns1=(title|field_a|field_b*=foo bar), ns2=(title|field_a|field_b*=baz)" // Construct the whole selector (modify/add other general selectors as needed) $selector = "template=my-template, limit=20, sort=-date" . $ns; // Find pages based on selector $results = $pages->find($selector); DISCLAIMER I haven't done any tests to see if this method is more efficient than running queries on each field separately and combining the results, I just wanted to see if it was possible!1 point
-
I have seen that error when fieldtype doesn't match input or a required field is empty, but it generally informs me what field was the problem (with a big old red notice on top of the field too). So that's weird that you're not getting any description of the problem. If you haven't added any of your own fields to the user template and have checked/double-checked the input of every form, here is what I would do : 1. turn on debug in /site/config.php and see if it gives any extra information 2. If that fails, search the code to see where it outputs that error. (Only one place: https://github.com/ryancramerdesign/ProcessWire/blob/676458407bd530b69b50c6ef2f44cf16e4ef4449/wire/modules/Process/ProcessPageEdit/ProcessPageEdit.module#L211) Based on that it's safe to assume you have some formErrors. Look a few lines before that (L195), I would temporarily change $formErrors = 0; foreach($this->notices as $notice) { if($notice instanceof NoticeError) $formErrors++; }to $formErrors = 0; foreach($this->notices as $notice) { if($notice instanceof NoticeError) { $this->error('Notice: '.$notice); $formErrors++; } } That might give you a clue about the notice that is causing a formError. Once you get that info (or even if you don't), you should undo the changes you made to the module file. Anyway it's a hack, but it's how I sometimes investigate what is happening...1 point
-
That is strange. I am using the same library for years now (http://mobiledetect.net/), on PHP 8+ i have no problems. Depending on where you put the mobile-detect files I have this in my _init.php: require_once '../../vendor/mobiledetect/mobiledetectlib/Mobile_Detect.php'; $deviceCheck = new Mobile_Detect; Then I can use the following expression to check the device. For example in a PHP template file. if (!$deviceCheck->isMobile()) { echo "this is not mobile"; }0 points