Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/06/2023 in all areas

  1. 140 commits, 55 resolved issues, dozens of new features, eight contributors, and five new pull requests make yet another great new version of ProcessWire. This week I’m happy to announce another new main/master branch version of ProcessWire, version 3.0.210. Like most main release versions, there is a lot here. This post covers some of the most notable additions and improvements— https://processwire.com/blog/posts/pw-3.0.210/
    16 points
  2. That's because it's not a regular array but a PageImages object. If you inspect $i in your first example, you'll see that it contains the image filename, not a numeric index. To get a plain array without the filenames as keys, use its inherited getValues() method. foreach ($page->images->getValues() as $i => $image):
    3 points
  3. The module can generate basic ICS calendar strings and files. Usage Example: $icsgen = wire()->modules->IcsGenerator; // set properties $icsgen->setArray(array( 'date' => new \DateTime('2033-12-24 12:00'), 'dateEnd' => new \DateTime('2033-12-24 13:00'), 'summary' => 'Event title', 'description' => 'Event description', )); // get path to a temporary .ics file // (using wire()->files->tempDir) $icspath = $icsgen->getFile(); // send email with ics file $mail = wireMail(); $mail->attachment($icspath, 'calendar.ics'); $mail->to($user->email); $mail->subject('ICS Demo'); $mail->body('This is a ICS demo.'); $numSent = $mail->send(); For more infos see GitHub Readme or Modules Page. If you experience reproducable issues please open a GitHub issue.
    2 points
  4. Not exactly my strength but looks like a worthwhile addition to me ? This is off topic but would you mind explaining why you are trying to avoid SMTP and what your preferred alternative is? I just found it really cumbersome to setup all the time. And complicated to use. And a pain to switch between live and development. I'm just setting um my server correctly to get 10/10 on mail-tester using plain WireMail() without installing any additional libraries. Then sending an email ist just 5 lines of code away and it works well on DDEV (gets caught by mailcatcher) and once pushed to live it sends real emails without changing anything.
    2 points
  5. This module has several bugs. Line 113 must be: if($archive == '1') { Line 159 must be: if($this->archive == '1') { Line 295 must be: $field->attr('name', 'bytes'); Forked here: https://github.com/techcnet/LogMaintenance
    2 points
  6. To guard against execution of scripts inside vendor folder there seem to be 2 common approaches. move vendor outside webroot protect vendor folder with a .htaccess file I 'm just wondering if option 2 might be the better in our case because it doesn't involve changing core index.php Other CMS include a .htaccess inside vendor. Drupal for example does it like this with following content in vendor/.htaccess # Deny all requests from Apache 2.4+. <IfModule mod_authz_core.c> Require all denied </IfModule> # Deny all requests from Apache 2.0-2.2. <IfModule !mod_authz_core.c> Deny from all </IfModule> # Turn off all options we don't need. Options -Indexes -ExecCGI -Includes -MultiViews # Set the catch-all handler to prevent scripts from being executed. SetHandler Drupal_Security_Do_Not_Remove_See_SA_2006_006 <Files *> # Override the handler again if we're run later in the evaluation list. SetHandler Drupal_Security_Do_Not_Remove_See_SA_2013_003 </Files> # If we know how to do it safely, disable the PHP engine entirely. <IfModule mod_php.c> php_flag engine off </IfModule> Other suggestions from SO for .htaccess are: Order allow,deny Deny from all Problem with this apporach seems to be that the .htaccess gets lost when you remove vendor and do a composer install for whatever reason. But this could be solved with composer scripts inside composer.json. For example a simple script that places an .htaccess file inside vendor after composer install is finished using the post-install-cmd event. In https://github.com/processwire/processwire/blob/master/composer.json after line 22 we could add , "scripts": { "post-install-cmd": "echo $'Order allow,deny\nDeny from all' > vendor/.htaccess" } Just tested this and it works. This is off topic but would you mind explaining why you are trying to avoid SMTP and what your preferred alternative is?
    2 points
  7. Happy new year everyone! New year, new module 🙂 A super simple color picker for the ProcessWire backend that can not only pick colors but also custom HTML (so you can use it for picking gradients, for example). Docs and Download: https://www.baumrock.com/en/processwire/modules/rockcolorpicker/
    1 point
  8. Me making bad assumptions ? How about changing these lines to replace "</body>" to "$view/$rawButton</body>" ? It will be safer now that I'm seeing this. (my bad for not seeing the second half of your issues)
    1 point
  9. Ok, so not a setting, but Regex magic. I'll look into it and will see if this fixes the issue. If so I might send you a pull request. It's not that urgent as the 1.1.2 runs pretty fine still. Update: Formatting works fine now with this change. ✓ The issue with <mj-body background-color="#efefef"> seems to come from L:366 and L:413.
    1 point
  10. Happy new year to you too @wbmnfktr ! I'm sorry you're facing this issue, most likely it's because I'm removing a space before your <strong> tag here PageMjmlToHtml.module line 161. I'm not at home until next week and can't push a fix but you can either just comment this line and the next one or you can edit the lines so the regexes look for a space / \n only after "<" and before ">": Hope this helps !
    1 point
  11. This is great. I am just about to finish a project that deals with events. I will give it a try.
    1 point
  12. I second this. My heart weeps every so slightly that this beautiful module isn't compatible with combo fields (and one presumes other profield types). It would be very delicious if it did!
    1 point
  13. <div id="content"> <?php // get all children as $child foreach($page->children() as $child) { // get all images and output the single images foreach($child->get('images') as $image) { $thumb = $image->width(250); ?> <div class='favs'> <a href='<?=$image->url?>' data-uk-lightbox="image"> <img src='<?=$thumb->url?>' alt='<?=$child->title?>'> </a> <div class='text-favs'> <span><?=$child->title?></span> </div> </div> <?php } } ?> </div> Something like this ? I think you should have another look at the php foreach function how it works ?
    1 point
  14. I am proud to announce my very first module: GooglePlaceDetails. I was in the need to include some google place reviews for a clients website. It turned out that no such review widget was available for ProcessWire. So I made my own solution which i want to share with you. Google Place Details for ProcessWire Modules Directory: https://processwire.com/modules/google-place-details/ Github: https://github.com/StefanThumann/GooglePlaceDetails What it does Google Place Details offers the possibility to send requests to the Google Maps API to receive information about a certain place. A typical use case would be to display the reviews of a place on your website. But you can receive any other information that the API offers. Before you start You need three things: A Google API Key The Place ID A project with a billing account activated You can set up all of those by using Googles quick start widget here: https://developers.google.com/maps/third-party-platforms/quick-start-widget-users How to install Copy this directory to /site/modules In your admin, go to Modules > Refresh, then Modules > New Click the "Install" button next to the Google Place Details module Fill out the API Key and Place ID fields in the module settings and you are ready to go. Module settings and field descriptions API Key This field is required and must contain your generated Google API key. Place ID This field is required. You can put the ID of any place into this field. Fields to include in request Specify a comma-separated list of place data types to return. Leave empty to load all default fields. For an overview of the available fields see: https://developers.google.com/maps/documentation/places/web-service/details Review Sorting Chose your sorting criteria. "Most relevant" is used by default. Preview Place Details If checked the place details can be previewed for debugging/development purpose on module page submit. Usage example Load the module in a page context: $module = $modules->get('GooglePlaceDetails'); Call a function to load data $module->getPlaceDetails(); This function fetches the data in realtime, on every page request and returns a php array containing the full response from the Google server. See the frontend example at the end of this document to see how to extract data from the array in a working example. Place details answer example The place details answer will be in JSON format and looks like this (depending of the fields you included in your request) { "html_attributions": [], "result": { "name": "Google Workplace 6", "rating": 4, "reviews": [ { "author_name": "Luke Archibald", "author_url": "https://www.google.com/maps/contrib/113389359827989670652/reviews", "language": "en", "profile_photo_url": "https://lh3.googleusercontent.com/a-/AOh14GhGGmTmvtD34HiRgwHdXVJUTzVbxpsk5_JnNKM5MA=s128-c0x00000000-cc-rp-mo", "rating": 1, "relative_time_description": "a week ago", "text": "Called regarding paid advertising google pages to the top of its site of a scam furniture website misleading and taking peoples money without ever sending a product - explained the situation, explained I'd spoken to an ombudsman regarding it. Listed ticket numbers etc.\n\nThey left the advertisement running.", "time": 1652286798, }, { "author_name": "Tevita Taufoou", "author_url": "https://www.google.com/maps/contrib/105937236918123663309/reviews", "language": "en", "profile_photo_url": "https://lh3.googleusercontent.com/a/AATXAJwZANdRSSg96QeZG--6BazG5uv_BJMIvpZGqwSz=s128-c0x00000000-cc-rp-mo", "rating": 1, "relative_time_description": "6 months ago", "text": "I need help. Google Australia is taking my money. Money I don't have any I am having trouble sorting this issue out", "time": 1637215605, }, { "author_name": "Jordy Baker", "author_url": "https://www.google.com/maps/contrib/102582237417399865640/reviews", "language": "en", "profile_photo_url": "https://lh3.googleusercontent.com/a/AATXAJwgg1tM4aVA4nJCMjlfJtHtFZuxF475Vb6tT74S=s128-c0x00000000-cc-rp-mo", "rating": 1, "relative_time_description": "4 months ago", "text": "I have literally never been here in my life, I am 17 and they are taking money I don't have for no reason.\n\nThis is not ok. I have rent to pay and my own expenses to deal with and now this.", "time": 1641389490, }, { "author_name": "Prem Rathod", "author_url": "https://www.google.com/maps/contrib/115981614018592114142/reviews", "language": "en", "profile_photo_url": "https://lh3.googleusercontent.com/a/AATXAJyEQpqs4YvPPzMPG2dnnRTFPC4jxJfn8YXnm2gz=s128-c0x00000000-cc-rp-mo", "rating": 1, "relative_time_description": "4 months ago", "text": "Terrible service. all reviews are fake and irrelevant. This is about reviewing google as business not the building/staff etc.", "time": 1640159655, }, { "author_name": "Husuni Hamza", "author_url": "https://www.google.com/maps/contrib/102167316656574288776/reviews", "language": "en", "profile_photo_url": "https://lh3.googleusercontent.com/a/AATXAJwRkyvoSlgd06ahkF9XI9D39o6Zc_Oycm5EKuRg=s128-c0x00000000-cc-rp-mo", "rating": 5, "relative_time_description": "7 months ago", "text": "Nice site. Please I want to work with you. Am Alhassan Haruna, from Ghana. Contact me +233553851616", "time": 1633197305, }, ], "url": "https://maps.google.com/?cid=10281119596374313554", "user_ratings_total": 939, "website": "http://google.com/", }, "status": "OK", } Usage in frontend example To display the reviews of a place you can do it like this (very basic markup!). I encourage every user to build their own markup of the reviews, fitting their design. <?php // 1. Connect to module $module = $modules->get('GooglePlaceDetails'); // 2. Save the details array to a variable $details = $module->getPlaceDetails(); // 3. Extract the data you want to iterate over $reviews = $details['result']['reviews']; // For debug purpose dump the array to inspect the data // TRACY DEBUGGER MODULE REQUIRED // dump($reviews); <? foreach ($reviews as $review) { ?> <div> <img src="<?=$review["profile_photo_url"]?>"/> <h4><?=$review["author_name"]?></h4> <? for ($i = 1; $i <= ($review['rating']); $i++) { ?> &#9733; <? } ?> <p><?=$review["text"]?></p> </div> <? } ?> ?> Here is a more advanced and nicer looking version (UIKit 3 Framework Markup is used) <div class="uk-container"> <div uk-slider> <div class="uk-position-relative"> <div class="uk-slider-container"> <ul class="uk-slider-items uk-child-width-1-2@s uk-child-width-1-3@m uk-grid uk-height-medium"> <? foreach ($reviews as $review) { ?> <li> <div class="uk-card uk-card-default uk-card-body"> <div> <img src="<?=$review["profile_photo_url"]?>" class="uk-responsive-width" style="height: 30px;" /> <span class="uk-text-middle"><?=$review["author_name"]?></span> </div> <div class="uk-margin"> <? for ($i = 1; $i <= ($review['rating']); $i++) { ?> &#9733; <? } ?> <? for ($i = 1; $i <= 5 - ($review['rating']); $i++) { ?> &#9734; <? } ?> </div> <div uk-overflow-auto="selContainer: .uk-slider-items; selContent: .uk-card"> <p><?=$review["text"]?></p> </div> </div> </li> <? } ?> </ul> </div> <a class="uk-position-center-left-out uk-position-small" href="#" uk-slidenav-previous uk-slider-item="previous"></a> <a class="uk-position-center-right-out uk-position-small" href="#" uk-slidenav-next uk-slider-item="next"></a> </div> </div> </div> If you are already using UIKit 3 and just want to get a quick result I put the code example above in a function that can can be called like this: <? $module = $modules->get('GooglePlaceDetails'); echo $module->getUIKitMarkupExample(); ?> The template file which is used for the markup lies inside the module directory. Adjust it to your needs.
    1 point
  15. I have been using Github Copilot for a month now and I love it. It is actually very close to pair coding. Colleague who point out your mistakes, remembers function names better than you do, does actually know regexp and also makes silly suggestions and mistakes. With Chatgpt I noticed great use case with a list of numbers I had. They were copy pasted from somewhere and formatting those, reading into code/excel and doing some needed calculations (like avg, median and range) would have taken 5-15 mins of my time. Now it was super fast and easy. AI didn't care about extra spaces and quotes, it did just understand the numbers and knew the math. I just delegated the task and got response back. It did made one silly and strange mistake (427,00 => 4270,00), but after pointing that out everything was correct.
    1 point
  16. Here's one of my latest projects: https://petibol.pt/ Petibol develops and produces of all types of EPP (Expanded Polypropylene) and EPS components and packaging for various industries. This website is a collaboration between Supertiny and GOdesign. Super simple approach: The frontend is just SCSS and vanilla js "components" (no libraries), and pages are built with a blocks system based on a repeater field. Having tried a bunch of stuff between building this site almost a year ago and publishing it (Tailwind, AlpineJS, VUE...) it's pleasing to return to this site's code and compare the approach. Here I've basically set up Laravel Mix to compile SCSS, join and minify a bunch of <1kb js files. A BEM style approach to the styles so that I have a bunch of preset variables for typography, spacing and whatnot, and the JS files follow the same logic of identifying components like the hamburger or the parallax effect by looking for specific data-attributes and going from there. Super clean, performant, and couldn't be easier to pick up and maintain.
    1 point
  17. Hello @ all I am using a lot of hooking of methods and I want to optimize the performance of a module a little. In my case I use the following Hooks inside my modules init() method: public function init() { $this->addHookBefore('Page::render', $this, 'function1'); $this->addHookBefore('Page::render', $this, 'function2'); $this->addHookBefore('Page::render', $this, 'function3'); $this->addHookBefore('Page::render', $this, 'function4'); } As you can see, I am always hooking the same method (Page::render) to run different functions. The functions itself are declared outside of the init() method. My question: Would it have an impact on the performance if I would fe summarize function1 to function4 into one function (see below) or does it not matter? public function init() { $this->addHookBefore('Page::render', $this, 'summarizeFunction'); } protected function summarizeFunction() { $this->function1(); $this->function2(); $this->function3(); $this->function4(); } As you can see, I have only 1 hook left, that hooks into Page::render - not 4 as before. I have not try it, if there would be a significant performance boost or not. I only want to ask some other devs if they have experiences if this could be optimize the performance a little bit or not. Best regards
    1 point
  18. Grazie @angelo, italy This saved my life today. Would be great to develop this integration as a Processwire module. @Cybermano to interact with the checkout page you just need a post form with the action to the checkout page. Ex: <form action='<?php echo $pages->get('template=checkout')->url; ?>' method='POST' > <button type='submit' id='checkout-button' >Pay with Credit Card</button> </form>
    1 point
  19. To go a bit deeper in what Robin explained. When you are on the last page of a level, you want the first page of the next sibling of it's parent. For this to work, you have to be actually positioned on the child page, and not the parent — you can do that by redirecting to the first child when positioned on one of the parent pages. As for the next and prev links something like this should work to get the correct pages; $prev = $page->prev->id ? $page->prev : $page->parent->prev->child; $next = $page->next->id ? $page->next : $page->parent->next->child("sort=-sort");
    1 point
  20. $t->flags = Template::flagSystemOverride; $t->flags = 0; // etc... save here or delete $t->save();
    1 point
×
×
  • Create New...