Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/15/2019 in all areas

  1. This week ProcessWire ProMailer has been released, plus we’ve got a nice upgrade in our community support forum, and more— https://processwire.com/blog/posts/promailer-now-available/
    6 points
  2. I've just upgraded the forums to the latest version 4.4.x as there was a critical security patch that warranted it. As usual, there is some pain in upgrading from a 4.x to 4.x branch due to template changes and feature changes/additions so you may find things have moved around a bit. There is still work to do on the template as this was a little rushed (security update forced my hand) but it should be functional at the very least. If you spot anything drastically broken that I may have missed, please let me know here. Minor template tweaks (fonts, alignment etc) will be updated in the next few days.
    5 points
  3. Thanks for pointing to that module @Sergio - I use it on every site. It would be hard enough for me to remember to change the page name to match a new title, let alone expecting a client to do it. Given that PW has the core Page Path History functionality, I rarely see the need to not change the name when the title changes.
    4 points
  4. This is less of a bug and more of a.. well, issue: the line length in the forum is kind of crazy. I'm getting 220-240 characters on a single line, while 100-120 would be good for readability. Would be great to get this fixed as well. I'm thinking that there probably should be a max width for the content area – or perhaps the font size should be double what it is now? ? The font is also really tiny and way too light (at least in some places, such as the breadcrumbs and other "less important" texts), neither of which really helps with the readability issue. Anyway, great job getting the update rolled out, and the forum looking more like the main site! Edit: I'm officially getting old. Setting browser zoom level to 125% or 150% makes things way more comfortable ?
    4 points
  5. Thanks for for the write-up of how you got this working. I've tried many different AMP stacks for Windows over the years and Laragon is the best. Among the useful features is a built-in mail sender: I recommend it to any Windows user - you'll be sending email from your local dev environment within minutes rather than days. ?
    3 points
  6. Yes, it's possible. Set $config->advanced = true; on your config file and a "System" tab will appear while editing the template. And there you can make the change. See screenshot. Similar thread:
    3 points
  7. Most of the styling issues are where UIKit for the new PW header is conflicting with the forum software styling. I'm actually surprised it broke as little as it has to be honest but will get onto these theme issues in the next day or two.
    3 points
  8. @happywire There are two classes that ProcessWire uses for images: Pageimage and Pageimages (note the s). Each instance of Pageimage holds a single image, instances of Pageimages can hold multiple images (the class is basically an array wrapper around Pageimage objects). The function needs a single image, so you need to give it a single image. If your images fields contains multiple images (I suspect so because of the plural), you could for example loop through them and build a responsive image out of each of them, or just use the first one: // build a responsive image from each image in this field foreach ($page->images as $image) { $content .= buildResponsiveImage($image, 1200); } // build a responsive image from the first image in this field $content .= buildResponsiveImage($page->images->first(), 1200); You can also tell the API whether to return a Pageimage or Pageimages instance for this field by default. In the field settings for your images field, go to the Details tab; under formatted value, you can select Array of items to always return a Pageimages instance, or Single item to always return a Pageimage (this only works if your field is limited to one image). When in doubt, use get_class to find out what kind of object you're dealing with. Note you also have to check for an empty field, or the function will throw an error if there's no image in your field. // check object class echo get_class($page->images); // ProcessWire\Pageimages echo get_class($page->images->first()); // ProcessWire\Pageimage // make sure the field isn't empty before your pass the image into the function // for a Pageimage if ($page->images !== null) { $content .= buildResponsiveImage($page->images, 1200); } // for Pageimages if ($page->images->count() > 0) { $content .= buildResponsiveImage($page->images->first(), 1200); } Let me know if it doesn't work for you. Cheers ? Edit: Check out the documentation for the Pageimages and Pageimage classes.
    3 points
  9. Your link to Cerberus is incorrect: https://tedgoas.github.io/Ce vs https://tedgoas.github.io/Cerberus/
    2 points
  10. One of my sites is also on 3.0.123 and it's working correctly there. Try turning debug mode on, and see if any warning or errors pops out. There's no settings responsible for ordering items in repeater field iirc (besides hooks maybe).
    2 points
  11. You could do it with a quick JS/CSS hack: (after you did the advanced mode stuff described above) let lis = document.querySelectorAll('#ProcessPageEditContent > ul.Inputfields > li.Inputfield'); lis.forEach(function(li, index) { li.style="order:" + index; }); document.querySelector('#wrap_Inputfield__pw_page_name').style="order: 2"; (only tested with Chrome + AdminThemUIKit)
    2 points
  12. Yes, is not the best solution from a UX point-of-view. But I don't think that adding it below the title, as WP does, is the best way around. In most cases, we don't want the user to edit the page name by mistake. In your situation, I would take a look at @adrian's PageRenameOptions module https://modules.processwire.com/modules/page-rename-options/. Another option is to add a warning, using a hook, if the page title is edited to alert the user to also change, or check, the page name on the Settings tab.
    2 points
  13. Personally, but I don't like to have my functions silently fail on invalid input. In this case, there's no useful thing the function can do if it doesn't receive a Pageimage, so you'd end up returning an empty string or null in this case (would need to make the return typehint nullable for the latter): function buildResponsiveImage(?Pageimage $img, int $standard_width): string { if ($img === null) { return ''; } /* ... */ } To me that feels like I'm creating a hard to debug error down the road, when I can't figure out why an image is not being displayed. Also, I want to be able to see all permutations of a given template by looking at it's source code; if an image field is optional, I want to see a conditional clause covering the case of an empty image field. Also, though I wrap the functions as static methods in a class, it's really more of a functional approach, so I'd rather create a higher-order function to wrap around this one and catch empty image fields in case I want to build on this. But this really comes down to personal preferences, and after all it was a tutorial on how to build such a function. I'd encourage everyone to build upon it and adjust it to their personal workflow / preferences, especially for things like error handling and default arguments ?
    2 points
  14. You'll need a hook, something like this: maybe along with:
    2 points
  15. I've spent two days trying to get my Windows 10 WAMP server setup to send the confirmation email generated by Ryans LoginRegister Module. It's a fine Module and I struggle with PHP and coding in general. BUT TODAY, I finally set it up and here is my HOW TO GUIDE for the community so no one else has to struggle as much as I did ? STEP #1: download the sendmail executable here https://www.glob.com.au/sendmail/ STEP #2: extract all the files anywhere you like. I chose, 'C:\Users\orgfel\www\_sendmail'. STEP #3: open and edit 'sendmail.ini', insert the following with your credentials: smtp_server=smtp.gmail.com smtp_port=465 auth_username=YourGmailUser@gmail.com auth_password=YourGmailPass smtp_ssl=ssl default_domain=localhost hostname=localhost I have 2-Step Verification set up for my Gmail account. I was incredibly frustrated when I kept trying to configure the module WireMailSmtp to send a test email and it continued to fail. The prompt kept saying I had the wrong password. I KNEW I did not have the wrong Gmail password and it was driving me nuts! I discovered that I needed an App Password ( Sign in using App Passwords). There's a generator process what give you a 16 character password that you put into your 'sendmail.ini'. STEP #4: open and edit 'php.ini', insert the path to where you put your 'sendmail.exe': sendmail_path = "C:\Users\orgfel\www\_sendmail\sendmail.exe -t" STEP #5: restart your Apache server and it should be working! STEP #6: create a simple page + template and paste in the following code for a quick test! <?php $to = 'recipient@gmail.com'; $subject = 'Testing sendmail.exe'; $message = 'Hi, you just received an email using sendmail!'; $headers = 'From: [your_gmail_account_username]@gmail.com' . "\r\n" . 'MIME-Version: 1.0' . "\r\n" . 'Content-type: text/html; charset=utf-8'; if(mail($to, $subject, $message, $headers)) echo "WOOHOO, email sent"; else echo "BUMMER, email failed"; ?> I completed my setup about an hour ago after having tried several other Windows STMP server solutions. They were all overly complex with too many settings that I just didn't need. I hope that's it and that I didn't miss anything.
    1 point
  16. I've developed for years on Debian. I recently made the move to Windows and ... well, I'm not liking it ? So many things require more complex processes to install Nodejs and other things I need for web dev. I will check out Laragon, thanks!
    1 point
  17. They're not actually uninstalled - just do a Modules > Refresh and you'll be back in business with all modules settings as they were.
    1 point
  18. What about: if($image->width > 9000) $image->size(9000, 0, $defaultOptions); I'd anyway prefer something generic like (You'll probably want to account for landscape and portrait as well): $imgWidth = $image->width; while($imgWidth > 400) // Larger than minimum? { $imgWidth /= 2; // half size (or whatever factor) $image->size($imgWidth, 0, $defaultOptions); } Not sure about the ImageMagick quality setting, but "max" quality of a JPEG normally relates to its (I'll name it) "cluster" size. The higher the quality setting, the smaller the cluster is. This has nothing to do with "keep quality from original", which may be encoded with a lower quality setting, which seems to be the case in your example.
    1 point
  19. Hello there, I've started using ProcessWire at work a while ago and I have been really enjoying building modular, clean and fast sites based on the CMS (at work, I usually post as @schwarzdesign). While building my first couple of websites with ProcessWire, I have written some useful helper functions for repetitive tasks. In this post I want to showcase and explain a particular function that generates a responsive image tag based on an image field, in the hope that some of you will find it useful :) I'll give a short explanation of responsive images and then walk through the different steps involved in generating the necessary markup & image variations. I want to keep this beginner-friendly, so most of you can probably skip over some parts. What are responsive images I want to keep this part short, there's a really good in-depth article about responsive images on MDN if you are interested in the details. The short version is that a responsive image tag is simply an <img>-tag that includes a couple of alternative image sources with different resolutions for the browser to choose from. This way, smaller screens can download the small image variant and save data, whereas high-resolution retina displays can download the extra-large variants for a crisp display experience. This information is contained in two special attributes: srcset - This attribute contains a list of source URLs for this image. For each source, the width of the image in pixels is specified. sizes - This attribute tells the browser how wide a space is available for the image, based on media queries (usually the width of the viewport). This is what a complete responsive image tag may look like: <img srcset="/site/assets/files/1015/happy_sheep_07.300x0.jpg 300w, /site/assets/files/1015/happy_sheep_07.600x0.jpg 600w, /site/assets/files/1015/happy_sheep_07.900x0.jpg 900w, /site/assets/files/1015/happy_sheep_07.1200x0.jpg 1200w, /site/assets/files/1015/happy_sheep_07.1800x0.jpg 1800w, /site/assets/files/1015/happy_sheep_07.2400x0.jpg 2400w" sizes="(min-width: 1140px) 350px, (min-width: 992px) 480px, (min-width: 576px) 540px, 100vw" src="/site/assets/files/1015/happy_sheep_07.1200x0.jpg" alt="One sheep"> This tells the browser that there are six different sources for this image available, ranging from 300px to 2400px wide variants (those are all the same image, just in different resolutions). It also tells the browser how wide the space for the image will be: 350px for viewports >= 1140px 480px for viewports >= 992px 540px for viewports >= 576px 100vw (full viewport width) for smaller viewports The sizes queries are checked in order of appearance and the browser uses the first one that matches. So now, the browser can calculate how large the image needs to be and then select the best fit from the srcset list to download. For browsers that don't support responsive images, a medium-sized variant is included as the normal src-Attribute. This is quite a lot of markup which I don't want to write by hand every time I want to place an image in a ProcessWire template. The helper function will need to generate both the markup and the variations of the original image. Building a reusable responsive image function Let's start with a function that takes two parameters: a Pageimage object and a standard width. Every time you access an image field through the API in a template (e.g. $page->my_image_field), you get a Pageimage object. Let's start with a skeleton for our function: function buildResponsiveImage( Pageimage $img, int $standard_width ): string { $default_img = $img->maxWidth($standard_width); return '<img src="' . $default_img->url() . '" alt="' . $img->description() . '">'; } // usage example echo buildResponsiveImage($page->my_image_field, 1200); This is already enough for a normal img tag (and it will serve as a fallback for older browsers). Now let's start adding to this, trying to keep the function as flexible and reusable as possible. Generating alternate resolutions We want to add a parameter that will allow the caller to specify in what sizes the alternatives should be generated. We could just accept an array parameter that contains the desired sizes as integers. But that is not very extendible, as we'll need to specify those sizes in each function call and change them all if the normal size of the image in the layout changes. Instead, we can use an array of factors; that will allow us to set a reasonable default, and still enable us to manually overwrite it. In the following, the function gets an optional parameter $variant_factor. // get the original image in full size $original_img = $img->getOriginal() ?? $img; // the default image for the src attribute, it wont be upscaled $default_image = $original_img->width($standard_width, ['upscaling' => false]); // the maximum size for our generated images $full_image_width = $original_img->width(); // fill the variant factors with defaults if not set if (empty($variant_factors)) { $variant_factors = [0.25, 0.5, 0.75, 1, 1.5, 2]; } // build the srcset attribute string, and generate the corresponding widths $srcset = []; foreach ($variant_factors as $factor) { // round up, srcset doesn't allow fractions $width = ceil($standard_width * $factor); // we won't upscale images if ($width <= $full_image_width) { $srcset[] = $original_img->width($width)->url() . " {$width}w"; } } $srcset = implode(', ', $srcset); // example usage echo buildResponsiveImage($page->my_image_field, 1200, [0.4, 0.5, 0.6, 0.8, 1, 1.25, 1.5, 2]); Note that for resizing purposes, we want to get the original image through the API first, as we will generate some larger alternatives of the images for retina displays. We also don't want to generate upscaled versions of the image if the original image isn't wide enough, so I added a constraint for that. The great thing about the foreach-loop is that it generates the markup and the images on the server at the same time. When we call $original_img->width($width), ProcessWire automatically generates a variant of the image in that size if it doesn't exist already. So we need to do little work in terms of image manipulation. Generating the sizes attribute markup For this, we could build elaborate abstractions of the normal media queries, but for now, I've kept it very simple. The sizes attribute is defined through another array parameter that contains the media queries as strings in order of appearance. $sizes_attribute = implode(', ', $sizes_queries); The media queries are always separated by commas followed by a space character, so that part can be handled by the function. We'll still need to manually write the media queries when calling the function though, so that is something that can be improved upon. Finetuning & improvements This is what the function looks like now: function buildResponsiveImage( Pageimage $img, int $standard_width, array $sizes_queries, ?array $variant_factors = [] ): string { // get the original image in full size $original_img = $img->getOriginal() ?? $img; // the default image for the src attribute, it wont be upscaled $default_image = $original_img->width($standard_width, ['upscaling' => false]); // the maximum size for our generated images $full_image_width = $original_img->width(); // fill the variant factors with defaults if not set if (empty($variant_factors)) { $variant_factors = [0.25, 0.5, 0.75, 1, 1.5, 2]; } // build the srcset attribute string, and generate the corresponding widths $srcset = []; foreach ($variant_factors as $factor) { // round up, srcset doesn't allow fractions $width = ceil($standard_width * $factor); // we won't upscale images if ($width <= $full_image_width) { $srcset[] = $original_img->width($width)->url() . " {$width}w"; } } $srcset = implode(', ', $srcset); return '<img src="' . $default_img->url() . '" alt="' . $img->description() . '" sizes="' . $sizes_attribute . '" srcset="' . $srcset . '">'; } It contains all the part we need, but there are some optimizations to make. First, we can make the $sizes_queries parameters optional. The sizes attribute default to 100vw (so the browser will always download an image large enough to fill the entire viewport width). This isn't optimal as it wastes bandwidth if the image doesn't fill the viewport, but it's good enough as a fallback. We can also make the width optional. When I have used this function in a project, the image I passed in was oftentimes already resized to the correct size. So we can make $standard_width an optional parameter that defaults to the width of the passed image. if (empty($standard_width)) { $standard_width = $img->width(); } Finally, we want to be able to pass in arbitrary attributes that will be added to the element. For now, we can just add a parameter $attributes that will be an associative array of attribute => value pairs. Then we need to collapse those into html markup. $attr_string = implode( ' ', array_map( function($attr, $value) { return $attr . '="' . $value . '"'; }, array_keys($attributes), $attributes ) ); This will also allow for some cleanup in the way the other attributes are generated, as we can simply add those to the $attributes array along the way. Here's the final version of this function with typehints and PHPDoc. Feel free to use this is your own projects. /** * Builds a responsive image element including different resolutions * of the passed image and optionally a sizes attribute build from * the passed queries. * * @param \Processwire\Pageimage $img The base image. * @param int|null $standard_width The standard width for this image. Use 0 or NULL to use the inherent size of the passed image. * @param array|null $attributes Optional array of html attributes. * @param array|null $sizes_queries The full queries and sizes for the sizes attribute. * @param array|null $variant_factors The multiplication factors for the alternate resolutions. * @return string */ function buildResponsiveImage( \Processwire\Pageimage $img, ?int $standard_width = 0, ?array $attributes = [], ?array $sizes_queries = [], ?array $variant_factors = [] ): string { // if $attributes is null, default to an empty array $attributes = $attributes ?? []; // if the standard width is empty, use the inherent width of the image if (empty($standard_width)) { $standard_width = $img->width(); } // get the original image in full size $original_img = $img->getOriginal() ?? $img; // the default image for the src attribute, it wont be // upscaled if the desired width is larger than the original $default_image = $original_img->width($standard_width, ['upscaling' => false]); // we won't create images larger than the original $full_image_width = $original_img->width(); // fill the variant factors with defaults if (empty($variant_factors)) { $variant_factors = [0.25, 0.5, 0.75, 1, 1.5, 2]; } // build the srcset attribute string, and generate the corresponding widths $srcset = []; foreach ($variant_factors as $factor) { // round up, srcset doesn't allow fractions $width = ceil($standard_width * $factor); // we won't upscale images if ($width <= $full_image_width) { $srcset[] = $original_img->width($width)->url() . " {$width}w"; } } $attributes['srcset'] = implode(', ', $srcset); // build the sizes attribute string if ($sizes_queries) { $attributes['sizes'] = implode(', ', $sizes_queries); } // add src fallback and alt attribute $attributes['src'] = $default_image->url(); if ($img->description()) { $attriutes['alt'] = $img->description(); } // implode the attributes array to html markup $attr_string = implode(' ', array_map(function($attr, $value) { return $attr . '="' . $value . '"'; }, array_keys($attributes), $attributes)); return "<img ${attr_string}>"; } Example usage with all arguments: echo buildResponsiveImage( $page->testimage, 1200, ['class' => 'img-fluid', 'id' => 'photo'], [ '(min-width: 1140px) 350px', '(min-width: 992px) 480px', '(min-width: 576px) 540px', '100vw' ], [0.4, 0.5, 0.6, 0.8, 1, 1.25, 1.5, 2] ); Result: <img class="img-fluid" id="photo" srcset="/site/assets/files/1/sean-pierce-1053024-unsplash.480x0.jpg 480w, /site/assets/files/1/sean-pierce-1053024-unsplash.600x0.jpg 600w, /site/assets/files/1/sean-pierce-1053024-unsplash.720x0.jpg 720w, /site/assets/files/1/sean-pierce-1053024-unsplash.960x0.jpg 960w, /site/assets/files/1/sean-pierce-1053024-unsplash.1200x0.jpg 1200w, /site/assets/files/1/sean-pierce-1053024-unsplash.1500x0.jpg 1500w, /site/assets/files/1/sean-pierce-1053024-unsplash.1800x0.jpg 1800w, /site/assets/files/1/sean-pierce-1053024-unsplash.2400x0.jpg 2400w" sizes="(min-width: 1140px) 350px, (min-width: 992px) 480px, (min-width: 576px) 540px, 100vw" src="/site/assets/files/1/sean-pierce-1053024-unsplash.1200x0.jpg" alt="by Sean Pierce"> Now this is actually too much functionality for one function; also, some of the code will be exactly the same for other, similar helper functions. If some of you are interested, I'll write a second part on how to split this into multiple smaller helper functions with some ideas on how to build upon it. But this has gotten long enough, so yeah, I hope this will be helpful or interesting to some of you :) Also, if you recognized any problems with this approach, or can point out some possible improvements, let me know. Thanks for reading!
    1 point
  20. While the forum is getting some attention, how about disabling the quote tooltip that drives everyone crazy with its evil span insertion ways?
    1 point
  21. Have replied via PM, but for others who are in the same boat the system still doesn't seem to be correctly promoting people from the Starter group to the Members group so I will look into that.
    1 point
  22. Yes, it's always good to do this but I was wondering if maybe the function itself should (also) do this check? ...just to make it more robust. Thanks.
    1 point
  23. @MoritzLost Great post, thank you. New to PW. I am having trouble getting the beginning of your function to work in the Intermediate profile. <?php // ########################## // I have this in _func.php function buildResponsiveImage(Pageimage $img, int $standard_width): string { $default_img = $img->maxWidth($standard_width); return '<img src="' . $default_img->url() . '" alt="' . $img->description() . '">'; } // ########################## // In a Gallery page I created and where I added a gallery-page template that does have the Images field I put this. // There I also added two images, both larger than 7000px width. <?php namespace ProcessWire; // gallery-page.php template file $content = $page->images; $content .= buildResponsiveImage($page->images, 1200); // ########################## // In the _main.php file I like to output the code in the main tag. <!-- main content --> <div id='content'> <h1><?php echo $title; ?></h1> <?php echo $content; ?> </div> "Fatal error: Uncaught TypeError: Argument 1 passed to ProcessWire\buildResponsiveImage() must be an instance of ProcessWire\Pageimage, instance of ProcessWire\Pageimages given". Thank you for any help or learning resources to get this right.
    1 point
  24. Yeah, someone else also did highly recommend to do that course. Have been watching the first couple hours through this site http://learnwebdev.net/ and had so many concepts suddenly make a lot of sense. Window object, this, execution context, lexical scope. Just the first 2h of that cleared up a lot of what I was missing all this time.
    1 point
  25. Glad it all worked out - we've all done similar things ?
    1 point
  26. Back here with... quite an amount of shame... I'm sorry I have taken time from you all. Here's the thing : my site/ready.php which I thought did not have access to bd() because I couldn't even see a simple bd('ok'); was not at the right place. A bell just rang in my head a few minutes ago after making a fresh re-install of a blank profile ! I came back to my original local site and thought : "No way, Fred ! site/ready.php NOT your-website-root/ready.php !!!!" I moved ready.php and.... tada ! (Of course...). What a nerd... So again, SORRY for having taken some of your time, but thanks for your helpful answers. I still have learned quite a lot from our exchange and that is the most important thing. I'm glad I posted in 'Getting started' ;)
    1 point
  27. Sorry dude, I am aware of this issue but forgot to update the first post and the github doc. So yes, basically, In the last version of Duplicator, its necessary (but unwanted) to move the unzipped data to the parent dir.. And about your last issue, try what its said in the github issue linked by @netcarver and more precisely this one : https://github.com/composer/composer/issues/7836#issuecomment-452341683 And just saying, I have not tested the module with PHP 7.x and it might have some issues on this version. sorry for the inconveniences, I hope to get the time to finally work on the V2 ? but I promise you guys to take a look at the actual version and make a revision in the last 10 days or ask to moderators to ban me from the forum ! ? ?
    1 point
  28. I guess you may keep the srcset creation in your function as is with very few changes. Add some output variable at the head of your function, something like this: function responsive_picture($acf_image_array, $media_condition, $type) { $out = ''; Replace each print with $out .= like this: $out .= '<img class="lazyload" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" '; // leave space between attributes $out .= 'data-src="' . esc_html($acf_image_array['sizes'][320]) . '" '; // default image size leave space between attributes Alternatively you can simply define a fallback src via the data-src attribute. $out .= 'alt="' . esc_html($acf_image_array['alt']) . '" '; // leave space between attributes $out .= 'sizes="' . esc_html($media_condition) . '" '; // leave space between attributes $out .= 'data-srcset="' . esc_html($srcset) . '">'; // close img tag here $out .= '</picture>'; End your function with return $out; } What you need to do is either creating the $acf_image_array from the PW image before calling the function (keep its API), or change the function to parse the media conditions and create matching variants as required (given a single image). Either way you'll do something like $imgVariant = $img->size($variantWidth, $variantHeight) for each required size.
    1 point
  29. @jploch AFAIK, you can turn off PCRE JIT compilation if needed. Some info in the discussion here.
    1 point
  30. wow!! new design for the forum, great!! ? Avatars are also squeezed in the latest topics links:
    1 point
  31. Home > Settings - color and icon stretching.
    1 point
  32. Soma and Robin S are missing their avatars - I am sure there are many more also.
    1 point
  33. Looking nice even in its unfinished state :-). One thing now that we have you here (I think I might have asked this before), you know when one is browsing list of unread posts/content, we used to be able to hover on a topic's title in the list and click a button/link to mark that AND ONLY that post as read. That was a time saver! There are times when you just want to mark A FEW/SOME posts as read without actually opening them (?). Are you able to look into this please? Thanks!
    1 point
  34. @SamC: Exactly @happywire: You are completely right except the last point: The snippet performs the boolean evaluation of Math.random() some thousend of times: var YesIfTrue = !!~~(Math.random() * 2); // Boolean result 50/50 You either get a boolean true or boolean false for each iteration. YesIfTrue is set, if the truncation of (Math.random() * 2) is equal or above 1.0 (or Math.random() returns a value equal or above 0.5). The less obfuscated version of that line would be: var YesIfTrue = Math.random() >= 0.5; Which can be unrolled to: var YesIfTrue; if(Math.random() >= 0.5) YesIfTrue = true; else YesIfTrue = false; which is what actually happens behind the scenese: A numerical comparison on two floats along with a "jump" to either assignment statement. While there still is some "jumps are bad" in many minds, that's not necessarily true for JavaScript. In fact the version using the comparison may effectively execute faster than the obfuscated "true boolean" version, but the unrolled version is slowest (10Mio iterations, Firefox 65): True Boolean: Yes: 4999123 No: 5000877 in 54ms Logical: Yes: 9997660 No: 10002340 in 51ms Comparison: Yes: 14996131 No: 15003869 in 39ms Unrolled: Yes: 19995907 No: 20004093 in 98ms Floor: Yes: 24996634 No: 25003366 in 57ms var i, cntYes=0, cntNo=0; var tStart, tEnd; tStart = window.performance.now(); for(i=0; i<10000000; ++i) { var YesIfTrue = !!~~(Math.random() * 2); cntYes += YesIfTrue; cntNo += !YesIfTrue; } tEnd = window.performance.now(); console.log('True Boolean: Yes: '+cntYes+' No: '+cntNo+' in '+(tEnd-tStart)+'ms'); tStart = window.performance.now(); for(i=0; i<10000000; ++i) { var YesIfTrue = ~~(Math.random() * 2); cntYes += YesIfTrue; cntNo += !YesIfTrue; } tEnd = window.performance.now(); console.log('Logical: Yes: '+cntYes+' No: '+cntNo+' in '+(tEnd-tStart)+'ms'); tStart = window.performance.now(); for(i=0; i<10000000; ++i) { var YesIfTrue = Math.random() >= 0.5; cntYes += YesIfTrue; cntNo += !YesIfTrue; } tEnd = window.performance.now(); console.log('Comparison: Yes: '+cntYes+' No: '+cntNo+' in '+(tEnd-tStart)+'ms'); tStart = window.performance.now(); for(i=0; i<10000000; ++i) { var YesIfTrue; if(Math.random() >= 0.5) YesIfTrue = true; else YesIfTrue = false; cntYes += YesIfTrue; cntNo += !YesIfTrue; } tEnd = window.performance.now(); console.log('Unrolled: Yes: '+cntYes+' No: '+cntNo+' in '+(tEnd-tStart)+'ms'); tStart = window.performance.now(); for(i=0; i<10000000; ++i) { var YesIfTrue = Math.floor(Math.random() * 2); cntYes += YesIfTrue; cntNo += !YesIfTrue; } tEnd = window.performance.now(); console.log('Floor: Yes: '+cntYes+' No: '+cntNo+' in '+(tEnd-tStart)+'ms');
    1 point
  35. sorry: No! Any logical operation like OR '|', AND '&', EXOR '^', Bitwise complement '~' or even shift can only be processed on integers. Using one of these operators enforce JavaScript to typecast any other type into integer. If one of the operators is a float (like return value of Math.random), then decimals are just truncated (a 1.99999 gets 1), if its a string, JS tries to convert it into an integer first. The logical OR (in contrast to the boolean OR '||') is executed in any case. Even if '| 0' does not seem to make any sense, its just there to enforce the type conversion, so the result is an integer. Using a logical operator in contrast to Math.floor basically optimizes for performance (no method call). And if you need a true boolean result and love obfuscated code, try this: var randomNum = !!~~(Math.random() * 2); Maybe this snippet helps to clarify it: var i, cntYes=0, cntNo=0; for(i=0; i<10000; ++i) { var YesIfTrue = !!~~(Math.random() * 2); // Boolean result 50/50 cntYes += YesIfTrue; // Count only true results cntNo += !YesIfTrue; // Count only not true results } console.log('Yes: '+cntYes+' No: '+cntNo);
    1 point
  36. Sorry to say, but when you intend to migrate fields between installs be aware that the GUI import/export functions rely on ids rather than names. If the target is not 100% in sync with the source, you may end up correcting things in the database. This is particular true when it comes to Repeaters and the RepeaterMatrix. ...and do Option fields restore options properly when importing an exported page? Until now I preferred to do this via API and run my own, application specific implementation.
    1 point
  37. I can reproduce. Seems like a bug. Issue here: https://github.com/processwire/processwire-issues/issues/826
    1 point
  38. I'm not sure what's going wrong in your module, but maybe it helps you to look at this proof of concept module which adds a config field named "Animal" to every field and allows setting the field in template context. ExtraFieldConfig.module <?php namespace ProcessWire; /** * * ExtraFieldConfig * * @author Robin Sallis * * ProcessWire 3.x * Copyright (C) 2011 by Ryan Cramer * Licensed under GNU/GPL v2, see LICENSE.TXT * * http://www.processwire.com * http://www.ryancramer.com * */ class ExtraFieldConfig extends WireData implements Module { /** * Module information */ public static function getModuleInfo() { return array( 'title' => 'Extra Field Config', 'summary' => 'Test module for adding and extra config field to Fieldtype config.', 'version' => '0.1.0', 'author' => 'Robin Sallis', 'autoload' => true, 'requires' => 'ProcessWire>=3.0.0', ); } /** * Ready */ public function ready() { $this->addHookAfter('Fieldtype::getConfigInputfields', $this, 'addConfigField'); $this->addHookAfter('Fieldtype::getConfigAllowContext', $this, 'allowContext'); } /** * Add config field * * @param HookEvent $event */ protected function addConfigField(HookEvent $event) { $field = $event->arguments(0); $wrapper = $event->return; /* @var InputfieldText $f */ $f = $this->wire('modules')->InputfieldText; $f_name = 'animal'; $f->name = $f_name; $f->label = $this->_('Animal'); $f->value = $field->$f_name; $wrapper->add($f); } /** * Allow setting config field in template context * * @param HookEvent $event */ protected function allowContext(HookEvent $event) { $allowed = $event->return; $allowed[] = 'animal'; $event->return = $allowed; } }
    1 point
  39. In a hurry, so answering quickly.. Yes. For fields and templates have a look at the method setImportData(). For pages, there's different ways. I'll let others chime in. Exporting pages example. Yes, for pages, using previously exported JSON or ZIP and for fields using previously exported JSON and setImportData(). Examples of importing fields and templates from JSON. Yes. How you do it depends on the fieldtype... (others will chime in here) Not sure I understand this fully, but yes, you can do everything from the API or using the GUI. For pages, the PagesExportImport is still experimental but it works fine (for me).
    1 point
  40. Hm... Just got reminded about this post. Actually I think it's not the best idea to have a render() and renderReady() method in a Fieldtype module. That are methods that belong to an Inputfield module and I think it's not good to mix them up... I'd be more than happy though to have a good and extensive documentation about developing fieldtypes for ProcessWire...
    1 point
  41. @JeevanisM Please take a look at https://processwire.com/docs/security/sessions/. With Database-driven sessions you can monitor live traffic on your site.
    1 point
  42. You can do it to the degree forums do it. Like track users activity somewhere in a database whenever communication happens and take some amount of timeout at which you consider a person without activity offline. What you cannot easily do is online users to the degree you would expect it from e.g. a chat platform, where you actually want to detect if someone is leaving without waiting 15 minutes and without them needing to communicate to your server constantly. This is the realm of websockets. I may be biased, but if you want a really proper (and scalable) solution for that problem take a look at: https://dockyard.com/blog/2016/03/25/what-makes-phoenix-presence-special-sneak-peek
    1 point
  43. Or add a checkbox to the template and when saving a page check for date and if empty set the checkbox. Then use "sort=hasdate_checkbox, sort=training_start, sort=id"
    1 point
  44. @phil_s: set_time_limit($n) sets the maximum amount of seconds the script may run before it get interrupted! If you set it to zero set_time_limit(0) it may run forever if your server isn't setup to avoid this. But you also don't want to have a script to run forever, because you loose control over it. Therefor it is a good choice to use it with a little amount of seconds in a loop, because it sets the max amount to live with each call again. For example, if the default php server setup for timeout is set to 30 seconds and you have 50 images to process whereas each image will take 2 seconds, your script will crash after the 15th image. BUT, if you call set_time_limit(15) within the foreach loop, all 50 images get processed and the script will run for 100 seconds, - if everything is ok. If the script run into problems with a single image and hangs, it get interuppted 15 seconds after it started to process the damaged image. Conclusion: with this approach you can exceed the default setting a script may run without loosing control.
    1 point
  45. This is the only way I know to create different sizes when uploading images: <?php class ImageCreateThumbs extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'ImageCreateThumbs', 'version' => 100, 'summary' => '', 'href' => '', 'singular' => true, 'autoload' => true ); } public function init() { $this->addHookAfter('InputfieldFile::fileAdded', $this, 'sizeImage'); } public function sizeImage($event) { $inputfield = $event->object; if($inputfield->name != 'images') return; // we assume images field $image = $event->argumentsByName("pagefile"); $image->size(120,120); $image->size(1000,0); } } https://gist.github.com/5685631 What I don't know is if it really makes a difference (I guess), and if using drag and drop ajax upload and old school upload would process image one by one. My suggestion is to also upload image already in 1000x* pixels because if they upload 3000+ px images it will just takes a lot longer.
    1 point
×
×
  • Create New...