Jump to content
nbcommunication

PageimageSrcset

Recommended Posts

I've spent the last while experimenting with srcset implementation - and PageimageSrcset is the result:

PageimageSrcset

Provides configurable srcset and sizes properties/methods for Pageimage.

Overview

The main purpose of this module is to make srcset implementation as simple as possible in your template code. It does not handle images rendered in CKEditor or similar fields.

For an introduction to srcset and sizes, please read this Mozilla article about responsive images.

Pageimage::srcset()

// The property, which uses the set rules in the module configuration
$srcset = $image->srcset;

// A method call, using a set rules string
// Delimiting with a newline (\n) would also work, but not as readable
$srcset = $image->srcset("320, 480, 640x480 768w, 1240, 2048 2x");

// The same as above but using an indexed/sequential array
$srcset = $image->srcset([
	"320",
	"480",
	"640x480 768w",
	"1240",
	"2048 2x",
]);

// The same as above but using an associative array
// No rule checking is performed
$srcset = $image->srcset([
	"320w" => [320],
	"480w" => [480],
	"768w" => [640, 480],
	"1240w" => [1240],
	"2x" => [2048],
]);

// Use the default set rules with portrait images generated for mobile/tablet devices
$srcset = $image->srcset(true);

// Return the srcset using all arguments
$srcset = $image->srcset("320, 480, 640x480 768w, 1240, 2048 2x", [
	"portrait" => "320, 640",
]);

// The set rules above are a demonstration, not a recommendation!

Image variations are only created for set rules which require a smaller image than the Pageimage itself. On large sites this may still result in a lot of images being generated. If you have limited storage, please use this module wisely.

Portrait Mode

In many situations, the ratio of the image does not need to change at different screen sizes. However, images that cover the entire viewport are an exception to this and are often the ones that benefit most from srcset implementation.

The main problem with cover images is that they need to display landscape on desktop devices and portrait when this orientation is used on mobile and tablet devices.

You can automatically generate portrait images by enabling portrait mode. It is recommended that you use this in combination with Pageimage::focus() so that the portrait variations retain the correct subject.

The generated variations are HiDPI/Retina versions. Their height is determined by the portrait ratio (e.g. 9:16). Variations are always generated, regardless of whether the original image is smaller. Upscaling is disabled though, so you may find that some variations are actually smaller than they say they are in their filename.

The sizes attribute should be used when portrait mode is enabled. Pageimage::sizes will return (orientation: portrait) and (max-width: {maxWidth}px) 50vw by default, which handles the use of these images for retina devices. The maximum width used in this rule is the largest set width.

Pageimage::sizes()

There is no option to configure default sizes because in most cases 100vw is all you need, and you do not need to output this anyway as it is inferred when using the srcset attribute. You can use the method for custom sizes though:

// The property
$sizes = $image->sizes;
// Returns 100vw in most cases
// Returns '(orientation: portrait) and (max-width: {maxWidth}px)50vw' if portrait mode enabled

// A method call, using a mixture of integer widths and media query rules
// Integer widths are treated as a min-width media query rule
$sizes = $image->sizes([
	480 => 50,
	"(orientation: portrait) and (max-width: 640px)" => 100,
	960 => 25,
]);
// (min-width: 480px) 50vw, (orientation: portrait) and (max-width: 640px) 100vw, (min-width: 960px) 25vw

// Determine widths by UIkit 'child-width' classes
$sizes = $image->sizes([
	"uk-child-width-1-2@s",
	"uk-child-width-1-3@l",
]);
// (min-width: 640px) 50vw, (min-width: 1200px) 33.33vw

// Determine widths by UIkit 'width' classes
$sizes = $image->sizes([
	"uk-width-1-2@m",
	"uk-width-1-3@xl",
]);
// (min-width: 960px) 50vw, (min-width: 1600px) 33.33vw

// Return the portrait size rule
$sizes = $image->sizes(true);
// (orientation: portrait) and (max-width: {maxWidth}px) 50vw

// The arguments above are a demonstration, not a recommendation!

Pageimage::render()

This module extends the options available to this method with:

  • srcset: When the module is installed, this will always be added, unless set to false. Any values in the formats described above can be passed.
  • sizes: Only used if specified. Any values in the formats described above can be passed.
  • uk-img: If passed, as either true or as a valid uk-img value, then this attribute will be added. The srcset attribute will also become data-srcset.

Please refer to the API Reference for more information about this method.

// Render an image using the default set rules
echo $image->render();
// <img src='image.jpg' alt='' srcset='{default set rules}'>

// Render an image using custom set rules
echo $image->render(["srcset" => "480, 1240x640"]);
// <img src='image.jpg' alt='' srcset='image.480x0-srcset.jpg 480w, image.1240x640-srcset.jpg 1240w'>

// Render an image using custom set rules and sizes
// Also use the `markup` argument
echo $image->render("<img class='image' src='{url}' alt='Image'>", [
	"srcset" => "480, 1240",
	"sizes" => [1240 => 50],
]);
// <img class='image' src='image.jpg' alt='Image' srcset='image.480x0-srcset.jpg 480w, image.1240x640-srcset.jpg 1240w' sizes='(min-width: 1240px) 50vw'>

// Render an image using custom set rules and sizes
// Enable uk-img
echo $image->render([
	"srcset" => "480, 1240",
	"sizes" => ["uk-child-width-1-2@m"],
	"uk-img" => true,
]);
// <img src='image.jpg' alt='' data-uk-img data-srcset='image.480x0-srcset.jpg 480w, image.1240x640-srcset.jpg 1240w' sizes='(min-width: 960px) 50vw'>

// Render an image using portrait mode
// Default rule sets used: 320, 640, 768, 1024, 1366, 1600
// Portrait widths used: 320, 640, 768
// Original image is 1000px wide
// Not possible to use portrait mode and custom sets or portrait widths in render()
// Sizes attribute automatically added
echo $image->render(["srcset" => true]);
// <img src='image.jpg' alt='' srcset='image.320x569-srcset-hidpi.jpg 320w, image.640x1138-srcset-hidpi.jpg 640w, image.768x1365-srcset-hidpi.jpg 768w, image.jpg 1024w' sizes='(orientation: portrait) and (max-width: 768px) 50vw'>

Configuration

To configure this module, go to Modules > Configure > PageimageSrcset.

Set Rules

These are the default set rules that will be used when none are specified, e.g. when calling the property: $image->srcset.

Each set rule should be entered on a new line, in the format {width}x{height} {inherentwidth}w|{resolution}x.

Not all arguments are required - you will probably find that specifying the width is sufficient for most cases. Here's a few examples of valid set rules and the sets they generate:

Set Rule Set Generated Arguments Used
320 image.320x0-srcset.jpg 320w {width}
480x540 image.480x540-srcset.jpg 480w {width}x{height}
640x480 768w image.640x480-srcset.jpg 768w {width}x{height} {inherentwidth}w
2048 2x image.2048x0-srcset.jpg 2x {width} {resolution}x

How you configure your rules is dependent on the needs of the site you are developing; there are no prescriptive rules that will meet the needs of most situations. This article gives a good overview of some of the things to consider.

When you save your rules, a preview of the sets generated and an equivalent method call will be displayed to the right. Invalid rules will not be used, and you will be notified of this.

Portrait Mode

Set Widths

A comma limited list of widths to create HiDPI/Retina portrait variations for.

Crop Ratio

The portrait ratio that should be used to crop the image. The default of 9:16 should be fine for most circumstances as this is the standard portrait ratio of most devices. However, you can specify something different if you want. If you add a landscape ratio, it will be switched to portrait when used.

Any crops in the set rules ({width}x{height}) are ignored for portrait mode variations as this ratio is used instead.

UIkit Widths

If your website theme uses UIkit, you can pass an array of UIkit width classes to Pageimage::sizes to be converted to sizes. The values stored here are used to do this. If you have customised the breakpoints on your theme, you should also customise them here.

Please note that only 1- widths are evaluated by Pageimage::sizes, e.g. uk-width-2-3 will not work.

Remove Variations

If checked, the image variations generated by this module are cleared on Submit. On large sites, this may take a while. It makes sense to run this after you have made changes to the set rules.

Image Suffix

You will see this field when Remove Variations is checked. The value is appended to the name of the images generated by this module and is used to identify variations. You should not encounter any issues with the default suffix, but if you find that it conflicts with any other functionality on your site, you can set a custom suffix instead.

Debug Mode

When this is enabled, a range of information is logged to pageimage-srcset.

PageimageSrcsetDebug.js is also added to the <head> of your HTML pages. This will console.log a range of information about the images and nodes using srcset on your page after a window.onresize event is triggered. This can assist you in debugging your implementation.

The browser will always use the highest resolution image it has loaded or has cached. You may need to disable browser caching to determine whether your set rules are working, and it makes sense to work from a small screen size and up. If you do it the other way, the browser is going to continue to use the higher resolution image it loaded first.

UIkit Features

This module implements some additional features that are tailored towards UIkit being used as the front-end theme framework, but this is not required to use the module.

Installation

  1. Download the zip file at Github or clone the repo into your site/modules directory.
  2. If you downloaded the zip file, extract it in your sites/modules directory.
  3. In your admin, go to Modules > Refresh, then Modules > New, then click on the Install button for this module.

ProcessWire >= 3.0.123 is required to use this module.

  • Like 17
  • Thanks 2

Share this post


Link to post
Share on other sites

@nbcommunication what a great module! Thank you.

Just a quick one:

I've noticed that in the renderImageSrcset() method you are setting the uk-img attribute as data-uk-img but I'm pretty certain it should in fact be uk-img as this is what I've always used and is stated in the documents here: https://getuikit.com/docs/image

Update: Also, I've noticed that if you are using uk-img it outputting data-srcset as well as srcset. The srcset should be omitted as uk-img adds the srcset attribute when required.

Edited by alexmercenary
Update

Share this post


Link to post
Share on other sites

Hi @alexmercenary,

"uk-img" doesn't validate as HTML5. I always use the data- prefix for this reason, it's one of the ways to use UIkit components: https://getuikit.com/docs/javascript#component-usage.

As for the srcset attribute - I think they've updated the docs here, they had it without the data- prefix until recently. I'll update this when I get a chance - the current implementation will still work.

Cheers,

Chris

Share this post


Link to post
Share on other sites

@nbcommunication ok cool. That's interetsing. Yeah, I've noticed this, it's due to the lack of img src tag when using uk-img isn't it?

But what I noticed when I used data- prefix is that the images weren't lazy loading when checking the waterfall on the network panel and scrolling down the page.

Share this post


Link to post
Share on other sites

Hi @alexmercenary - aye I didn't have the "uk-img" enabled by way of the data-src attribute. I've fixed that now, should be on the repo.

Worth noting that enabling uk-img changes the src attribute to data-src, and adds a src attribute with a blank pixel: src='data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw=='. The src attribute is required for valid HTML5, so I've been in the habit of adding this blank pixel for this purpose.

  • Like 1

Share this post


Link to post
Share on other sites

With the default settings, running this:

echo $page->image->render(["srcset" => true, "uk-img" => true]);

Outputs this:

<img src='/myprocesswire/site/assets/files/1/la1.jpg' alt='' data-uk-img data-srcset='/myprocesswire/site/assets/files/1/la1.320x569-srcset-hidpi.jpg 320w, /myprocesswire/site/assets/files/1/la1.640x1138-srcset-hidpi.jpg 640w, /myprocesswire/site/assets/files/1/la1.768x1365-srcset-hidpi.jpg 768w, /myprocesswire/site/assets/files/1/la1.1024x557-srcset.jpg 1024w, /myprocesswire/site/assets/files/1/la1.2048x1115-srcset.jpg 2x' sizes='(orientation: portrait) and (max-width: 768px) 50vw'>

Notice how "src" is not "data-src" as per UIkit's documentation:
https://getuikit.com/docs/image#srcset

As a result, according to Chrome DevTools network graph, 2 images are loaded as in the attached screenshot.

Shouldn't 'data-' be added to 'src' in UIkit mode?

2019-11-20_11-25-23.png

Share this post


Link to post
Share on other sites

Hi @Jonathan Lahijani,

I'm not seeing this with the latest version (0.0.7) - I get the data-src attribute and the src attribute is the blank pixel gif:

<img data-src='/site/assets/files/1033/placeholder-city.webp' alt='' data-uk-img src='data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==' data-srcset='/site/assets/files/1033/placeholder-city.320x569-srcset-hidpi.jpg 320w, /site/assets/files/1033/placeholder-city.640x1138-srcset-hidpi.jpg 640w, /site/assets/files/1033/placeholder-city.768x1365-srcset-hidpi.jpg 768w, /site/assets/files/1033/placeholder-city.webp 1024w' data-sizes='(orientation: portrait) and (max-width: 768px) 50vw'>

It isn't actually necessary to pass "srcset" as true by the way. This is actually telling the module to use portrait mode:

echo $page->image->render(["uk-img" => true]);
// Should return the above <img> tag but without the "sizes" attribute.

The render() method is a bit limited unfortunately - you can't access all the options that can be accessed by using $page->image->srcset() and $page->image->sizes(). However, what you are trying to do should work - are you on the latest version?

Cheers,

Chris

Share this post


Link to post
Share on other sites

Hey @nbcommunication!

Just wondering: do you think it would make sense to implement picture support into this module, or do you see that as a completely unrelated thing? 🙂

The background is that I'm currently looking into ways of handling webp+srcset. Since IE and Safari don't support webp, a fallback is necessary, yet none of the .htaccess fallback solutions are (in my opinion) really up to the task. Every solution I've found so far comes with drawbacks that would eventually cause issues for our clients.

Best solution so far seems to be <picture> with fallback <img> element. I could build a (very simple) markup module that just outputs the picture element for me (it's not a whole lot of boilerplate, but still a bit bothersome to write all over the place), but then it occurred to me that since I'm going to need this module anyway, wouldn't it be awesome if I could just call Pageimage::render() and this module would handle the rest.

What do you think? 😅

Share this post


Link to post
Share on other sites

Hi @teppo,

I've not used <picture> myself, so will need time to do a bit of research. Off the top of my head though, I do feel that this module wouldn't necessarily be the best place for it.

When I get a chance I'll have a think through the implications.

Cheers,

Chris

  • Like 1

Share this post


Link to post
Share on other sites

Hello @nbcommunication,

Thank you for this module. I'm using it to generate all the images on my website I'm building. Using hannacode, I'm even using it to generate the img markup from a textarea (like the blog_body) which is pretty neat!

I'm wondering if you could consider incorporating an option where instead of pointing the src to the original jpeg file, the module would instead use one of the srcset images that it generated (maybe the largest setting or the user selectable size)? The reason why I'm interested in this option is that my original images are very large and I've currently disallowed access to the original jpeg (using htaccess lockout that I found in this forum). I plan to have a download original image later on for customers so that why I need the original image on the website.

Is this doable? Thank you for reading.

Regards,

montero4

Share this post


Link to post
Share on other sites

Hi @montero4,

Can you please give a code example? From your description, it seems to me that all you need to do is resize the pageimage before rendering/getting attributes.

Cheers,

Chris

Share this post


Link to post
Share on other sites

@teppo, having read a bit about <picture>, it probably would make sense to provide this functionality in the module, but possibly as a separate method distinct from render(). 

I’ve got a fair bit I want to do on this module, but it’s behind a lot of other work at the moment. I’ll add this to the todo list, but for the time being, I would go with writing something for your own use. 

Cheers,

Chris

Share this post


Link to post
Share on other sites

Thanks @nbcommunication, makes sense!

If I happen to find time for this I might send you a pull request for this feature, but no pressure – I've got plenty of stuff on my plate as well, and even if I do send such a PR, it's perfectly fine if you don't think the suggested solution is good enough... 😛

  • Like 1

Share this post


Link to post
Share on other sites

For folk using the module - is the configuration of sets in the textarea working OK for you? I've been mulling over trying to build something a bit more user-friendly, like a kind of repeater field for entering data, but I'm not convinced that it would actually be easier to work with, particularly as I usually only enter an image width per line and that's it.

In a future version I want to add the configuration on a per-field basis (maybe even per-image even though that would be overkill), so I want to get the configuration method as solid as possible first.

Perhaps retaining the textarea, but with a live preview would be the best option?

I'm also not sure whether it is useful to have portrait mode and UIkit widths as config options. Ultimately the module is meant to extend Pageimage so that srcset and sizes can be used - I feel these config options are a result of my own bias in how I use the module, and yet I don't think I've used the portrait option at all!

Any ideas/thoughts you have, please come with them!

Cheers,

Chris

  • Like 1

Share this post


Link to post
Share on other sites
19 hours ago, nbcommunication said:

Hi @montero4,

Can you please give a code example? From your description, it seems to me that all you need to do is resize the pageimage before rendering/getting attributes.

Hello @nbcommunication,

Here is a sample output being rendered on the page

<img src="/site/assets/files/1633/ve08195.jpg" alt="Beach Resort" srcset="/site/assets/files/1633/ve08195.480x181-srcset.jpg 480w, /site/assets/files/1633/ve08195.1240x468-srcset.jpg 1240w" sizes="(orientation: portrait) and (max-width: 768px) 50vw">
 

I wonder if instead of using "/site/assets/files/1633/ve08195.jpg" as the src, there could be a user selectable option to use the max size for the src, as in "/site/assets/files/1633/ve08195.1240x468-srcset.jpg" instead? It might also make sense for user to maybe select the smallest size if that works with some lazy loading scripts that does progressive loading(?).

Currently in my setup, the original image cannot be accessed if the user attempts to paste the actual address on the browser. I wonder what the SEO impact is of doing this, so I'm not completely happy with this current setup... However...last night, I actually figured out a way to assemble the markup for <img> using some string manipulations on the output of the your module (although I haven't implemented it yet), so maybe my original request is no longer necessary? It would be easier though if the module had this option out of the box.

Thank you and regards,

 

Share this post


Link to post
Share on other sites
5 hours ago, nbcommunication said:

For folk using the module - is the configuration of sets in the textarea working OK for you?

I'm also not sure whether it is useful to have portrait mode and UIkit widths as config options.

I thought based on the module overview that you had that "It does not handle images rendered in CKEditor or similar fields." So with your question above, does it work on the textarea? I'm completely new to PW and php/html/css so maybe I'm misunderstanding your question. If yes, please ignore and no need to reply :-) I'm using hannacode in the ckeditor textarea to generate the srcset and it's working fine for me. My size settings are still not final, but it's so easy to change later so I'm not worried. I could also delete all the past srcset images using your module (that's why I love your module and I'm using it to generate all the image markup on the website). If I need a different srcset configuration set, I could always create a different hannacode, so I think it's going to be fine.

I haven't read enough on the portrait mode to know if I'm going to use this feature.

Regards,

Edited by montero4
too rushed in my reply.

Share this post


Link to post
Share on other sites
On 2/1/2020 at 2:28 AM, montero4 said:

Hello @nbcommunication,

Here is a sample output being rendered on the page

<img src="/site/assets/files/1633/ve08195.jpg" alt="Beach Resort" srcset="/site/assets/files/1633/ve08195.480x181-srcset.jpg 480w, /site/assets/files/1633/ve08195.1240x468-srcset.jpg 1240w" sizes="(orientation: portrait) and (max-width: 768px) 50vw">

I wonder if instead of using "/site/assets/files/1633/ve08195.jpg" as the src, there could be a user selectable option to use the max size for the src, as in "/site/assets/files/1633/ve08195.1240x468-srcset.jpg" instead? It might also make sense for user to maybe select the smallest size if that works with some lazy loading scripts that does progressive loading(?).

 

Hi @montero4,

I'm sorry, I'm still not following? There's nothing stopping you changing the src - you should resize the image first:

// Get the image
$image = $page->images->first;

// Resize the image
$image = $image->size(1024, 468);

// Output the image
echo "<img src='$image->url' alt='$image->description' srcset='$image->srcset'>";

// Or alternatively
echo $image->render();

PageimageSrcset recognises that it is an image variation and then uses the original to generate srcset variations.

It isn't really this module's job to handle the src attribute. In theory you could do some manipulations of the "srcset" value to extract the first or last image for use, but I'd say it is a lot cleaner just to resize the image.

Cheers,

Chris

  • Like 1

Share this post


Link to post
Share on other sites

Hi @nbcommunication

Thank you for your reply. That's a neat solution. I didn't realize that if you resized or manipulated an image, it's -that- variation image that gets used as the src in the <img> tag. That actually makes sense. However, in my case, that approach wouldn't work because I'm disallowing access to the original jpeg images through an htaccess lockout method posted by horst in this forum. The way that method works is that it disallows all access to .jpeg files unless it has a certain suffix (like -piacontain, -pim2-full,-blogthumb, etc.). I want the jpegs to therefore have the "-srcset" suffix so that it is accessible.

Here's the solution I came up with for future reference as the approach might help other people.

	//assemble img markup
    $image = $page->image;
    $string = $image->srcset("1200"); //create srcset of image 1200px wide
    $address = explode(" ", $string);
    $address = $address[0];
    
    //create srcset using pageimagesrcset module default settings
    $srcset = $image->srcset;
    
    echo "<img src=\"$address\" alt=\"$alt_text\" srcset=\"$srcset\">";


	The result of above code:

	<img src="/pw/site/assets/files/1070/test.1200x619-srcset.jpg" alt="alt_test" srcset="/pw/site/assets/files/1070/test.320x165-srcset.jpg 320w, /pw/site/assets/files/1070/test.640x330-srcset.jpg 640w, /pw/site/assets/files/1070/test.768x480-srcset.jpg 960w, /pw/site/assets/files/1070/test.1200x619-srcset.jpg 1200w">

This approach works and the htaccess gatekeeper lets the image request go through, but if a user attempts to access test.jpg directly, then it will not pass through. Thank you for module. As mentioned, I'm using it to serve all the images on my website.

Regards,

  • Like 2

Share this post


Link to post
Share on other sites

Hi @montero4,

That all makes sense. You can also do the following:

// Create an image variation 1200px wide with -srcset suffix
$image = $page->image->width(1200, ["suffix" => "srcset"]);
echo "<img src='$image->url' alt='$alt_text' srcset='$image->srcset'>";
// PageimageSrcset will use the original to generate the srcset value

If you have a look at the Pageimage options, you can add a suffix to the filename when resizing.

Cheers,

Chris

  • Like 2

Share this post


Link to post
Share on other sites

I have two questions:

1. Why does this code:

$content .= $img->render([
    'alt'=> $img->name,
    'height' => $img->height,
    'width' => $img->width,
    'srcset' => '883, 687, 369',
    ]);

generate this where I have the portrait sizes setting even though I haven't set the portrait mode on?

<img src="/site/assets/files/1185/image.691x499.jpg" 
    alt="image" 
    srcset="/site/assets/files/1185/image.369x266-srcset.jpg 369w,
            /site/assets/files/1185/image.687x496-srcset.jpg 687w, 
            /site/assets/files/1185/image.jpg 883w" 
    sizes="(orientation: portrait) and (max-width: 768px) 50vw">

How is the portrait mode set on? I think, it needs 

'portrait' => true
or
srcset('true')

2. render should extend PageImage::render, but  the width or height attributes don't remain in my code with the above example. Why is that?

Share this post


Link to post
Share on other sites

Hi @lpa,

Apologies for the late response. I've had a look at this...

Number 2 - width and height attributes not rendering - this isn't anything to do with PageimageSrcset. These options, when passed to Pageimage::render(), resize the image, but don't get rendered as attributes. If you want this behaviour, adding a markup option should do the trick:

$content .= $img->render([
    'alt'=> $img->name,
    'height' => $img->height,
    'width' => $img->width,
    'srcset' => '883, 687, 369',
	'markup' => "<img src='{url}' alt='{alt}' width='{width}' height='{height}' />"
    ]);

As for portrait mode, I'm not getting this when I test. I get:

<img 
     src='/site/assets/files/1033/placeholder-city.691x499.1000x667.webp'
     alt='placeholder-city.jpg'
     srcset='
             /site/assets/files/1033/placeholder-city.369x266-srcset.webp 369w,
             /site/assets/files/1033/placeholder-city.687x496-srcset.webp 687w,
             /site/assets/files/1033/placeholder-city.691x499.webp 883w'
>

In your example, the image isn't being resized as portrait, so it is odd that the sizes attribute is being added.

What settings do you have in the module config for Portrait mode? Are you on the latest version of the module (1.01)?

Cheers,

Chris

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Gadgetto
      SnipWire - Snipcart integration for ProcessWire
      Snipcart is a powerful 3rd party, developer-first HTML/JavaScript shopping cart platform. SnipWire is the missing link between Snipcart and the content management framework ProcessWire.
      With SnipWire, you can quickly turn any ProcessWire site into a Snipcart online shop. The SnipWire plugin helps you to get your store up and running in no time. Detailed knowledge of the Snipcart system is not required.
      SnipWire is free and open source licensed under Mozilla Public License 2.0! A lot of work and effort has gone into development. It would be nice if you could donate an amount to support further development:

      Status update links (inside this thread) for SnipWire development
      2020-07-03 -- SnipWire 0.8.7 (beta) released! Fixes some small bugs and adds an indicator for TEST mode 2020-04-06 -- SnipWire 0.8.6 (beta) released! Adds support for Snipcart subscriptions and also fixes some problems 2020-03-21 -- SnipWire 0.8.5 (beta) released! Improves SnipWires webhooks interface and provides some other fixes and additions 2020-03-03 -- SnipWire 0.8.4 (beta) released! Improves compatibility for Windows based Systems. 2020-03-01 -- SnipWire 0.8.3 (beta) released! The installation and uninstallation process has been heavily revised. 2020-02-08 -- SnipWire 0.8.2 (beta) released! Added a feature to change the cart and catalogue currency by GET, POST or SESSION param 2020-02-03 -- SnipWire 0.8.1 (beta) released! All custom classes moved into their own namespaces. 2020-02-01 -- SnipWire is now available via ProcessWire's module directory! 2020-01-30 -- SnipWire 0.8.0 (beta) first public release! (module just submitted to the PW modules directory) 2020-01-28 -- added Custom Order Fields feature (first SnipWire release version is near!) 2020-01-21 -- Snipcart v3 - when will the new cart system be implemented? 2020-01-19 -- integrated taxes provider finished (+ very flexible shipping taxes handling) 2020-01-14 -- new date range picker, discount editor, order notifiactions, order statuses, and more ... 2019-11-15 -- orders filter, order details, download + resend invoices, refunds 2019-10-18 -- list filters, REST API improvements, new docs platform, and more ... 2019-08-08 -- dashboard interface, currency selector, managing Orders, Customers and Products, Added a WireTabs, refinded caching behavior 2019-06-15 -- taxes provider, shop templates update, multiCURL implementation, and more ... 2019-06-02 -- FieldtypeSnipWireTaxSelector 2019-05-25 -- SnipWire will be free and open source Plugin Key Features
      Fast and simple store setup Full integration of the Snipcart dashboard into the ProcessWire backend (no need to leave the ProcessWire admin area) Browse and manage orders, customers, discounts, abandoned carts, and more Multi currency support Custom order and cart fields Process refunds and send customer notifications from within the ProcessWire backend Process Abandoned Carts + sending messages to customers from within the ProcessWire backend Complete Snipcart webhooks integration (all events are hookable via ProcessWire hooks) Integrated taxes provider (which is more flexible then Snipcart own provider) Useful Links
      SnipWire in PW modules directory SnipWire Docs (please note that the documentation is a work in progress) SnipWire @GitHub (feature requests and suggestions for improvement are welcome - I also accept pull requests) Snipcart Website  

       
      ---- INITIAL POST FROM 2019-05-25 ----
       
    • By Sten
      Hello
      Till now I hacked something with the twig template but it works no more with new PW versions so I look forward to create a module. I am working on a site in multiple languages : French, English, Italian, German, Spanish, Portuguese, Hebrew, Russian. The new posts are entered in any language with a field for language. Till now, I got twig files to get the translations with constants defined for each part of the pages.
      So I'd like to create a module to include theses files added according to the url /fr/en/...
      Have you some observations to do before I begin about the direction to take ?
      Thank you
    • By ukyo
      Mystique Module for ProcessWire CMS/CMF
      Github repo : https://github.com/trk/Mystique
      Mystique module allow you to create dynamic fields and store dynamic fields data on database by using a config file.
      Requirements
      ProcessWire 3.0 or newer PHP 7.0 or newer FieldtypeMystique InputfieldMystique Installation
      Install the module from the modules directory:
      Via Composer:
      composer require trk/mystique Via git clone:
      cd your-processwire-project-folder/ cd site/modules/ git clone https://github.com/trk/Mystique.git Module in live reaction with your Mystique config file
      This mean if you remove a field from your config file, field will be removed from edit screen. As you see on youtube video.
      Using Mystique with your module or use different configs path, autoload need to be true for modules
      Default configs path is site/templates/configs/, and your config file name need to start with Mystique. and need to end with .php extension.
      Adding custom path not supporting anymore !
      // Add your custom path inside your module class`init` function, didn't tested outside public function init() { $path = __DIR__ . DIRECTORY_SEPARATOR . 'configs' . DIRECTORY_SEPARATOR; Mystique::add($path); } Mystique module will search site/modules/**/configs/Mystique.*.php and site/templates/Mystique.*.php paths for Mystique config files.
      All config files need to return a PHP ARRAY like examples.
      Usage almost same with ProcessWire Inputfield Api, only difference is set and showIf usage like on example.
      <?php namespace ProcessWire; /** * Resource : testing-mystique */ return [ 'title' => __('Testing Mystique'), 'fields' => [ 'text_field' => [ 'label' => __('You can use short named types'), 'description' => __('In file showIf working like example'), 'notes' => __('Also you can use $input->set() method'), 'type' => 'text', 'showIf' => [ 'another_text' => "=''" ], 'set' => [ 'showCount' => InputfieldText::showCountChars, 'maxlength' => 255 ], 'attr' => [ 'attr-foo' => 'bar', 'attr-bar' => 'foo' ] ], 'another_text' => [ 'label' => __('Another text field (default type is text)') ] ] ]; Example:
      site/templates/configs/Mystique.seo-fields.php <?php namespace ProcessWire; /** * Resource : seo-fields */ return [ 'title' => __('Seo fields'), 'fields' => [ 'window_title' => [ 'label' => __('Window title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'attr' => [ 'placeholder' => __('Enter a window title') ] ], 'navigation_title' => [ 'label' => __('Navigation title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'showIf' => [ 'window_title' => "!=''" ], 'attr' => [ 'placeholder' => __('Enter a navigation title') ] ], 'description' => [ 'label' => __('Description for search engines'), 'type' => Mystique::TEXTAREA, 'useLanguages' => true ], 'page_tpye' => [ 'label' => __('Type'), 'type' => Mystique::SELECT, 'options' => [ 'basic' => __('Basic page'), 'gallery' => __('Gallery'), 'blog' => __('Blog') ] ], 'show_on_nav' => [ 'label' => __('Display this page on navigation'), 'type' => Mystique::CHECKBOX ] ] ]; Searching data on Mystique field is limited. Because, Mystique saving data to database in json format. When you make search for Mystique field, operator not important. Operator will be changed with %= operator.
      Search example
      $navigationPages = pages()->find('my_mystique_field.show_on_nav=1'); $navigationPages = pages()->find('my_mystique_field.page_tpye=gallery');
    • By Robin S
      This is a module I made as an experiment a while ago and never got around to releasing publicly. At the time it was prompted by discussions around using Repeater fields for "page builder" purposes, where the depth feature could possibly be used for elements that would be nested inside other elements. I thought it would be useful to enforce some depth rules and translate the depth data into a multi-dimensional array structure.
      I'm not using this module anywhere myself but maybe it's useful to somebody.
      Repeater Depth Helper
      This module does two things relating to Repeater fields that have the "Item depth" option enabled:
      It enforces some depth rules for Repeater fields on save. Those rules are:
      The first item must have a depth of zero. Each item depth must not be more than one greater than previous item depth. It provides a RepeaterPageArray::getDepthStructure helper method that returns a nested depth structure for a Repeater field value.
      Helper method
      The module adds a RepeaterPageArray::getDepthStructure method that returns a multi-dimensional array where the key is the page ID and the value is an array of nested "child" items, or null if there are no nested children.
      Example

      The module doesn't make any assumptions about how you might want to use the depth structure array, but here is a way you might use it to output a nested unordered list.
      // Output a nested unordered list from a depth structure array function outputNestedList($depth_structure, $repeater_items) { $out = "<ul>"; foreach($depth_structure as $page_id => $nested_children) { $out .= "<li>" . $repeater_items->get("id=$page_id")->title; // Go recursive if there are nested children if(is_array($nested_children)) $out .= outputNestedList($nested_children, $repeater_items); $out .= "</li>"; } $out .= "</ul>"; return $out; } $repeater_items = $page->my_repeater; $depth_structure = $repeater_items->getDepthStructure(); echo outputNestedList($depth_structure, $repeater_items);
       
      https://github.com/Toutouwai/RepeaterDepthHelper
      https://modules.processwire.com/modules/repeater-depth-helper/
    • By MoritzLost
      Cacheable Placeholders
      This module allows you to have pieces of dynamic content inside cached output. This aims to solve the common problem of having a mostly cacheable site, but with pieces of dynamic output here and there.  Consider this simple example, where you want to output a custom greeting to the current user:
      <h1>Good morning, <?= ucfirst($user->name) ?></h1> This snippet means you can't use the template cache (at least for logged-in users), because each user has a different name. Even if 99% of your output is static, you can only cache the pieces that you know won't include this personal greeting. A more common example would be CSRF tokens for HTML forms - those need to be unique by definition, so you can't cache the form wholesale.
      This module solves this problem by introducing cacheable placeholders - small placeholder tokens that get replaced during every request. The replacement is done inside a Page::render hook so it runs during every request, even if the response is served from the template cache. So you can use something like this:
      <h1>Good morning, {{{greeting}}}</h1> Replacement tokens are defined with a callback function that produces the appropriate output and added to the module through a simple hook:
      // site/ready.php wire()->addHookAfter('CachePlaceholders::getTokens', function (HookEvent $e) { $tokens = $e->return; $tokens['greeting'] = [ 'callback' => function (array $tokenData) { return ucfirst(wire('user')->name); } ]; $e->return = $tokens; }); Tokens can also include parameters that are parsed and passed to the callback function. There are more fully annotated examples and step-by-step instructions in the README on Github!
      Features
      A simple and fast token parser that calls the appropriate callback and runs automatically. Tokens may include multiple named or positional parameters, as well as multi-value parameters. A manual mode that allows you to replace tokens in custom pieces of cached content (useful if you're using the $cache API). Some built-in tokens for common use-cases: CSRF-Tokens, replacing values from superglobals and producing random hexadecimal strings. The token format is completely customizable, all delimiters can be changed to avoid collisions with existing tag parsers or template languages. Links
      Github Repository & documentation Module directory If you are interested in learning more, the README is very extensive, with more usage examples, code samples and usage instructions!
×
×
  • Create New...