Jump to content
Martijn Geerts

FieldtypeSelectFile & InputfieldSelectFile

Recommended Posts

FieldtypeSelectFile & InputfieldSelectFile

Inputfield Select File is an Inputfield & Fieldtype to select a single file or folder and stores the name and / or use the selected file as page template. The last option enables the editor to use multiple views for a page, depending on the selected template.

Settings

  • The folder containing the files and/or folders.
    • A relative path relative to the /site/templates/ folder.
  • Hide file extensions
  • Hide files
  • Hide folders
  • Natural Sort (Select options)
    • Sort files and folders in natural ordering (PHP >= 5.4.0)
  • Change Page Template

    • Just before the Page::loaded event the selected file is set as template file for the page. This setting can only be applied once per a page and folders are exluded from the select inputfield.

      Note that a page with no associated template file will render with the selected file.

When to use ?

Let editors select a file and base your own logic upon this. With the change page template setting you're able to use the selected file as template file. This could reduce the amount of normal templates needed and let editors choose how the page get rendered. There are plenty of use cases for this Inputfield.

In the examples I call the field selected_file.

// let the editor choose a CSS file
$config->styles->append($config->urls->templates . "styles/" . $page->selected_file);

/**
 * advanced usage example
 *
 * You need multiple ways to render your markup. Let the site editor choose which
 * file the page need to render.
 *
 */

$tpl = new TemplateFile($config->paths->templates . "includes/" . $page->selected_file);
$tpl->set('current', $page);
$markup = $tpl->render();

(It could be a real good companion with InputfieldSelector)

Download at GitHub

Modules directory

Edited by Martijn Geerts
  • Like 18

Share this post


Link to post
Share on other sites

this is great...! i was trying to write this module about 2 months ago and couldn't figure out how to do it..

edit: brilliant, works perfectly, and even works using ../ to get out of the templates folder... this is going to be extremely useful for html5 video, selecting files to be used instead of uploading to processwire page.... and in other situations where we want to store large media assets somewhere else in the filesystem..

many thanks for this.

  • Like 4

Share this post


Link to post
Share on other sites

having an issue with this, the select works fine, but the field doesn't save... any idea what might be causing that?

cheers!

Share this post


Link to post
Share on other sites

@Macrura, tnx for the report.

Are you  absolutely sure the value is not stored or is the value not pre-selected ?

I'll take a closer look, as soon if I have some little time.

Share this post


Link to post
Share on other sites

hi Martijn - i'm pretty sure the value is not stored; i ran a quick selector and the field is showing as empty...

  • Like 1

Share this post


Link to post
Share on other sites

Tnx for the followup !

Gonna test this weekend. 


I didn't thought people would use this fieldtype with ../ in the field settings, so I cleaned the values when I discovered this behaviour.

Normal users can't set those settings so I removed this checking and clearing of the data in the update. (can't think of doing real harm)

Thanks for finding this Macrura. The module is updated on Github.

Edited by Martijn Geerts
  • Like 1

Share this post


Link to post
Share on other sites

Sorry to hijack this thread, but if you are working with HTML5 video, have you seen my draft video fieldtype module:

https://processwire.com/talk/topic/4580-video-fieldtype/

@Adrian - looks really good! In the use case i have, my video page has options for youtube, vimeo or local video; with the local video, some of them were very large sizes so i didn't feel like bothering with the uploader; for the html5 video, i have mp4 and webm versions of both, plus the poster image...so i have a media folder in /site/ for all of those things.. having the ability to let the user select the video file makes this whole thing possible.. but i will look into your module for sure on future stuff and i'm redoing a site now and will probably upgrade my system to use your module... will comment on that thread soon!

  • Like 1

Share this post


Link to post
Share on other sites

@martijn, thanks for that update! this works for sure now with regular pages, only issue is that i can't seem to get it to work with repeaters, i looked at the code but nothing popped out at me as to why this would be the case..

Share this post


Link to post
Share on other sites

@Macrura

I don't see any issues here regarding using the field inside a repeater. Can you provide me with more information so I could replicate your situation ?

post-577-0-94317300-1402132451_thumb.png

Share this post


Link to post
Share on other sites

@Martijn, thanks, i'm not sure what the problem is, just can't get values to save in these repeaters i have;

i will keep testing/troubleshooting this; i tried changing the path, checking/unchecking the hide file extension, and i checked the database.. they just don't save..

thanks for you help.. nothing urgent...

Share this post


Link to post
Share on other sites

You may want to also check other modules that you may have installed recently. I had an issue where repeaters wouldn't save and it turned out to be an issue with a recently installed module.  I only figured it out by retracing my steps and uninstalling modules.

  • Like 1

Share this post


Link to post
Share on other sites

ok, figured it out, sorry for posting an error that wasn't really this module... it was something to do with the conditional visibility of fields that was breaking my repeater...

thanks again.. this is all sorted!

  • Like 2

Share this post


Link to post
Share on other sites

Little update on the module.

You can choose to list folders and or files. If you already had this module installed, be sure you check Hide folders and and save the field settings. Updated the first post in this thread.

  • Like 4

Share this post


Link to post
Share on other sites

@Martijn,

I was researching how to get this module to return an alphabetically sorted file list;

found some stuff on stack exchange and php about reading the files into an array and sorting...

$dh  = opendir($dir);
while (false !== ($filename = readdir($dh))) {
    $files[] = $filename;
}
sort($files);

just wondering if you might be up to being 'sponsored' to add that feature... can send beer $

Share this post


Link to post
Share on other sites

@Macrura:

I like your suggestion so updated the module with an option to use SORT_NATURAL on the options of the select. 

// Natural Sort (NOT checked)
image_1.jpg
image_12.jpg
image_21.jpg
image_4.jpg
 
// Natural Sort (checked)
image_1.jpg
image_4.jpg
image_12.jpg
image_21.jpg
 
 
  • Like 5

Share this post


Link to post
Share on other sites

@martijn, wow can't thank you enough; this module has come in handy so many times; this is a great enhancement to it.. thanks!!

BTW - just tested and it works perfectly!

  • Like 1

Share this post


Link to post
Share on other sites
Just pushed a (major) update which adds a new feature: Change Page Template.

Change Page Template:

Just before the Page::loaded event the selected file is set as template file for the page. This enables you to have multiple file templates for the same page, selectable by the editor. This setting can only be applied once per a page and folders are exluded from the select inputfield. Note that a page with no associated template file will render fine with a selected file. :-)

+ Changed the sorting from SORT_NATURAL flag to the natcasesort function because the flag requires PHP 5.4.0 or higher.

First post is modified & please report issues.

  • Like 2

Share this post


Link to post
Share on other sites

I am currently using this field for the first time and I love it! Really a useful little time saver!

One minor issue I found: I configured the folder path without a trailing slash. When editing a template i could see the files in the folder, but the field never saved the selected value. After adding a trailing slash to the foldername everything worked as expected. I did not see any warnings or errors on screen or in my logs.

Another thing I still could not figure out is, how to use this field with showIf field dependencies. Is this even possible? I would like to show some other fields only if a certain file is selected. 

Share this post


Link to post
Share on other sites

Could you change the line in the sanitizeValue method in The fieldtype to:

$file = $this->config->paths->templates . trim(trim($field->folderPath, '/')) . '/' . $value;

Then the first 'issue' should be fixed. (although it was mentioned in the notes below the setting)

For the second issue, I have no time to invest now... will look at it this weekend. (Could be related to the first.)

Share this post


Link to post
Share on other sites

Thanks Martijn! After changing the sanitizeValue method the trailing slash is no longer needed. 

Field dependencies still don't work, but I did not expect it either :) Thanks for looking into it, but in my current project I can totally live without it. It's just a "nice to have", and I wanted to give you some feedback.

  • Like 1

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 teppo
      Needed a really simple solution to embed audio files within page content and couldn't find a module for that, so here we go. Textformatter Audio Embed works a bit like Textformatter Video Embed, converting this:
      <p>https://www.domain.tld/path/to/file.mp3</p> Into this:
      <audio controls class="TextformatterAudioEmbed"> <source src="https://www.domain.tld/path/to/file.mp3" type="audio/mpeg"> </audio> The audio element has pretty good browser support, so quite often this should be enough to get things rolling 🙂
      GitHub repository: https://github.com/teppokoivula/TextformatterAudioEmbed Modules directory: https://modules.processwire.com/modules/textformatter-audio-embed/
    • By Richard Jedlička
      Tense    
      Tense (Test ENvironment Setup & Execution) is a command-line tool to easily run tests agains multiple versions of ProcessWire CMF.
      Are you building a module, or a template and you need to make sure it works in all supported ProcessWire versions? Then Tense is exactly what you need. Write the tests in any testing framework, tell Tense which ProcessWire versions you are interested in and it will do the rest for you.

      See example or see usage in a real project.
      How to use?
      1. Install it: 
      composer global require uiii/tense 2. Create tense.yml config:
      tense init 3. Run it:
      tense run  
      For detailed instructions see Github page: https://github.com/uiii/tense
       
      This is made possible thanks to the great wireshell tool by @justb3a, @marcus and others.
       
      What do you think about it? Do you find it useful? Do you have some idea? Did you find some bug? Tell me you opinion. Write it here or in the issue tracker.
    • By Chris Bennett
      Hi all, I am going round and round in circles and would greatly appreciate if anyone can point me in the right direction.
      I am sure I am doing something dumb, or missing something I should know, but don't. Story of my life 😉

      Playing round with a module and my basic problem is I want to upload an image and also use InputfieldMarkup and other Inputfields.
      Going back and forth between trying an api generated page defining Fieldgroup, Template, Fields, Page and the InputfieldWrapper method.

      InputfieldWrapper method works great for all the markup stuff, but I just can't wrap my head around what I need to do to save the image to the database.
      Can generate a Field for it (thanks to the api investigations) but not sure what I need to do to link the Inputfield to that. Tried a lot of stuff from various threads, of varying dates without luck.
      Undoubtedly not helped by me not knowing enough.

      Defining Fieldgroup etc through the api seems nice and clean and works great for the images but I can't wrap my head around how/if I can add/append/hook the InputfieldWrapper/InputfieldMarkup stuff I'd like to include on that template as well. Not even sure if it should be where it is on ___install with the Fieldtype stuff or later on . Not getting Tracy errors, just nothing seems to happen.
      If anyone has any ideas or can point me in the right direction, that would be great because at the moment I am stumbling round in the dark.
       
      public function ___install() { parent::___install(); $page = $this->pages->get('name='.self::PAGE_NAME); if (!$page->id) { // Create fieldgroup, template, fields and page // Create new fieldgroup $fmFieldgroup = new Fieldgroup(); $fmFieldgroup->name = MODULE_NAME.'-fieldgroup'; $fmFieldgroup->add($this->fields->get('title')); // needed title field $fmFieldgroup->save(); // Create new template using the fieldgroup $fmTemplate = new Template(); $fmTemplate->name = MODULE_NAME; $fmTemplate->fieldgroup = $fmFieldgroup; $fmTemplate->noSettings = 1; $fmTemplate->noChildren = 1; $fmTemplate->allowNewPages = 0; $fmTemplate->tabContent = MODULE_NAME; $fmTemplate->noChangeTemplate = 1; $fmTemplate->setIcon(ICON); $fmTemplate->save(); // Favicon source $fmField = new Field(); $fmField->type = $this->modules->get("FieldtypeImage"); $fmField->name = 'fmFavicon'; $fmField->label = 'Favicon'; $fmField->focusMode = 'off'; $fmField->gridMode = 'grid'; $fmField->extensions = 'svg png'; $fmField->columnWidth = 50; $fmField->collapsed = Inputfield::collapsedNever; $fmField->setIcon(ICON); $fmField->addTag(MODULE_NAME); $fmField->save(); $fmFieldgroup->add($fmField); // Favicon Silhouette source $fmField = new Field(); $fmField->type = $this->modules->get("FieldtypeImage"); $fmField->name = 'fmFaviconSilhouette'; $fmField->label = 'SVG Silhouette'; $fmField->notes = 'When creating a silhouette/mask svg version for Safari Pinned Tabs and Windows Tiles, we recommend setting your viewbox for 0 0 16 16, as this is what Apple requires. In many cases, the easiest way to do this in something like illustrator is a sacrificial rectangle with no fill, and no stroke at 16 x 16. This forces the desired viewbox and can then be discarded easily using something as simple as notepad. Easy is good, especially when you get the result you want without a lot of hassle.'; $fmField->focusMode = 'off'; $fmField->extensions = 'svg'; $fmField->columnWidth = 50; $fmField->collapsed = Inputfield::collapsedNever; $fmField->setIcon(ICON); $fmField->addTag(MODULE_NAME); $fmField->save(); $fmFieldgroup->add($fmField); // Create: Open Settings Tab $tabOpener = new Field(); $tabOpener->type = new FieldtypeFieldsetTabOpen(); $tabOpener->name = 'fmTab1'; $tabOpener->label = "Favicon Settings"; $tabOpener->collapsed = Inputfield::collapsedNever; $tabOpener->addTag(MODULE_NAME); $tabOpener->save(); // Create: Close Settings Tab $tabCloser = new Field(); $tabCloser->type = new FieldtypeFieldsetClose; $tabCloser->name = 'fmTab1' . FieldtypeFieldsetTabOpen::fieldsetCloseIdentifier; $tabCloser->label = "Close open tab"; $tabCloser->addTag(MODULE_NAME); $tabCloser->save(); // Create: Opens wrapper for Favicon Folder Name $filesOpener = new Field(); $filesOpener->type = new FieldtypeFieldsetOpen(); $filesOpener->name = 'fmOpenFolderName'; $filesOpener->label = 'Wrap Folder Name'; $filesOpener->class = 'inline'; $filesOpener->collapsed = Inputfield::collapsedNever; $filesOpener->addTag(MODULE_NAME); $filesOpener->save(); // Create: Close wrapper for Favicon Folder Name $filesCloser = new Field(); $filesCloser->type = new FieldtypeFieldsetClose(); $filesCloser->name = 'fmOpenFolderName' . FieldtypeFieldsetOpen::fieldsetCloseIdentifier; $filesCloser->label = "Close open fieldset"; $filesCloser->addTag(MODULE_NAME); $filesCloser->save(); // Create Favicon Folder Name $fmField = new Field(); $fmField->type = $this->modules->get("FieldtypeText"); $fmField->name = 'folderName'; $fmField->label = 'Favicon Folder:'; $fmField->description = $this->config->urls->files; $fmField->placeholder = 'Destination Folder for your generated favicons, webmanifest and browserconfig'; $fmField->columnWidth = 100; $fmField->collapsed = Inputfield::collapsedNever; $fmField->setIcon('folder'); $fmField->addTag(MODULE_NAME); $fmField->save(); $fmFieldgroup->add($tabOpener); $fmFieldgroup->add($filesOpener); $fmFieldgroup->add($fmField); $fmFieldgroup->add($filesCloser); $fmFieldgroup->add($tabCloser); $fmFieldgroup->save(); /////////////////////////////////////////////////////////////// // Experimental Markup Tests $wrapperFaviconMagic = new InputfieldWrapper(); $wrapperFaviconMagic->attr('id','faviconMagicWrapper'); $wrapperFaviconMagic->attr('title',$this->_('Favicon Magic')); // field show info what $field = $this->modules->get('InputfieldMarkup'); $field->name = 'use'; $field->label = __('How do I use it?'); $field->collapsed = Inputfield::collapsedNever; $field->icon('info'); $field->attr('value', 'Does this even begin to vaguely work?'); $field->columnWidth = 50; $wrapperFaviconMagic->add($field); $fmTemplate->fields->add($wrapperFaviconMagic); $fmTemplate->fields->save(); ///////////////////////////////////////////////////////////// // Create page $page = $this->wire( new Page() ); $page->template = MODULE_NAME; $page->parent = $this->wire('pages')->get('/'); $page->addStatus(Page::statusHidden); $page->title = 'Favicons'; $page->name = self::PAGE_NAME; $page->process = $this; $page->save(); } }  
    • By Sebi
      Since it's featured in ProcessWire Weekly #310, now is the time to make it official:
      Here is Twack!
      I really like the following introduction from ProcessWire Weekly, so I hope it is ok if I use it here, too. Look at the project's README for more details!
      Twack is a new — or rather newish — third party module for ProcessWire that provides support for reusable components in an Angular-inspired way. Twack is implemented as an installable module, and a collection of helper and base classes. Key concepts introduced by this module are:
      Components, which have separate views and controllers. Views are simple PHP files that handle the output for the component, whereas controllers extend the TwackComponent base class and provide additional data handling capabilities. Services, which are singletons that provide a shared service where components can request data. The README for Twack uses a NewsService, which returns data related to news items, as an example of a service. Twack components are designed for reusability and encapsulating a set of features for easy maintainability, can handle hierarchical or recursive use (child components), and are simple to integrate with an existing site — even when said site wasn't originally developed with Twack.
      A very basic Twack component view could look something like this:
      <?php namespace ProcessWire; ?> <h1>Hello World!</h1> And here's how you could render it via the API:
      <?php namespace Processwire; $twack = $modules->get('Twack'); $hello = $twack->getNewComponent('HelloWorld'); ?> <html> <head> <title>Hello World</title> </head> <body> <?= $hello->render() ?> </body> </html> Now, just to add a bit more context, here's a simple component controller:
      <?php namespace ProcessWire; class HelloWorld extends TwackComponent { public function __construct($args) { parent::__construct($args); $this->title = 'Hello World!'; if(isset($args['title'])) { $this->title = $args['title']; } } } As you can see, there's not a whole lot new stuff to learn here if you'd like to give Twack a try in one of your projects. The Twack README provides a really informative and easy to follow introduction to all the key concepts (as well as some additional examples) so be sure to check that out before getting started. 
      Twack is in development for several years and I use it for every new project I build. Also integrated is an easy to handle workflow to make outputs as JSON, so it can be used to build responses for a REST-api as well. I will work that out in one section in the readme as well. 
      If you want to see the module in an actual project, I have published the code of www.musical-fabrik.de in a repository. It runs completely with Twack and has an app-endpoint with ajax-output as well.
      I really look forward to hear, what you think of Twack🥳!
      Features Installation Usage Quickstart: Creating a component Naming conventions & component variants Component Parameters directory page parameters viewname Asset handling Services Named components Global components Ajax-Output Configuration Versioning License Changelog
    • By Robin S
      Page Reference Default Value
      Most ProcessWire core inputfield types that can be used with a Page Reference field support a "Default value" setting. This module extends support for default values to the following core inputfield types:
      Page List Select Page List Select Multiple Page Autocomplete (single and multiple) Seeing as these inputfield types only support the selection of pages a Page List Select / Page List Select Multiple is used for defining the default value instead of the Text / Textarea field used by the core for other inputfield types. This makes defining a default value a bit more user-friendly.
      Note that as per the core "Default value" setting, the Page Reference field must be set to "required" in order for the default value to be used.
      Screenshot

       
      https://github.com/Toutouwai/PageReferenceDefaultValue
      https://modules.processwire.com/modules/page-reference-default-value/
×
×
  • Create New...