Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by teppo

  1. To be fair I believe we're on the same page here, except for one detail: those module — Seo Maestro and Markup Metadata — are actually two very different solutions. In fact what you're describing is exactly why we use Markup Metadata by default in our projects: there's no GUI, and a big part of the markup is based on globally defined values or values from (pre-existing) page fields. It's just a markup module for handling the repetitive task of rendering a standard set of metadata elements, correctly and consistently, from project to project. That being said, in my experience some people prefer a more complex approach, either because they actually need it or because they think they do — and if a client was specifically requesting feature set similar to that of Yoast, a solution such as Seo Maestro might be just what you need to convince them that they don't need to go with WordPress just for that 😉
  2. Same. I also tend to bundle these with fields for open graph metadata, option to override page title separately, and whatnot. You might want to check out module solutions if you haven't yet. Seo Maestro is a neat one, and MarkupMetadata is what we use for our web projects (though latter one doesn't provide a GUI for content editors, it's just for generating proper markup). My experience is similar: the content analyzing features of Yoast have never been particularly useful for me, in part because I've mostly worked on non-English sites where they don't seem to work so well. Also these reports seem to — at best — provide a rough estimate of how good your content might be, and (in my opinion) there are better tools for that. If your clients are often interested in doing "hardcore SEO", I'd definitely dig into such external tools and see if there are some that you can recommend instead. Yoast does have some nice features for working around WP's shortcomings, and I've found their "helper" tools (such as breadcrumb creation) pretty handy in the past. ProcessWire, on the other hand, makes things like breadcrumbs and canonical links trivial, and the structure is often so straightforward that you don't actually need to do a whole lot to make your site "SEO friendly". One thing to note is that Yoast actually does handle "modular pages" relatively well. Last I checked it required a separate plugin and only worked if your content was all visible in the editor. My understanding is that it just mashed it all together and then did it's magic. A little crude perhaps, but in many (most?) cases this provides decent results 🙂
  3. Awesome! ... well, not awesome that the DNS was messed up, but you know, awesome that they got it solved — eventually 😉
  4. Hope they can help. If I got this right and the name server doesn't know the domain, this definitely sounds like a DNS issue. Though I may have misunderstood what you meant here. Just for the record what I meant by "Linode changing something" was just whether they might've changed the IP of the server, or something along those lines. Though if your other domains point to the same domain and have identical DNS records, that'd be an unlikely scenario. Anyway, this is very much just guesswork. If you don't get answers from namecheap but can share the domain name with us (or via PM), I could also take a look. Sometimes two pairs of eyes see more than one, etc. 🙂
  5. Most likely a silly question, but are you certain that the DNS records point to the correct address? Linode didn't change anything regarding these when they upgraded the server? If you check the records for this site manually (host -t A www.yourdomain.com, or nslookup -type=A www.yourdomain.com if you're on Windows), are they correct? Also: if you try the domain with a service like https://isitup.org/, does it work there? Just trying to figure out if it's an issue with your environment, or a more widespread thing 🙂
  6. See the API post: $image->pim2Load('wm')->removePimVariations() should do it, though you'd want to make sure that you don't leave this code in place longer than you need it (probably won't do a lot of harm, but it'd be pointless). I'm not sure if pim stores the images as regular variations, but if it does, you can also remove them by hand from the admin (edit the image and you should see variations somewhere in the GUI). I wouldn't worry too much about those old variations, though. Most likely you haven't generated so many of them that they'd take considerable space on the disk, and anyone opening them accidentally is also quite unlikely.
  7. It seems to me (based on a very quick glance at the code) that both 'center' and 'c' are acceptable. Could you try setting it to 'center', then removing the generated image variation, and then loading the page again? My initial guess would be that the image is not changing since you're getting the previously created image back. Alternatively you can provide a different prefix value for pim2Load; something like pim2Load('wm2', [...]).
  8. Right — seems like it's an issue with formatting, i.e. single quote gets escaped (converted to HTML entity). Try $sanitizer->selectorValue($page->getUnformatted('title')) instead, that should work.
  9. Have you tried running the title through $sanitizer->selectorValue()? That's what you should be doing anyway, passing "raw" values to selectors is never a good idea — even if said value comes from a field on the page 🙂
  10. To my best knowledge there's no easy way around this, except for not using the MultiPHP Manager in the first place... which might not be an option for your use case 🙂 Some (possibly awful) ideas you could try: Perhaps you could disable overriding PHP settings via htaccess on your dev server by defining more restrictive AllowOverride option in your virtual host? AllowOverride also works on a per-directory basis, so I believe you could disable these for this particular site only, in case you're hosting multiple sites on this environment. How 'bout manually creating matching directory (/var/cpanel/php/sessions/ea-php72) on your dev server for storing sessions for this site? It sounds to me like cPanel will make these modifications automatically. If it also remembers all values somehow (in database or some other config file) and then repopulates them on first request or something, perhaps you could manage just one version and let cPanel work it's magic automatically after deployment? Not sure if that's exactly how it works, and whether that's feasible in the first place also depends on what your dev/deployment workflow looks like... 🙂 It'd be great if the folks at cPanel provided some way to decide where specifically these rules should go, but I guess that'd be a new feature request. Based on some googling it also looks like when they introduced the automatic modification part, they broke quite a few sites in the process. Not cool 🙄
  11. Not plain PHP, but there are a couple of ProcessWire modules that can help you here: Page Image Manipulator 2 has multiple methods for watermarking images. AvbImage provides a method called insert(), which (to my best understanding, haven't used it myself) applies another image on top of the first one (so, basically, creates a watermark).
  12. Hey @joshua! Would you consider making this module installable via Composer? Technically this just requires a) adding a composer.json file where you specify project name, type ("pw-module"), and a dependency for installer plugin (preferably wireframe-framework/processwire-composer-installer), b) adding the project to packagist.org, and c) (optional, but recommended) setting up a webhook between GitHub and Packagist so that new releases become automatically available at Packagist (or giving Packagist the permission to handle this step). Here's an example composer.json from ProcessRedirects: https://github.com/apeisa/ProcessRedirects/blob/master/composer.json. Thanks in advance for considering this 🙂
  13. I've had similar issues with Chrome (probably because that's the only browser I really use) many times over, though not sure if it's ever occurred with a ProcessWire site. From your description it seems quite likely that "something" in the browser itself gets stuck — I'm really not an expert here, but again it's happened a number of times for me, and only things that seem to help are a) waiting until it goes away (could be a long wait), or b) rebooting the browser. Pretty much just guessing here, but I'd suspect either some sort of JavaScript issue, a problem with a browser extension, some sort of network issue, or perhaps some piece of software installed locally. Ad blockers, for an example, are known to cause browsers to freeze, but typically only under some very specific conditions. (I've also helped clients debug some pretty weird issues cause by firewalls or virus scanners.) Probably not very helpful, sorry; if you can see any console warnings or such please let us know, that'd make debugging much easier 🙂
  14. I've had this issue on some occasions, though for me it's been more like "sometimes it works, sometimes it doesn't", rather than not working for some pages at all. Never could really debug what it was all about since these have been very random occurrences, but your guess about some sort of JavaScript conflict seems reasonable. I've not had a proper look "under the hood" but I believe that front-end editing works by essentially duplicating your content behind the scenes, so the issue could also have something to do with the structure of the pages in question. Do they differ somehow from the pages where this works as expected? When this happens, do you see any JS errors in the dev tools console? Do you have any particular JS libraries etc. loaded — jQuery and the likes? Also, which editing option are you using and which version of ProcessWire do you have installed? Sorry for the load of questions — I'm really not sure what could cause this, but perhaps we can at least narrow it down a bit 🙂
  15. Hey @bernhard! Thanks for reporting this. The latter problem is connected to the first one. Config screen asks the main module for the paths object, but due to a recent change this wasn't available. This is fixed now in the latest version of the module (0.17.1).
  16. This was from browser, so some network latency was included in that number. If I check the render time from the site, it's roughly the same, average being somewhere around 1s. I'm looking at the numbers provided by Tracy for a logged in user, so the higher time is explained by the stuff that doesn't apply to visitors (admin tools, Tracy itself, etc.) Don't have a great testing setup for non-cached visitor execution time 🙂 ProCache is always disabled on POST requests, GET variables and cookies that bypass cache are configurable. I tend to rely on just the normal invalidation cycle — I have reasonably short cache time configured, so I don't have to clear the cache manually / programmatically very often. Depends on the use case, of course; for most regular websites it really doesn't matter if the data is 15..30 minutes old, even if it's of the "rapidly updating" sort. It's easy to flush the cache with PHP, though: see https://processwire.com/api/ref/pro-cache/ for more details. As for the "try before you buy" part, I don't actually know if there's such an option. You could try contacting Ryan 🙂
  17. Those numbers seem pretty normal. Just for comparison: The doc (HTML) part of a fairly complex site I recently finished takes ~600-900ms when I'm bypassing ProCache. This is from browser, though, so could be a bit different from what you're measuring (not sure how exactly you got these numbers). With ProCache I'm getting consistent < 100ms. ProCache serves content directly from disk (via Apache), bypassing PHP and database, so it's naturally quite a bit faster. Took a cursory glance at a couple of (also relatively complex) WordPress site that I know for a fact are well built and hosted on pretty powerful hardware, and load times for these were somewhere between ~1.5-3 seconds uncached, 200-400ms cached (static cache using nginx, I believe). In my opinion 1-3 seconds would still be "pretty good" for just about any ProcessWire or WordPress site without proper caching. Anything below 4-5 seconds is in the "pretty normal" range, while 5-10 seconds is just plain wrong (but sadly not that rare). 5+ seconds is usually a sign of really bad hosting, or really bad implementation 🙂 Might be worth noting that, in my experience at least, PHP is rarely the real bottleneck: if the server returns the markup in a few hundred milliseconds but then there's blocking JavaScript, CSS, or perhaps a large image that takes hundreds of milliseconds to seconds at worst to finish loading and/or executing, it would be better to focus on that. Just saying; developers (including yours truly) have a tendency to focus way too much on shaving milliseconds off one end, even if at the other end it might be possible to shave off seconds 😛 Template cache loads the page from the disk and doesn't execute any of your markup generating code, but it still has to go through ProcessWire, so there's definitely some overhead there compared to ProCache. How beneficial template cache is (in comparison to non-cached site) depends a lot on how complex the site is and how well it's already optimized. Kind of covered this already, but to reiterate: it would definitely make a difference. ProCache is usually low maintenance, but this depends a bit on how your content is generated — such as whether it's all from stored with/in ProcessWire, or if you have parts that are loaded (especially with PHP) from other sources. Typically ProCache gets flushed based on predefined rules when pages are saved, so if your content isn't stored on pages, that could be a potential issue. In which case you may even need to programmatically flush it (via cron or some other method). You can configure the preferred lifespan, so technically you can make ProCache stick to cached data almost indefinitely, and thus ProcessWire/ProCache will very rarely need to regenerate it. Though, again, in my opinion this is something that folks tend to pay too much attention to: if your typical page render (non-cached) takes 1-3 seconds at most and your cache hit ratio is 99+%, cache warming has so little actual effect that it's (in my opinion) mostly just wasted time and effort 🙂
  18. It seems to me that the only case when we'd want mb_decode_mimeheader() to run is when the header is encoded, in which case it's always base64 or quoted-printable (AFAIK), and these are always (US-)ASCII. I'm not aware of any notable issues with current approach, though; most likely the "worst case" is that you'd pass something that doesn't need decoding to mb_decode_mimeheader(), and it seems like a major coincidence if this operation actually ends up scrambling the data. Anyway, the gist is that if we're looking for ASCII strings, it's better to be specific 🙂
  19. Moderator note: Modules/Plugins section of the support forum is reserved for dedicated third party module support threads. For the time being I'm moving this thread to the General Support area of the forum. Note that Padloper also has a separate support area on the forum, accessible for existing users with a valid license; you should post Padloper questions to said support area to make sure that they get noticed by the module author(s). As for your question: the Padloper website mentions PayPal and Stripe payment modules. If there are other payment methods, at least they are not listed on the site. As for shipping methods, there's not much information out there — I'd definitely recommend posting this question to the Padloper support forum. If you have a valid license but don't have access to said support forum, please contact the module author.
  20. Users are not typical pages, so you should use wire()->users->find() instead. Or, alternatively, you can use wire()->pages->find('template=user, id=..., check_access=0').
  21. There are a few problems with that code: Switching $magazine to $page doesn't actually help at all. $page is not defined here either. As I mentioned in my previous post, you're in function context, and in that context you only have access to a) function arguments ($event), b) variables you've made accessible with "use" (currently there are none), and c) global functions. $page is none of those. Another issue is that there's no savedPageOrField method for Inputfield, so Inputfield(...)::savedPageOrField is never triggered — what you're looking for is Pages::savedPageOrField. From your post I assume that you've put this code in the template file, i.e. /site/templates/your_template_name.php? If so, the hook only applies to when you're viewing a page using that template, i.e. it has no effect in Admin. I'm not sure if that's what you really intended, but I'd assume not — more likely you'd want to put this hook somewhere it gets added in the admin as well, so perhaps /site/init.php or /site/ready.php. ... and, finally, even if your code did work, you would've likely ran into an infinite loop: if you hook into page save and save the page, that'll trigger the page save hook, which will then save the page and trigger the page save hook again, which... you know the drill. Pages::saveReady() is often better method to hook, as you can just modify the page values, and they'll get saved soon after (you don't have to call save in your hook) 🙂 In this case something along these lines could work: // hook into Pages::saveReady $wire->addHookafter('Pages::saveReady', function($event) { // get current Page object — in this case this is the first argument for the $event object $page = $event->arguments[0]; // bail out early if current Page *doesn't* have the field we're interested in if (!$page->template->hasField('snipcart_item_image')) return; // ... and also bail out early if the snipcart_item_image field hasn't changed if (!$page->isChanged('snipcart_item_image')) return; // now that we know that snipcart_item_image has changed, set a custom value to another field $page->set('imagecolorat', 'YOUR_NEW_VALUE_HERE'); // finally, populate our modified $page object back to the event $event->arguments(0, $page); }); Note: written in browser and not properly tested.
  22. I know you mentioned docs being confusing, but I'd still suggest taking another look at them — specifically this part, as it explains this pretty clearly: https://processwire.com/docs/modules/hooks/#defining-hooks. To simplify things a bit... the key difference between the first two is that $wire->addHookAfter() works outside classes, while $this->addHookAfter() is how you'd usually attach the hook when you're in a method of a class (i.e. while you're working on a module of your own). $page->addHookAfter() attaches the hook to the current Page object (which $page typically refers to), not all Page objects in general. Important distinction in case you're working with multiple pages and don't want your hook to run for all of them. Not sure if that explains it any better than the docs, but again the biggest difference is just the context in which you're defining the hook (use $wire when in template files, /site/init.php, /site/ready.php, /site/admin.php, etc. and $this when you're within a method in a class) and whether you want your hook to apply to a single object ($page, $pages, or a specific item such as $mypage where $mypage = $pages->get('some_selector')) or all items of a specific type. Most commonly you'll need your own hookable methods when you're, say, developing a reusable module. Instead of tweaking the module on a per-site basis, you'll likely want to keep it as-is and rather make some minor modifications by hooking into it's methods. This way you can easily update the module without having to redo or work around your modifications every single time. On some edge cases you might have a utility function on the site, and then depending on some other event you may want to say that "at this specific instance the method should do something else", so you'd want to make it hookable. Can't think of many cases where that'd make sense, though. I'm not sure what you're getting at here. Is this is just an example of what you're doing at the moment? Either way your hook looks fine to me. Should've read this more carefully. You're accessing $magazine object here, but if this is your entire code, that won't work — you're not defining $magazine variable anywhere. Since you're in function scope, you only have access to the arguments passed to that function, variables you've passed in with "use" language construct, and global functions. Even if $magazine exists outside your function, you'd have to pass it in with function($event) use ($magazine) { ... } That being said, what you're probably looking for is something like Pages::savedPageOrField(). If you take a look at that docs page, there are code examples dealing with changes etc. Or, alternatively, Pages::savePageOrFieldReady(), which occurs right before the page/field is saved (which means that you can modify the values right before they are saved to the database). ... and please let me know if I missed your point here 🙂
  23. Definitely this one. Unless the translator has very specific requirements (i.e. they intend to import the file into some sort of app), CSV export/import is by far the most effortless approach for all parties involved 🙂 Edit: purely out of curiosity tried to run a conversion from ProcessWire's JSON format to other formats (such as PO, the format typically used by WP translation plugins — .wordpress is a new one for me, so not sure if they meant this, or if that's just something I haven't come across yet) using https://localise.biz/free/converter, and it seemed to work fine. Though would need to test properly to make sure that the process is also easy to reverse, and the result can be imported properly. Conversion done this way would be a bit of a pain, though, since you'd have to convert each file one by one. Unless you happen to have most of your translations in a single file or something like that. Seems like there are decent libraries for this available as well, so a conversion tool would be relatively simple to set up, but again for a one-off case that'd be a lot of extra work 😅
  24. It seems that whatever route you take, the memory / performance optimization approach would eventually run off the cliff. I mean... it's just not scalable. So, trying to think outside the box for a moment: When you say that "Snipcart returns to your page", what does that mean specifically? Does it perform a GET/POST request against the page? If so, is there any chance that it would provide enough information for you with that request to actually generate a smaller subset of prices used in that specific order? This would technically shift the responsibility for the validation step from Snipcart to your site, but it also seems like something that could scale much better 🙂 Anyway, just throwing in ideas.
  25. Sorry, this is not my area of expertise either. Used to deal with that a lot, but thankfully no longer — switching all email sending features to use services like Mailgun has made my life so much better 😉 Anyway, your solution seems reasonable. Only thing I'm wondering is whether it'd be better to specifically check for ASCII encoding with mb_detect_encoding(), instead of "not UTF-8"? It's a really small nuance, though.
  • Create New...