Leaderboard
Popular Content
Showing content with the highest reputation on 11/22/2019 in all areas
-
ProcessWire 3.0.146 contains about 22 commits (relative to 3.0.145) and these commits are largely focused on resolving reports from the processwire-issues repository. However, there have also been several improvements and related additions. One of these additions was a foundational upgrade that adds support for Fieldtype modules to use a custom class for Field objects. This will open more possibilities for improved Field/Fieldtype-specific APIs. Several have asked for improvements in the APIs of Repeaters and other fields, so this is a step that begins the lay the tracks for moving in that direction. Traditionally the API calls for working with Fields and Fieldtypes have not been nearly as simple as those that work with Pages, so this will be an upgrade that narrows and eventually eliminates that gap, longer term. On the core side, I currently plan on using this to improve the API for Repeaters, Comments and Options fields, and perhaps others. Outside of the core, ProFields will eventually take advantage of custom Field objects as well. As usual, none of this will break any existing code, but it will add simplicity for those that work with Field/Fieldtype APIs in ProcessWire. As for other changes in 3.0.146, I think last week’s ProcessWire Weekly did a great job of covering them, so if you are interested be sure to check that out. Next week is partially a holiday week here in the US, so I’ll be on a little bit of a reduced schedule, but will still be working on the core. I’m also releasing a new module into the ProDevTools set of modules next week, so I’ll tell you more about that one in next week’s blog or forum post. Thanks for reading and have a great weekend!13 points
-
Hello. I'd somewhat rewritten WireMailMailgun a while back, to implement some more features and implement PW coding guidelines etc. My version has been somewhat in limbo, although there's been various discussions in the thread linked above. I've decided to release my version as a separate module called WireMailgun, as it has breaking changes and a slightly different implementation. I've also got it using the email validation v4 endpoint. For simple usage, either module will do what you need it to do. If you need to do some more advanced things e.g inline images or adding data, this module will help you with that. Here's the readme... WireMail Mailgun Extends WireMail to use the Mailgun API for sending emails. Installation Download the zip file at Github or clone the repo into your site/modules directory. If you downloaded the zip file, extract it in your sites/modules directory. In your admin, go to Modules > Refresh, then Modules > New, then click on the Install button for this module. API Prior to using this module, you must set up a domain in your Mailgun account to create an API key. Add the API key and domain to the module's settings. Usage Usage is similar to the basic WireMail implementation, although a few extra options are available. Please refer to the WireMail documentation for full instructions on using WireMail, and to the examples below. Extra Methods The following are extra methods implemented by this module: Chainable The following methods can be used in a chained statement: cc(string|array|null $email) - Set a "cc" email address. Only used when $batchMode is set to false. Please refer to WireMail::to() for more information on how to use this method. bcc(string|array|null $email) - Set a "bcc" email address. Only used when $batchMode is set to false. Please refer to WireMail::to() for more information on how to use this method. addData(string $key, string $value) - Add custom data to the email. See https://documentation.mailgun.com/en/latest/user_manual.html#attaching-data-to-messages for more information. addInlineImage(string $file, string $filename) - Add an inline image for referencing in HTML. Reference using "cid:" e.g. <img src='cid:filename.ext'> Requires curl_file_create() (PHP >= 5.5.0) See https://documentation.mailgun.com/en/latest/user_manual.html#sending-inline-images for more information. addRecipientVariables(array $recipients) - Add recipient variables. $recipients should be an array of data, keyed by the recipient email address See https://documentation.mailgun.com/en/latest/user_manual.html#batch-sending for more information. addTag(string $tag) - Add a tag to the email. Only ASCII allowed Maximum length of 128 characters There is a maximum number of 3 tags allowed per email. addTags(array $tags) - Add tags in a batch. setApiKey(string $apiKey) - Override the Mailgun API Key module setting. setBatchMode(bool $batchMode) - Enables or disables batch mode. This is off by default, meaning that a single email is sent with each recipient seeing the other recipients If this is on, any email addresses set by cc() and bcc() will be ignored Mailgun has a maximum hard limit of recipients allowed per batch of 1,000. Read more about batch sending. setDeliveryTime(int $time) - The (unix)time the email should be scheduled for. setDomainName(string $domain) - Override the "Domain Name" module setting. setRegion(string $region) - Override the "Region" module setting. Valid regions are "us" and "eu" Fails silently if an invalid region is passed setSender(string $domain, string $key) - Set a different API sender than the default. The third argument is $region which is optional A shortcut for calling setDomainName(), setApiKey() and setRegion() setTestMode(bool $testMode) - Override the "Test Mode" module setting. setTrackOpens(bool $trackOpens) - Override "Track Message Opens" module setting on a per-email basis. Open tracking only works for emails with bodyHTML() set setTrackClicks(bool $trackClicks) - Override "Track Message Clicks" module setting on a per-email basis. Click tracking only works for emails with bodyHTML() set Other send() - Send the email. Returns a positive number (indicating number of emails sent) or 0 on failure. validateEmail(string $email) - Validates a single address using Mailgun's address validation service. Returns an associative array. To return the response as an object, set the second argument to false For more information on what this method returns, see Mailgun's documentation. getHttpCode() - Get the API HTTP response code. A response code of 200 indicates a successful response Examples Basic Example Send an email: $mg = $mail->new(); $sent = $mg->to("user@domain.com") ->from("you@company.com") ->subject("Message Subject") ->body("Message Body") ->send(); Advanced Example Send an email using all supported WireMail methods and extra methods implemented by WireMailgun: $mg = $mail->new(); // WireMail methods $mg->to([ "user@domain.com" => "A User", "user2@domain.com" => "Another User", ]) ->from("you@company.com", "Company Name") ->replyTo("reply@company.com", "Company Name") ->subject("Message Subject") ->bodyHTML("<p>Message Body</p>") // A text version will be automatically created ->header("key1", "value1") ->headers(["key2" => "value2"]) ->attachment("/path/to/file.ext", "filename.ext"); // WireMailgun methods $mg->cc("cc@domain.com") ->bcc(["bcc@domain.com", "bcc2@domain.com"]) ->addData("key", "value") // Custom X-Mailgun-Variables data ->addInlineImage("/path/to/file-inline.jpg", "filename-inline.jpg") // Add inline image ->addTag("tag1") // Add a single tag ->addTags(["tag2", "tag3"]) // Add tags in a batch ->setBatchMode(false) // A single email will be sent, both "to" recipients shown ->setDeliveryTime(time() + 3600) // The email will be delivered in an hour ->setSender($domain, $key, "eu") // Use a different domain to send, this one in the EU region ->setTestMode(true) // Mailgun won't actually send the email ->setTrackOpens(false) // Disable tracking opens ->setTrackClicks(false); // Disable tracking clicks // Batch mode is set to false, so 1 returned if successful $numSent = $mg->send(); echo "The email was " . ($numSent ? "" : "not ") . "sent."; Validate an Email Address $mg = $mail->new(); $response = $mg->validateEmail("user@domain.com", false); if($mg->getHttpCode() == 200) { echo $response->result == "deliverable" ? "Valid" : "Not valid"; } else { echo "Could not validate"; } I hope it is useful! Cheers, Chris5 points
-
Haha, I spent last week working on a GraphQL API module built upon the webonyx library! Not wasted time though, I think I've probably implemented a few things that would be welcome additions (e.g. WireCache for $pages->find()). When I get a chance I'll have a look at the new version of this module and see whether I can suggest any additions. Cheers, Chris4 points
-
If I use Tracy to do a test dump in FieldtypePage::wakeupValue (which is where the stored IDs are loaded into a PageArray) then it seems that this method executes regardless of the visibility of the field in Page Edit. And it's not Page Edit that's the main problem anyway. If you have a field then presumably you want to work with that field, but whenever you do... $page->my_pr_field ...then all the pages are loaded to memory. So for instance if you want to add a page via the API... $page->my_pr_field->add($p) ...then you are automatically loading all the pages to memory. @bernhard's suggestion and @teppo's module are good workarounds but I think it's important to get a core solution to this. PW has an "everything is a page" philosophy, so pages can be any unit of data, not necessarily a viewable page of content. And Page Reference fields are the fundamental way to make connections between pages in PW. So when you have thousands of pages that need to have connections to thousands of other pages then you have to start looking beyond the core fieldtypes which is a limitation for PW. Sometimes you can do what @wbmnfktr suggested and reverse the connection, putting the PR field in the other template to reduce the number of pages stored per field. But this isn't always possible. In terms of concrete examples, imagine you were using PW to build some kind of Spotify-like database that tracks users' listening habits. There could be thousands of users who listen to thousands of songs, so either way you cut it you want to store thousands of pages in a PR field.3 points
-
Just for the record (not saying that it would be the best solution overall), FieldtypePageIDs also has certain benefits if/when the problem is loading too many Page objects into memory. It could be worth looking into in this sort of situation ?3 points
-
I have a spare computer laying around so I did a fresh install of Windows and installed Laragon. I must say, it is very slick, feature rich and I can understand the appeal... it just works and has a lot of useful magic (such as auto virtual hosts and easy SSL setup).2 points
-
@AndZyk, a Page Reference field doesn't scale well because all pages are loaded into memory and there is no ability to limit the loaded pages or paginate the inputfield in admin. Back in 2016 Ryan said it was likely that pagination would be added to several core fieldtypes but it hasn't happened yet: https://processwire.com/blog/posts/fieldtype-pagination/ The Page Reference fieldtype/inputfield is the one that would benefit the most from this. I have an open request for this that you could add your voice to: https://github.com/processwire/processwire-requests/issues/132 points
-
Hey @teppo and @d'Hinnisdaël – both very good ideas indeed. I'm happy to implement both hooks, the only problem is that this time of year is super busy for me, so I won't be able to get to it straight away. If it's something you're looking for in the immediate-term, please feel free to pop me a merge request or two. In the meantime, I'll open up an issue on the repo. ?2 points
-
I'd build a custom DB table that holds the id of the page and the id of the user that visited that page. page | user -----|----- 1 | 41 2 | 41 3 | 41 Get all pages that have been visited by the admin? SELECT page FROM visitedpages WHERE user = 41 Get all users that visited page 1? SELECT user FROM visitedpages WHERE page = 1 Executing custom SQL is as easy as that: Thousands of pages? No Problem ? Thousands of users? No Problem ? PS: If you only want an array of all page ids:2 points
-
I can't reproduce that here. If you insert an image without the caption checkbox checked then the plugin inserts an image with the class applied and doesn't insert a wrapping figure element. <p><img alt="" class="align_right" src="/site/assets/files/1/colin-watts-1141600-unsplash.300x0-is.jpg" width="300" />Lorem ipsum dolor sit amet, adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec faucibus. Nunc iaculis suscipit dui.</p> If you insert an image with the caption checkbox checked then the plugin inserts a figure + img + figcaption with the class applied to the figure element. <figure class="align_right"><img alt="" src="/site/assets/files/1/colin-watts-1141600-unsplash.300x0-is.jpg" width="300" /> <figcaption>Your caption text here</figcaption> </figure> <p>Lorem ipsum dolor sit amet, adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec faucibus. Nunc iaculis suscipit dui.</p> Something to be aware of is that if you change the alignment classes for Page Edit Image from their defaults you need to allow those classes in the Extra Allowed Content setting for the CKEditor field. img figure(is-pulled-left,is-pulled-right) It would be better if the class names configured in Page Edit Image were automatically allowed - there's an open issue about this: https://github.com/processwire/processwire-issues/issues/8001 point
-
1 point
-
Note to self: When creating tags, be sure to actually click on "Create Tag" ? Please try again ?1 point
-
@adrian – I'd be happy to. I see from a previous discussion with Teppo that the priority was set due to a conflict with sitemaps. That being said, I do believe there is a measure in place to circumvent sitemap.xml URIs from being logged, so as a result, I don't see why we can't change the hook and priority. At the end of the day, it kinda makes sense. Modules that need to do things with 404 events should be given the opportunity to do so before JL comes in as a last resort. So I'm going to go ahead and do this – if anyone encounters any issues, we'll need to deal with them on an as-and-when basis.1 point
-
Setting the icon markup of the wrapper does not work, because this also affects all following inputfields and always sets the same icon on all inputfields. This is what I came up with now: // add method to set icon of inputfield manually $this->addHook("Inputfield::setIcon", function($event) { $field = $event->object; $name = $field->name; $icon = $event->arguments(0); $field->parent->addHookAfter('render', function($event) use($name, $icon) { $search = " for='Inputfield_$name'>"; $event->return = str_replace( $search, $search."<i class='$icon'></i> ", $event->return ); }); }); Usage is even simpler: $field->setIcon('fad fa-link');1 point
-
I'm glad you believe @Robin S if you didn't want to believe me ? Just create a custom $page method that does your logic, then you have your own performant API. That should get you started: $wire->addHook("Page::readByUser", function($event) { $result = $this->database->query("SELECT id,templates_id FROM pages LIMIT 5"); $ids = $result->fetchAll(\PDO::FETCH_OBJ); $user = $event->arguments(0); d("check for user $user"); $event->return = $ids; }); d($page->readByUser($user));1 point
-
The issue has been fixed! FYI https://github.com/processwire/processwire-issues/issues/10311 point
-
Hi, I see Mailgun have updated their API to version 4. I'm going to implement this then submit my version to the directory as a separate module - no idea what to call it though... maybe WiremailMailgunApi. Cheers, Chris EDIT: turns out that it is only the email validation that's been updated to version 4...!1 point
-
Here I made a little example with a simple CSS transition: https://jsfiddle.net/x8gwrbys/ I have Autoprefixer in CodeKit for all those prefixes, so I don't have to write any prefix again. I can really recommend it. But for example transform is now a few years old and well supported, so you don't have to write prefixes for transform anymore. JavaScript for animating is not bad. But CSS animations have in general a better performance. For small animations there is not much of a difference, but on heavy animations you can really slow down a computer with JavaScript animations in my experience. ?1 point
-
Hi guys, Super sorry for not getting back to you – much like @kongondo, royally swamped (this time of year). First off, I'm battling to understand why folks are having install/upgrade troubles here. Whilst JL1 doesn't use a full-on DB migration strategy, it does have an iterative cycle. If you're on schema v4 and upgrade to the latest version, it should be doing v5 and then v6. Only thing I can think of then is that the schema version got messed up somehow. It gets saved in the module’s config, so I really don't see what could have messed it up (I recently formatted those files, but naturally that should not make a difference). I'd need to try reproduce this to see what might be going on. As an aside, JL2 will use DB migrations, so this issue would less likely be encountered unless the applicable tracking table was truncated. Hoping to get JL2 wrapped up over the holidays (lots of leave-days, no big plans). @adrian – I see PagePathHistory doesn't set its own priority, and JL does. I recall doing this for a reason, but given what you've said, perhaps JL should be somehow setup to be the 'last resort'? @teppo – Given the schema errors that are being experienced, I think that for the time being, I'm going to simply truncate the string that gets stored to 512 characters. Also a little confused by the 404 logger – it really should not be doing anything if turned off. I do see that it only logs the 404 if there are no jumplinks – I'll definitely fix up that part. Update: I've pushed out 1.5.58 - please let me know if the DB errors stop. Thanks!1 point
-
Yes. If you want the hook to apply to a specific Lister Pro instance instead of a bookmark you could do this: $wire->addHookBefore('ProcessPageLister::execute', function(HookEvent $event) { /* @var ProcessPageLister $lister */ $lister = $event->object; // If executing a specific Lister Pro instance if($event->wire('page')->name === 'your-lister-page-name') { // Find the templates that contain the meta_title field $tpls = new TemplatesArray(); foreach($event->wire('templates') as $template) { if($template->flags) continue; // Skip system templates (e.g. repeater templates) if($template->fieldgroup->has('meta_title')) $tpls->add($template); } // Set the defaultSelector for the Lister $lister->defaultSelector = "template=$tpls, meta_title=''"; } });1 point
-
@Wanze – congratulations for version 1.0.0 and a big thank you! @adrian: i've got it working now to correctly display the og:image in admin view – below the hook with inheritance mode as follows: if page og:image is empty, travel up tree until there is one at closest parent, use this. If no og:image found until home use default og:image from settings-page (a special page for sitewide settings). should go @ready.php /** * In addition to module SeoMaestro * if page has no og:image set, inherit from closest parent with given og:image * if no og:image is set in branch until home -> fallback to default og:image @settings-page */ $this->addHookAfter('SeoMaestro::renderSeoDataValue', function (HookEvent $event) { $group = $event->arguments(0); $name = $event->arguments(1); $value = $event->arguments(2); $isAdmin = ($this->page->rootParent->id == 2); if ($isAdmin) { $page = wire('pages')->get(wire('input')->get->id); } else { $page = $event->wire('page'); } $field = "og_image"; // used field for og:image // @config: one element or NULL if empty // no default output if empty $configpage = "1049"; // holding site-wide default og:image (og_image here set as required) if ($group === 'opengraph' && $name === 'image') { bd('og image is: '.$value); bd('page is: '.$page->id); // do nothing if page has og:image if ($value !== "") return; $sitedefaultimage = wire('pages')->get($configpage)->getFormatted('og_image'); //scenario 1: fetch default image assigned in field-settings (get formatted) // config field settings @og_image accordingly, what page to use if empty //scenario 2: inherit from next upper parent-page in tree with assigned image // @config @og_image: no setting for default value $selector = "og_image.count>'0'"; $option = $page->parent($selector); if ($option->id) { $value = $option->getFormatted($field); $src = $option->title; } else { $value = $sitedefaultimage; $src = "site-settings"; } $value = $value->httpUrl; bd("og:image inherited from: {$src}\n{$value}"); $event->return = $value; } }); I corrected $value = $value->url; to $value = $value->httpUrl;1 point
-
Thanks for your answers, guys! I think I will also only support the UIKit theme. This will make the development a lot easier and I can concentrate on more important features!1 point
-
Hi @Jonathan Lahijani thx for that link. It looks nice indeed. Nonetheless I'm not sure how useful it would be. I'm not doing a lot of frontend, and ~5€/month doesn't sound too bad, but, well... it's 60€ per year and I'm not sure if I want to spend that. I think I don't need that fancy screenshot and zooming stuff (or do I?!), so I just hacked together a simple html page that shows an input for an URL and loads iframes in different sizes: https://bernhardbaumrock.github.io/devtools/ First problem I got was the same-origin restriction, so I copied the HTML file to my PW site. Well... that does not have synchronized scrolling but maybe it could still be helpful? This could also quite easily be turned into a PW module that hooks into the 404 exception when logged in as Superuser on /devtools url (or the like). What do you guys think? Anybody up for that? ? Here's the code: https://github.com/BernhardBaumrock/devtools1 point
-
New version release! 1.0.2 I am very happy to inform you guys that the new major version of the module is out. ⚠️ WARNING: Breaking Changes! ⚠️ The module was rewritten to use webonyx/graphql-php instead of youshido/graphql. This was a big issue because the latter was not properly maintained anymore and the webonyx/graphql-php gone very further in development and supports more features that we need. There are some more breaking changes that are listed on the latest release page. What's new trash(id: ID!): Page! field allows to move pages to trash via GraphQL api. Solves N+1 problem for FieldtypePage field. Significantly improves response speed! Support for even more ProcessWire permissions. Now the full list is: page-add page-create page-delete page-edit page-move page-view page-edit-created page-edit-trash-created It is already available in ProcessWire's modules directory. So you can install it via class name.1 point
-
I use WSL all the time, but my local server is still on Windows. It used to be XAMPP, but now I move to Laragon. One of the beauties of Laragon is that you can easilly swith PHP, Apache, MySQL and everything else versions almost instantly. As far as I know from my attempts to set everything up on Linuх, it is not that that easy there (though, surely, possible). I have not found any configuration for Linux that would be nearly that easy. Docker based Laradock was the closest, but it still required some additional docker skills, was not as fast and more complicated. And docker sucks badly on WSL)))1 point