Jump to content

Insert multiple images - Shift +Click


Greg Lumley
 Share

Recommended Posts

Hi! I've just discovered Processwire and I'm absolutely loving how clean it is. Especially with the full control over what it outputs. 

Excuse me if this is a really stupid question.

What happens if a user wants to insert multiple images into the blog field? In other words Shift+Click all the images attached to a specific page in and insert. It seems I can insert one at a time but not multiple.

Based on the above, I want to rebuild my website. I'm a photographer (ex php dev 2004) and plan also to target websites at other photographers. So inserting multiple images into blog posts is a key part. I'd like to output that to something like UIkit or some kind of Masonry Gallery script. Any thoughts would be fantastic please. 

Thank you.

Greg. 

I'm an ex PHP developer now photographer, now thanks to Corona and not photo work, a rusty PHP developer 😁

Link to comment
Share on other sites

Hey Greg,

First of all, welcome to the forums! Quick question, is your images field set to Automatic (single item or null when max...) ? I just tested with an image field in my template and after clicking "choose file", shift clicking allows me to select/upload multiple files. 

Link to comment
Share on other sites

Hi Louise, thank you for the really fast response. 😁

I should have been clearer, I'm able to upload multiple images without a problem. I can't place multiple images at once though. 

In other words, if I have 20 images already uploaded, can I grab all of them and drop them. This would be important in a gallery situation. One wouldn't want to individually place each image. Especially if there are quite a few. 

Does that make more sense? 🙂

 1681735737_Screenshot2020-05-0615_24.18_cr.thumb.png.aa9b2b6abf22f1dc124e9ebf6c9d9ee0.png

Link to comment
Share on other sites

Sounds like a reasonable feature request. I’m assuming you’re using CKEditor?

In the meantime, have you considered outputting directly from the image field? That is, looping through the images in your template and generating the markup that way. If you’re doing a gallery of all images on the page, or maybe all images with a certain tag, that seems like the way to go. It would also give you more control over the presentation, for example if you need clicked images to open in a lightbox or something.

  • Like 1
Link to comment
Share on other sites

I am using CKEditor 🙂 I must be honest I was more curious than anything. I realise it's not the right way to do it. I've come from Wordpress which I'm just getting tired of. That's what I really like about PW .. nice neat and clean input and output. 

Thank you for the suggestion I had a feeling I could output through the image field, I've seen tags but not sure how it's all put together... yet. 

I'm getting my head around PW at the moment. 

Thank you for your help. 
 

  • Like 2
Link to comment
Share on other sites

6 hours ago, Greg Lumley said:

I'm an ex PHP developer now photographer, now thanks to Corona and not photo work, a rusty PHP developer

Hi @Greg Lumley, welcome to the forums. This is funny, for me it is the other way round. Coming from photography I more and more moved into the field of programming. 🙂

If you don't mind, I can point you to some spots and third party modules in the context that I, as a photographer, find very useful in PW.

  • Like 1
Link to comment
Share on other sites

Just now, horst said:

Hi @Greg Lumley, welcome to the forums. This is funny, for me it is the other way round. Coming from photography I more and more moved into the field of programming. 🙂

If you don't mind, I can point you to some spots and third party modules in the context that I, as a photographer, find very useful in PW.

Hi Horst, that would be fantastic!

Thank you! 

Link to comment
Share on other sites

Ok, when working with image fields, you have many useful functions right with the core image field, and / or you can use third party modules.

At first, you should enable the imagick rendering engine under modules > core > image. (Your webserver need to support this) Also you can enable the animated gif engine. The engines get invoked by inspected image filetypes. It do no harm to have more then the default fallback based on GD-lib.

With the core image fields you can enable/disable a lot of features, like limiting the amount of images, allow upload of multiple images via ZIP, make use of focus point & zoom!, and many more.

When it comes to cropping, you have many different ways to choose from. I prefer using the focus point and template code, assisted by PIA.

You can use the built in crop functionality for manually create and name crop variations, but if you do, go and add the ImageCropRatios module to the toolbox. With it you can define fixed ratios.

Another way can be to use the CroppableImage4 module. (module board of CAI3) With it you can define crop ratios per template basis. Also interesting, the CAI4 extends the core image field, what lets you use all functionalities in one field. You can make use of the focus & zoom in one template, and use predefined crops in another.

If you once have a need for individual image manipulation, there is a module too.

Thats the toolbox that I use or select from, but there are a lot more in regard of the variation filenames, EXIF data. There are modules that create a lightbox gallery out of the box, and more.

But best is to know how the core pageimage work, in template scope and elsewhere!

---------------------------------------------------------------------------------- 

More:

https://modules.processwire.com/modules/process-media-manager/

 

 

  • Like 3
Link to comment
Share on other sites

9 hours ago, Greg Lumley said:

In other words, if I have 20 images already uploaded, can I grab all of them and drop them. This would be important in a gallery situation. One wouldn't want to individually place each image.

For a gallery of images you wouldn't want to insert the images separately into the CKEditor field. You'd want to loop over all the images in the field and output markup for each of them. A typical approach would be to show thumbnail images linked to larger images that display in a JS lightbox (I like to use Fresco), so your template code might look like this (assumes your images field is named "images"):

<?php if($page->images->count): ?>
	<div class="gallery">
		<?php foreach($page->images as $image): ?>
			<a href="<?= $image->maxSize(1000,1000)->url ?>" class="fresco" data-fresco-caption="<?= $image->description ?>">
				<img src="<?= $image->size(300,300)->url ?>" alt="<?= $image->description ?>">
			</a>
		<?php endforeach; ?>
	</div>
<?php endif; ?>

So the simplest scenario is if your blog text and gallery are separate from each other - e.g. the gallery appears before or after the text. This way you just output the gallery and text separately in your template file.

Chances are that's what you want to do, but here are a couple of other scenarios and possible solutions...

1. You want to optionally insert one gallery somewhere within the blog text. In other words, you want some text, followed by the gallery, followed by some more text.

One way to do this would be to have two CKEditor fields in your template, labelled "Before gallery" and "After gallery". You divide your text between these two fields. The two CKEditor fields and the images field are all output directly by code in your template file.

Another way is to have a single CKEditor field use the Hanna Code module to insert the gallery somewhere in the text. You would create a PHP Hanna tag named "gallery" and use the gallery code shown above for the tag. Then you'd insert [[gallery]] in your CKEditor field wherever you want the gallery to appear.

 

2. You want to insert multiple galleries somewhere within the blog text.

If you stump up some $$ to buy the excellent ProFields module you could use the included Repeater Matrix module to create separate matrix types for Text and Gallery. Then you just add alternating Text and Gallery items to the page as needed to build up the blog post content.

Another approach for this that is a bit more advanced but that doesn't cost anything is to use a standard Repeater field for the galleries. You would add an Images field and the Title field to the Repeater field and create a Repeater item for each gallery on the page. Then you'd use Hanna Code to insert the galleries within a single CKEditor field. And to make it easier to select a gallery in the Hanna tag you can use the Hanna Code Dialog module.

The "gallery" Hanna tag would have a "title" attribute and the code would look like this:

<?php $repeater_item = $page->galleries->findOne("title=$title"); ?>
<?php if($repeater_item->id): ?>
	<div class="gallery">
		<?php foreach($repeater_item->images as $image): ?>
			<a href="<?= $image->maxSize(1000,1000)->url ?>" class="fresco" data-fresco-caption="<?= $image->description ?>">
				<img src="<?= $image->size(300,300)->url ?>" alt="<?= $image->description ?>">
			</a>
		<?php endforeach; ?>
	</div>
<?php endif; ?>

And the Hanna Code Dialog hook in /site/ready.php to build the dialog form would look like this:

$wire->addHookAfter('HannaCodeDialog::buildForm', function(HookEvent $event) {

	// The Hanna tag that is being opened in the dialog
	$tag_name = $event->arguments(0);

	// The page open in Page Edit
	/* @var Page $edited_page */
	$edited_page = $event->arguments(1);

	// The form rendered in the dialog
	/* @var InputfieldForm $form */
	$form = $event->return;

	if($tag_name === 'gallery') {
		$modules = $event->wire('modules');
		$gallery_titles = $edited_page->galleries->explode('title');
		/* @var InputfieldSelect $f */
		$f = $modules->InputfieldSelect;
		$f->name = 'title';
		$f->id = 'title';
		$f->label = 'Gallery title';
		$f->addOptions($gallery_titles, false);
		$form->add($f);
	}

});

And this would give you an interface in Page Edit that looks like this (when the Hanna Code dialog is open):

2020-05-07_102831.thumb.png.14d019e0b9afc79bddf9b5008e65728a.png

  • Like 12
  • Thanks 1
Link to comment
Share on other sites

Thank you everyone! All this info is awesome!

This feels like the old days. Anyone remember 4guysFromRolla? 1999 ish... 

I learned so much from that forum, long before the days of Youtube, Apache and PHP were a nightmare to setup and CGI was king.

 

 

  • Like 2
Link to comment
Share on other sites

22 hours ago, Robin S said:

For a gallery of images you wouldn't want to insert the images separately into the CKEditor field. You'd want to loop over all the images in the field and output markup for each of them. A typical approach would be to show thumbnail images linked to larger images that display in a JS lightbox (I like to use Fresco), so your template code might look like this (assumes your images field is named "images"):


<?php if($page->images->count): ?>
	<div class="gallery">
		<?php foreach($page->images as $image): ?>
			<a href="<?= $image->maxSize(1000,1000)->url ?>" class="fresco" data-fresco-caption="<?= $image->description ?>">
				<img src="<?= $image->size(300,300)->url ?>" alt="<?= $image->description ?>">
			</a>
		<?php endforeach; ?>
	</div>
<?php endif; ?>

So the simplest scenario is if your blog text and gallery are separate from each other - e.g. the gallery appears before or after the text. This way you just output the gallery and text separately in your template file.

Chances are that's what you want to do, but here are a couple of other scenarios and possible solutions...

1. You want to optionally insert one gallery somewhere within the blog text. In other words, you want some text, followed by the gallery, followed by some more text.

One way to do this would be to have two CKEditor fields in your template, labelled "Before gallery" and "After gallery". You divide your text between these two fields. The two CKEditor fields and the images field are all output directly by code in your template file.

Another way is to have a single CKEditor field use the Hanna Code module to insert the gallery somewhere in the text. You would create a PHP Hanna tag named "gallery" and use the gallery code shown above for the tag. Then you'd insert [[gallery]] in your CKEditor field wherever you want the gallery to appear.

 

2. You want to insert multiple galleries somewhere within the blog text.

If you stump up some $$ to buy the excellent ProFields module you could use the included Repeater Matrix module to create separate matrix types for Text and Gallery. Then you just add alternating Text and Gallery items to the page as needed to build up the blog post content.

Another approach for this that is a bit more advanced but that doesn't cost anything is to use a standard Repeater field for the galleries. You would add an Images field and the Title field to the Repeater field and create a Repeater item for each gallery on the page. Then you'd use Hanna Code to insert the galleries within a single CKEditor field. And to make it easier to select a gallery in the Hanna tag you can use the Hanna Code Dialog module.

The "gallery" Hanna tag would have a "title" attribute and the code would look like this:


<?php $repeater_item = $page->galleries->findOne("title=$title"); ?>
<?php if($repeater_item->id): ?>
	<div class="gallery">
		<?php foreach($repeater_item->images as $image): ?>
			<a href="<?= $image->maxSize(1000,1000)->url ?>" class="fresco" data-fresco-caption="<?= $image->description ?>">
				<img src="<?= $image->size(300,300)->url ?>" alt="<?= $image->description ?>">
			</a>
		<?php endforeach; ?>
	</div>
<?php endif; ?>

And the Hanna Code Dialog hook in /site/ready.php to build the dialog form would look like this:


$wire->addHookAfter('HannaCodeDialog::buildForm', function(HookEvent $event) {

	// The Hanna tag that is being opened in the dialog
	$tag_name = $event->arguments(0);

	// The page open in Page Edit
	/* @var Page $edited_page */
	$edited_page = $event->arguments(1);

	// The form rendered in the dialog
	/* @var InputfieldForm $form */
	$form = $event->return;

	if($tag_name === 'gallery') {
		$modules = $event->wire('modules');
		$gallery_titles = $edited_page->galleries->explode('title');
		/* @var InputfieldSelect $f */
		$f = $modules->InputfieldSelect;
		$f->name = 'title';
		$f->id = 'title';
		$f->label = 'Gallery title';
		$f->addOptions($gallery_titles, false);
		$form->add($f);
	}

});

And this would give you an interface in Page Edit that looks like this (when the Hanna Code dialog is open):

2020-05-07_102831.thumb.png.14d019e0b9afc79bddf9b5008e65728a.png

Thank you Robin for your incredible answer. You've virtually given me a tutorial. This thread is gold! 

  • Like 2
Link to comment
Share on other sites

  • 2 weeks later...
  • 2 months later...

Is there a way to simply select more images at once when adding them right inside the body-text? I can add images one by one no problem, so I would think that selecting more at once when adding them isn't too far fetched. Any more ideas on this issue?

EDIT:

The solution described above is rather for image galleries. I understand this can facilitate the upload procedure, upload to different galleries, repeated with a repeater-field and then included to the HTML with Hanna Code without the need of selecting images one by one anymore. 

This works fine when you know which images go above/below which text, but what if you want to upload all images at once to the page first (either to one field or more probably via FTP to the according /assets/file/page-folder/) and then, when entering/copy-pasting the text, select the images appropriately. If you have long articles (which is the case in my case) and up to 60 images, you still want to select more at once and not one-by-one.

Also, I checked for CK-Editor-updates on Github. The current CKEditor-version on PW is 1.6.3, not to be confused with CKEditor4 or 5 version-numbering – I guess the module's version that comes with any new PW-installation is the newest anyway? 

What about addons/plugins from the ckeditor-page itself? ckeditor.com/cke4/addons. Personally couldn't find anything that meets my needs.

Thanks for suggestions

Edited by fruid
additional info
Link to comment
Share on other sites

  • 2 months later...

* Admin Actions
https://modules.processwire.com/modules/process-admin-actions/
"FTP Files to Page Add files/images from a folder to a selected page."

* You can drag-drop the selected images from the computer's folder to the CKEditor field (perhaps using Ctrl-C and Ctrl-V also works).
The images are uploaded and inserted in the field, and are then added automatically to the first image field in the page (my experience).

Edited by Christophe
Link to comment
Share on other sites

  • 5 months later...
On 5/7/2020 at 12:34 AM, Robin S said:

<?php if($page->images->count😞 ?> <div class="gallery"> <?php foreach($page->images as $image😞 ?> <a href="<?= $image->maxSize(1000,1000)->url ?>" class="fresco" data-fresco-caption="<?= $image->description ?>"> <img src="<?= $image->size(300,300)->url ?>" alt="<?= $image->description ?>"> </a> <?php endforeach; ?> </div> <?php endif; ?>

Sorry, I wake up an old post, but it fits exactly my question:

I don't upload multiple photos with the editor, I upload them with an image field (heroimage). Will this work then too?

I have adjusted the code so, but unfortunately the output is missing:

<section class="slider">
    <ul class="slides">
        <?php if($page->heroimage->count): ?>
        <li>
            <?php foreach($page->heroimage as $image): ?>
            <img src="<?php echo $page->image->url; ?>" alt="<?php echo $page->image->description; ?>">
            <?php endforeach; ?>
        </li>
        <?php endif; ?>
    </ul>
</section>

The output is without error message, but unfortunately also without list:

<section class="slider">
    <ul class="slides">
    </ul>
</section>

 

Link to comment
Share on other sites

<?php foreach($page->heroimage as $image): ?>
<li>
  <img src="<?php echo $image->url; ?>" alt="<?php echo $image->description; ?>">
</li>
<?php endforeach; ?>

You might want to try this instead. In your foreach() the $image has to be adressed and not the $page->image. And also the <li> should probably be in there too.

  • Like 1
Link to comment
Share on other sites

No, that unfortunately does not work either. The result looks this way:

<section class="slider">
    <ul class="slides">
                <li>
            <img src="" alt="">
        </li>
                <li>
            <img src="" alt="">
        </li>
                <li>
            <img src="" alt="">
        </li>
                <li>
            <img src="" alt="">
        </li>
                <li>
            <img src="" alt="">
        </li>
                <li>
            <img src="" alt="">
        </li>
                <li>
            <img src="" alt="">
        </li>
                <li>
            <img src="" alt="">
        </li>
                <li>
            <img src="" alt="">
        </li>
            </ul>
</section>

Uploaded were 2 photos, 10 list items returned blank.

The name of the field is correct. When I start the photo single it is not displayed either.

<img src="<?php echo $heroimage->url; ?>" alt="<?php echo $heroimage->description; ?>">

Is it perhaps because the field is a multiple field and I am uploading multiple files (Maximum allowed number of files: 5)? That's why I took foreach, so that the list items build up based on the number of photos. I need it for the Materialize CSS Slider, it's built up in a simple list, one list item per photo.

Link to comment
Share on other sites

Your $page->heroimage seems to be something else than an array of pageimages... Are you using tracy? Then a bd($page->heroimage) could bring light into the dark 😉 

Link to comment
Share on other sites

I have installed Tracy, but I don't understand how to use it? The options are massive. I assume that if there are any errors, Tracy will show them in the front or back end? But, no errors displayed. Then maybe it's not a code error!?

Maybe the 'Images' field does not can handle multiple photos? Maybe I need a ProFields repeater for this?

I don't use any additional scripts, except the CSS framework, which could cause the error, which is not shown. The slider is already in Materialize:
materializecss.com/media.html#slider

Link to comment
Share on other sites

Just edit your page in the backend and then go to the tracy console and enter this:

db($page);

You should see a dump of your page, something like this:

jysOdZQ.png

Then type dump($page->heroimage) and show us the results.

Link to comment
Share on other sites

There is nothing in the backend to Tracy. There are only two entries in the modules directory: Tracy Debugger + Process Tracy Adminer. I have viewed both, but find no option for a debugger. The help unfortunately also gives no information about the use, no 'go on'.

Link to comment
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
 Share

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By prestoav
      Hi all,
      I've noticed that, when creating new users for clients, the chosen admin theme is not saved. For example, I create a new user select Reno or UIKit as the theme at point of creation and save. When logging in that user for the first time the admin theme is back to default. Changing it again and saving corrects this.

      Anyone else noticed this or is it a known bug at the moment?

      CMS V 3.0.156.

      Thanks!
    • By AndZyk
      Hello,
      this maybe a simple question, but it bothers me for a while now:
      There used to be a warning, if two or more user try to edit the same page. But ever since AdminThemeUIkit I haven't seen it any more.
      Is this a bug or are there special circumstances under which the warning will be displayed?
      If I am logged-in in the same browser with one default and one privat window, I don't see this warning. But also different browsers on different machines in the same network don't see this warning.
      I was looking for the blog post on which this feature was announced, but couldn't find it anymore.
      We had the case, that two people were writing a text for the same page, but after person A saved the page first, the text of the person B was lost. I know we could have used ProDrafts for this case, but it shouldn't happen in the first place.
      I would appreciate some feedback. 😀
      Regards, Andreas
    • By SwimToWin
      I have a website that allows users to create their personal "website" (a page with sub-pages).
      Users shall be able to:
      Log in (frontend and/or admin), Edit "their" page(s) - I am using the "Page Edit Per User"-module (https://modules.processwire.com/modules/page-edit-per-user/) to grant access to the relevant pages Create child pages - possible? Users shall not be able to see other pages in the admin interface - "Admin Restrict Page Tree" may do the trick (https://modules.processwire.com/modules/admin-restrict-page-tree/)? Frontend editing shall be possible - I am considering "Fredi" (https://modules.processwire.com/modules/fredi/) for this. The challenge is that it takes a lot of modules and configuration.
      Is there a way to set this up that doesn't require a lot of configuration for each new user?
    • By benbyf
      Hello, having trouble getting PW to save my user or field in cron hook.
      It seems to report the same field info each time unchanged. It should be counting down in seconds.
      public function init() { // set to every30Seconds in settings $this->defaultInterval = $this->cron_check; // add hooks to CRON $this->addHookAfter("LazyCron::{$this->defaultInterval}", $this, 'checkUserSubscription'); } public function ___checkUserSubscription(HookEvent $e){ // seconds since last lazycron $seconds = $e->arguments[0]; $log = wire('log'); $field = $this->exclusiveRole; // users with specific role and field $users = $this->users->find("roles=$field"); foreach ($users as $user) { // get stored time $currentTime = $user->get($this->fieldName); // if time not null if($currentTime){ // evalute stored time minus time past $resultTime = intval($currentTime) - intval($seconds); $log->message("result ".$resultTime); // save user page $user->set($this->fieldName, $resultTime); $this->users->save($user); } } }  
    • By benbyf
      HELLO! having user Role issues.
      I've got a Role:  members and a template that is set to only allow view of Members and to redirect anyone else to / but id redircts Member users still currently, and only alows people to view the page if the template is set to view on the guest role also.
      Any help would be appreciated. I'm running  ProcessWire 3.0.62



×
×
  • Create New...