kongondo

Module
Visual Page Selector (commercial page picker module for ProcessWire)

22 posts in this topic

Visual Page Selector

Released 31 March 2016

https://processwireshop.pw/plugins/visual-page-selector/

 
*******************************************************   ORIGINAL POST   *******************************************************

Introducing VPS, a commercial visual page field selector. 

This is a pre-sale closed-beta version. This post is WIP and will be updated now and then.

############################

Many ProcessWire users use the 'one image per page' principle to manage and reuse images across their sites. This works fine. However, for site editors who mainly work with images, especially for larger sites, it is sometimes difficult to remember the pages where particular images reside. This module helps to solve this challenge.

Harnessing the awesomeness  that is ProcessWire, VPS provides a rich editing experience, enabling editors to search for, view, select, add, remove and delete page-images easily, in an easy to use and friendly interface. ProcessWire Lister is the workhorse behind the lightning-fast searches. Editors will be able to search for images by their descriptions, names, partial names, page names, templates, etc. 

Current Features

  1. Single-image mode
  2. Full search
  3. Batch add/Remove/Delete Image/Delete Page in page fields
  4. Image Browser
  5. Selectable pages as per page field settings + Lister filters
  6. Grid and List View
  7. Draggable sorting
  8. Responsive (almost fully :-)..iframes!)

Planned Features

  1. Multi-image mode (there are times you want to group similar images in multi-image field in one page; e.g. the back, front and side of a car photo)
  2. Configurable CSS on the fly resizing vs real image resizing (image resizing can quickly hog memory)
  3. Other as per feedback from beta testing

FAQs

When will this be available? 

Soon.

How much will it cost?

Reasonably priced. Announcement soon.

Where will I be able to buy this from?

At all fine stores that stock quality ProcessWire products :-)

Do we really need another page field/inputfield select?

See links below.

What type of licenses will be available?

Soon to be announced.

Can I beta test this?

Thanks for the interest but all available slots have been taken.

Video (excuse the video quality please - too many takes....)


Screens

post-894-0-74508200-1443695262_thumb.png

post-894-0-08547400-1443695199_thumb.png

post-894-0-57554100-1443696381_thumb.png

post-894-0-91846400-1443695208_thumb.png

post-894-0-93252500-1443695213_thumb.png

post-894-0-23311500-1443695244_thumb.png

Previous Discussions

https://processwire.com/talk/topic/10927-wishlist-select-pages-by-thumbnail/

Edited by kongondo
official release
21 people like this

Share this post


Link to post
Share on other sites

Yesssss, I am so excited about this. :D This was the only real stumbling block to using PW for a bunch of projects.

1 person likes this

Share this post


Link to post
Share on other sites

support only pages with single image only?

How about multiple images of a page ?

Planned Features

  • Multi-image mode (there are times you want to group similar images in multi-image field in one page; e.g. the back, front and side of a car photo)

:)  ;)

1 person likes this

Share this post


Link to post
Share on other sites
Visual Page Selector (VPS) module demo and documentation (coming soon)

For now, please refer to the README.txt file in your VPS folder

Would you mind making the README available to prospective purchasers? Likewise the README for Media Manager?

Share this post


Link to post
Share on other sites

Can do, and was gonna do it but thought it is easier for guys to watch the demo videos (as I finish the documentation...)...to understand what's going on :-)

Share this post


Link to post
Share on other sites

Hi all,

I'm going to be away for the next couple of weeks (4-5 weeks possibly) with little if any access to the internet. I will deal with any queries on my return.

Thanks

Share this post


Link to post
Share on other sites

I am back. Might be a while before I go through all pending issues.

On 24/08/2016 at 0:46 PM, gerritvanaaken said:

I get an error message because there is no fancybox present in PW 3.0 ...

@gerritvanaaken. The module is not yet PW 3+ ready...but it will be once we have a stable release of that version of PW, thanks.

Share this post


Link to post
Share on other sites

Hi @kongondo

I have a few pre-purchase questions:

1. Is a PW3-compatible version of Visual Page Selector very far off? How about Media Manager - is that PW3-compatible?

2. Could you say a bit about how the use cases would differ for Visual Page Selector versus Media Manager? They seem similar in many ways (or similar in terms of image management - I know that MM supports more than just images).

3. Media Manager includes an upload feature to go from image files on my computer to page-per-image pages in PW. Does Visual Page Selector have a similar upload feature? If not, how do you recommend images are loaded to pages?

4. One of the main things that appeals to me about the page-per-image approach used in VPS/MM is the ability to add custom fields to the page used to hold the image. But I saw that you commented in the MM thread:

On 8/08/2016 at 0:57 AM, kongondo said:

Custom fields: Yes if you add them directly to the templates but you will not be able to edit those custom fields using the MM interface. In addition, MM pages are hidden in the admin so editing your custom fields will not be ideal (or accessible to normal users). Alternatively, you can use images/files native description and tag fields. These are currently editable directly in your Media Library.

So would VPS be a better option if the editing of custom fields is needed?

5. The demo video for VPS doesn't show if the page holding the image may be opened for editing from the VPS field. In other words, can I click the thumbnail or image title and open the page? Does it open in a modal window?

Thanks,
Robin.

1 person likes this

Share this post


Link to post
Share on other sites

Hi @Robin S,

Thanks for your interest in VPS and MM.

  1. My plan is for these to be ready within 3 weeks. However, some users of MM have reported successfully using it in PW 3 with no hiccups. 
  2. @see below please
  3. No, VPS does not have an upload feature since it functions as a 'normal' page field...i.e. it does not have a central repository of media but includes images you've uploaded yourself to any number of named image fields (named in the settings of VPS
  4. Custom fields: Yes, VPS would be better in that case, although the other benefits of MM probably outweigh this one advantage
  5. No, you can't, currently

#2 Differences between VPS and MM

Media Manager is a complete digital asset management for 4 types of media: audio, document, image and video. Media are stored and managed in one central repository. Uploading, editing and publication of media are tightly controlled by various permissions. Media can be uploaded to a waiting area before uploading to your Media Library. Media can be previewed (e.g. listen to a MP3 file), edited, tagged, filtered, etc with great ease. Media can be inserted in a page in two ways: in a field or in a CKEditor RTE. Media can be infinitely reused across your site. Media Manager has its own API for frontend use.

Visual Page Selector is mainly targeted to those who 'consciously' use  the one page per image approach. It is an Inputfield for Pagefields. Its purpose is to remove the guess work in site editors' minds when they have to include 'pages' in a 'page' in situations where those 'pages' are included on the 'page' for the sole purpose of accessing and reusing images found in those 'pages' (wow, a mouthful, sorry!). VPS does this by offering a visual selector where the editors can see the images contained in those 'pages'.  VPS does not have its own API...it is a Pagefield, hence is accessed like any other Pagefield in ProcessWire.

Hence, the two modules are quite different from each other actually. In MM, your editors don't know and don't care that they are actually dealing with pages. All they see are media, easily accessible via a single Media Library. VPS is a visual interface to a normal Pagefield. This means you will need to set it up like any other Pagefield, with one or two extra details you have to tell it, for instance, the name of the 'image field(s) in the 'pages'. If, on the other hand, you would like a streamlined workflow for your media management, from uploads to inclusion in pages, managing tens or hundreds or thousands of media, all in a single easy to use interface, then MM is for you. 

 

Hope this answers your question. Sorry, I have just seen that I never availed the READMEs for this modules as per your request. I can still send these to you if you wish. Please let me know if you require any more info. 

Cheers.

 

 

2 people like this

Share this post


Link to post
Share on other sites

Thanks for the answers @kongondo.

Both Media Manager and Visual Page Selector look like useful and clever modules, although the cost/features ratio favours MM.

I think what would be really fantastic is something in between the feature set of MM and VPS, and this could perhaps be accomplished by borrowing some of the features developed for MM into VPS.

To explain, something I think PW is missing is custom fields for images (and I'm not alone: this GitHub request from today has 4 upvotes in 2 hours). There are loads of use cases for this, but one example: you are using images in your site that have a Creative Commons Attribution license. To fulfill the terms of the license each image needs the following fields attached: Author (text), Source link (URL), License (Page select), License link (URL, although in fact you'd probably store the URL for each license in the License page field). The ImageExtra module only supports textarea custom fields so it's not the right solution. What would work is a page-per-image approach with the custom fields for the image stored in the image's page. VPS is a big step towards making this a workable solution, but to use this as a replacement for a standard image field some extra features are needed beyond what is currently offered...

1. There needs to be an easy way to edit the image's custom fields from the Page inputfield. A modal link to Page Edit is all that's needed to begin with - this is something that's possible with existing inputfields such as AsmSelect. Somewhere down the line this could maybe be enhanced with AJAX loading of the custom fields into the list view of VPS, as per repeaters (just dreaming here).

2. There needs to be an easy way to add an image (page) from the inputfield. This is possible with most existing Page inputfields if the template and parent for allowed pages is defined. Basic support for this would be to open the Add Page form in a modal (the Page Field Edit Links module does something like this). But to be a closer match to existing image field functionality it would be nice to be able to upload multiple images at once. This feature is in MM - could it be added to VPS? (when template and parent are defined for the field).

3. There needs to be an easy way to embed an image into CKEditor. This feature is in MM - could it be added to VPS?

Really keen to hear your thoughts on this. Thanks!

 

4 people like this

Share this post


Link to post
Share on other sites

Hi @Robin S,

Just acknowledging that I've seen this. Really pressed for time currently but would like to give a comprehensive answer, so hope you can wait a bit longer? In summary though, I think I might be able to add some of the features you've suggested (though some might take a while...a long while to implement). My biggest constraint is time (cliche, I know) though,...not lack of willingness :)

 

1 person likes this

Share this post


Link to post
Share on other sites

Thanks for the reply; no hurry at all.

Am currently getting by using PageTable for page-per-image images, and when I get time I will explore Inputfield Selectize also as that looks like it would be good for the task.

One last question for now: do you offer an upgrade path for your commercial modules? That is, if I purchase a Single license and find that I love it and want to use it on all my projects can I pay an upgrade fee to move to a Developer license?

 

Share this post


Link to post
Share on other sites
1 hour ago, Robin S said:

One last question for now: do you offer an upgrade path for your commercial modules? That is, if I purchase a Single license and find that I love it and want to use it on all my projects can I pay an upgrade fee to move to a Developer license?

 

Yes I do. You'd only have to pay the difference. You'd have to send me an email to arrange that. Thanks.

1 person likes this

Share this post


Link to post
Share on other sites

Hi Kongondo, i'm looking for a popup page selector, that would show the pages in a lister – but in my case sometimes no image is needed, only the list - is that something that VPS can do, or could it be something made configurable for the module;  Out of all of the various page pickers, one that i seem to be in need of is a lister style popup, which could be very useful where you have to select a page, but need to see some columns to know what you are picking, and the ability to sort, and filter the selectable pages...

Share this post


Link to post
Share on other sites

Hi @Macrura,

Sorry for the very late response. Currently, VPS cannot do that. However, if you want a custom solution based on VPS, we could discuss that separately. 

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 joshuag
      Introducing our newest [commercial] module:
      Recurme
      Processwire Recurring Dates Field & Custom Calendar Module.
      http://www.99lime.com/modules/recurme/
      One Field to Recur them ALL…
      A Recurring Dates InputField for your Processwire templates. The InputField you’ve been waiting for.
      Complex RRule date repeating in a simple and fast user interface.
      Use the super simple, & powerful API to output them into your templates.
      example:
      <? // easy to get recurring events $events = $recurme->find(); // events for this day $events = $recurme->day(); // events for this week $events = $recurme->week(); // events for this month $events = $recurme->month(); ?> <? // Loop through your events foreach($events as $event){ echo $event->title; echo $event->start_date; echo $event->rrule; echo $event->original->url; ... } ?> Unlimited Custom Calendars.
      Imagine you could create any calendar you wanted on your website. Use recurring events with the Recurme field, or use your own Processwire pages and date fields to render calendars… it’s up to you. Fully customizable. Make as many calendars as you like. Get events from anywhere. Recurme does all the hard date work for you.
      Unlimited Custom Admin Calendars too.
      Hope you like it  ,
       Joshua & Eduardo from 99Lime.
       




    • By valan
      At our site we use both email and phone authorizations at frontend. To make life easier, I've developed HelperPhone pack that handles phone numbers. This pack includes following modules for ProcessWire CMS/CMF:
      FieldtypePhoneNumber: module that stores phone numbers InputfieldPhoneNumber: module that renders inputfield for phone numbers HelperPhone: module that loads PhoneNumber and PhoneNumberConst classes, and 'libphonenumber' namespace All these modules require included PW WireData-derived class PhoneNumber and PhoneNumberConst.
      PhoneNumber class is a thin wrapper over giggsey/libphonenumber-for-php, itself is port of Google's libphonenumber. PhoneNumberConst class stores constants, used by PhoneNumber class Usage: PhoneNumber class
      $phone = '8 (916) 318-07-29 ext 1234'; // input string could be in any phone-recognizable format $phoneNumber = new PhoneNumber($phone, 'RU'); // or wire('modules')->get('HelperPhone')->makePhoneNumber($phone, 'RU'); echo ($phoneNumber->isValidNumber() ? 'Yes':'No'); // Yes echo ($phoneNumber->isValidNumberForRegion($regionCode) ? 'Yes':'No'); // Yes echo $phoneNumber->getNumberTypeTitle(); // Mobile echo $phoneNumber->getCountryCode(); // 7 echo $phoneNumber->getRegionCode(); // RU echo $phoneNumber->getNationalNumber(); // 9163180729 echo $phoneNumber->getExtension(); // 1234 echo $phoneNumber->formatForCallingFrom('US') // 011 7 916 318-07-28 echo $phoneNumber->formatForCallingFrom('GE') // 00 7 916 318-07-28
      For more methods and properties please refer to PhoneNumber and PhoneNumberConst source files. Need more? Check giggsey/libphonenumber-for-php and use it by accessing $phoneNumber->phoneNumber property - it is instance of \libphonenumber\PhoneNumber or null (if empty).
      Usage: field
      Note: on field creation, make sure that you've configured field settings
      Default region: assumed region if input phone number string is not in international format (starts with '+', etc)
      Enabled/disabled phone extentions: if disabled, phone extension will be removed on field save.
      Phone field settings in example below: default region code 'RU', phone extensions are enabled
      echo $page->phone; // +79163180729 // Note1: $page->phone stores instance of PhoneNumber and renders to string in E164 format. // Note2: E164 format does not include extension. echo $page->getFormatted('phone'); // +7 916 318-07-29 ext. 1234 echo $page->getUnformatted('phone'); // +79163180729 echo $page->phone->format(PhoneNumberConst::RFC3966); // tel:+7-916-318-07-29;ext=1234 echo $page->phone->getNationalNumber(); // 9163180729 Usage: PW selectors
      FieldtypePhoneNumber is instance of FieldtypeText. It stores phone numbers and extensions as string in E164 format with #extention (if provided by user and enabled in settings) E.g. in db it looks like this: '+79163180729#1234'. This makes it easy to query fields as any text field.
      echo $pages->find([     'template' => 'my_temlate',     'phone^=' => '+79163180729', ]); // will echo page ids where phone starts with '+79163180729' Finally
      I've decided to put it here first and later to Modules directory (based on your feedbacks).
      GitHub: https://github.com/valieand/HelperPhone
      Enjoy
    • By justb3a
      Little admin helper module: Using this module you can view all template cache settings at once. E.g. cache status, cache time (configurable). Furthermore it adds the functionality to clear the entire template cache or just the template cache for a given template. Note that this may cause a temporary delay for one or more requests while pages are re-cached.

       
      GitHub: https://github.com/justb3a/processwire-templatecacheoverview
    • By Steven Veerbeek
      Hi,
      I am trying to create a module for a webshop in which I can predefine a number of thumbnail sizes for my product images. I was thinking of storing each of these image sizes as a child page with 'width' and 'height' fields under the module page , so I can use a PageTable input field in my module to easily manage them.
      I know how to create a Pagetable field and add it to templates so I can use it in regular pages, but because I am planning on implementing some other functionalities that (I think) can't be achieved with a regular page, I need the PageTable field to work within a module.
      So far I have come up with this piece of code by trial and error:
      $page = $this->page; $field_sizes = $this->modules->get("InputfieldPageTable"); $field_sizes->title = "image_sizes"; $field_sizes->label = "Image sizes"; $field_sizes->set('parent_id', $page->id); $template = wire("templates")->get("image_size"); $field_sizes->set('template_id', $template->id); $field_sizes->set('columns', "title\nimage_width\nimage_height"); $wrapper->add($field_sizes); It works in that it does display an empty PageTable in my module. I can also add pages and they will be added as child pages under my module page, but when I do, the way the PageTable is displayed gets all messed up. Instead of showing the newly created page as a row in the PageTable, all the fields on the module page (including the PageTable field itself) are repeated within the PageTable field.
      I hope my explanation makes sense. I am fairly new to Processwire (and module development in particular) so perhaps I am just trying to use PageTable in a way it was not intended to be. Maybe you guys could give me some directions on how to achieve what I am looking for?
      Thanks!
    • By abdus
      After this tutorial you'll have learned how to:
      Build a Process module Make an AJAX request to backend Serve JSON as response Let's say you want to display the latest orders in a dashboard that you can access from admin panel. And you want it to refresh its content with a button click. Most straightforward and proper way (that I know of) is to create a Process module, as they're built for this purpose.
      First, create a directory under /site/modules/, call it ProcessDashboard, and create a file named ProcessDashboard.module under that directory. Following is about the least amount of code you need to create a Process module.
      <?php namespace ProcessWire; class ProcessDashboard extends Process { public static function getModuleInfo() { return [ 'title' => 'Orders Dashboard', 'summary' => 'Shows latest orders', 'version' => '0.0.1', 'author' => 'abdus', 'autoload' => true, // to automatically create process page 'page' => [ 'name' => 'order-dashboard', 'title' => 'Orders', 'template' => 'admin' ] ]; } public function ___execute() { return 'hello'; } } Once you refresh module cache from Modules > Refresh, you'll see your module. Install it.

      It will create an admin page under admin (/processwire/) and will show up as a new item in top menu, and when you click on it, it will show the markup we've built in execute() function.

       
      All right, now let's make it do something useful. Let's add create a data list to display latest orders. We'll change execute() function to render a data table.
      public function ___execute() { /* @var $table MarkupAdminDataTable */ $table = $this->modules->MarkupAdminDataTable; $table->setID($this->className . 'Table'); // "#ProcessDashboardTable" $table->headerRow([ 'Product', 'Date', 'Total' ]); // fill the table foreach ($this->getLatest(10) as $order) { $table->row([ $order['title'], $order['date'], $order['total'] ]); } // to refresh items $refreshButton = $this->modules->InputfieldSubmit; $refreshButton->name = 'refresh'; $refreshButton->id = $this->className . 'Refresh'; // "#ProcessDashboardRefresh" $refreshButton->value = 'Refresh'; // label of the button return $table->render() . $refreshButton->render(); } where getLatest() function finds and returns the latest orders (with only title, date and total fields)
      protected function getLatest($limit = 5, $start = 0) { // find last $limit orders, starting from $start $orders = $this->pages->find("template=order, sort=-created, limit=$limit, start=$start"); // Only return what's necessary return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total ]; }); } When you refresh the page, you should see a table like this

      Now we'll make that Refresh button work. When the button is clicked, it will make an AJAX request to ./latest endpoint, which will return a JSON of latest orders. We need some JS to make AJAX request and render new values. Create a JS file ./assets/dashboard.js inside the module directory.
      window.addEventListener('DOMContentLoaded', function () { let refresh = document.querySelector('#ProcessDashboardRefresh'); let table = document.querySelector('#ProcessDashboardTable'); refresh.addEventListener('click', function (e) { // https://developer.mozilla.org/en/docs/Web/API/Event/preventDefault e.preventDefault(); // Send a GET request to ./latest // http://api.jquery.com/jquery.getjson/ $.getJSON('./latest', { limit: 10 }, function (data) { // check if data is how we want it // if (data.length) {} etc // it's good to go, update the table updateTable(data); }); }); function renderRow(row) { return `<tr> <td>${row.title}</td> <td>${row.date}</td> <td>${row.total}</td> </tr>`; } function updateTable(rows) { table.tBodies[0].innerHTML = rows.map(renderRow).join(''); } }); And we'll add this to list of JS that runs on backend inside init() function
      public function init() { $scriptUrl = $this->urls->$this . 'assets/dashboard.js'; $this->config->scripts->add($scriptUrl); } Requests to ./latest will be handled by ___executeLatest() function inside the module, just creating the function is enough, PW will do the routing. Here you should notice how we're getting query parameters that are sent with the request.
      // handles ./latest endpoint public function ___executeLatest() { // get limit from request, if not provided, default to 10 $limit = $this->sanitizer->int($this->input->get->limit) ?? 10; return json_encode($this->getRandom($limit)); } Here getRandom() returns random orders to make it look like there's new orders coming in. 
      protected function getRandom($limit = 5) { $orders = $this->pages->find("template=order, sort=random, limit=$limit"); return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total ]; }); } And we're done. When refresh button is clicked, the table is refreshed with new data.
      Here it is in action: 
      2017-04-29_19-01-40.mp4 (227KB MP4, 0m4sec)
      Here's the source code:
      https://gist.github.com/abdusco/2bb649cd2fc181734a132b0e660f64a2
       
      [Enhancement] Converting page titles to edit links
      If we checkout the source of MarkupAdminDataTable module, we can see we actually have several options on how columns are built.
      /** * Add a row to the table * * @param array $a Array of columns that will each be a `<td>`, where each element may be one of the following: * - `string`: converts to `<td>string</td>` * - `array('label' => 'url')`: converts to `<td><a href='url'>label</a></td>` * - `array('label', 'class')`: converts to `<td class='class'>label</td>` * @param array $options Optionally specify any one of the following: * - separator (bool): specify true to show a stronger visual separator above the column * - class (string): specify one or more class names to apply to the `<tr>` * - attrs (array): array of attr => value for attributes to add to the `<tr>` * @return $this * */ public function row(array $a, array $options = array()) {} This means, we can convert a column to link or add CSS classes to it.
      // (ProcessDashboard.module, inside ___execute() method) // fill the table foreach ($this->getLatest(10) as $order) { $table->row([ $order['title'] => $order['editUrl'], // associative -> becomes link $order['date'], // simple -> becomes text [$order['total'], 'some-class'] // array -> class is added ]); } Now, we need to get page edit urls. By changing getLatest() and getRandom() methods to return edit links in addition to previous fields
      protected function getLatest($limit = 5, $start = 0) { // find last $limit orders, starting from $offset $orders = $this->pages->find("template=order, sort=-created, limit=$limit, start=$start"); return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total, 'editUrl' => $order->editUrl ]; }); } protected function getRandom($limit = 5) { $orders = $this->pages->find("template=order, sort=random, limit=$limit"); return $orders->explode(function ($order) { return [ 'title' => $order->title, 'date' => date('Y-m-d h:i:s', $order->created), 'total' => $order->total, 'editUrl' => $order->editUrl ]; }); } and tweaking JS file to render first column as links
      function renderRow(row) { return `<tr> <td><a href="${row.editUrl}">${row.title}</a></td> <td>${row.date}</td> <td>${row.total}</td> </tr>`; } we get a much more practical dashboard.