Jump to content
MatthewSchenker

Create Pages (with File-Upload Field) via API

Recommended Posts

Ok I copied your code over and starting taking closer look and test.

There was so many faults and things to change, I can't name them all.

First off, I changed the input submit and changed to if($input->post->submit){..., since contactname in the form isn't required and just personal preference and a good practice.

I made sure debug mode in true in /site/config.php.

First submit, BANG!!! error:

Fatal error: Exception: Can't save page 0: /about/: It has an empty 'name' field (in /Applications/XAMPP/xamppfiles/htdocs/pwprofile/wire/core/Pages.php line 514) #0 [internal function]: Pages->___save(Object(Page)) #1…..

So it can't create and save the page because you don't assign a title nor a "name" to the page before saving. I moved the code around to add those.

--

Then there was a wierd line:

$contact_photo = $input->post->contact_photo;

and later:

$np->contact_photo = $contact_photo; // being the file POST

Maybe a left off when trying something?

--

Then after that, the assignment of the upload to the page image:

foreach($files as $filename){
    $uploadpage->contact_photo = $upload_path . $filename;
}

$uploadpage?

should be

$np

--

At the end of when errors found you still have the contest_photo instead of contact_photo.

// get the errors
foreach($contest_photo->getErrors() as $error) $message .= "<p class='error'>$error</p>";

--

All in all nothing special and nothing wrong with the PW code in there, except the page name left out. But with debug mode on an easy spot.

I created a gist with a working version of your code here: https://gist.github.com/somatonic/5207537

(I changed template and parent to my default install but nothing to worry about. I also commented out a bunch not needed to make it work.)

Still with the validation of the form fields open to do, currently you only validate the upload and show errors.

  • Like 2

Share this post


Link to post
Share on other sites

Greetings Soma,

Thanks for taking a close look at the code!  I admit there were an unusual number of un-spotted bits in there.

I certainly don't think there's anything wrong with ProcessWire code.  It's just that this operation does require a bit more code than other "simple" operations in ProcessWire, so there's more potential for errors.

Still, I know this is something that a lot of people need to do with ProcessWire, so I'm glad it was out there and bashed around until it worked.

I'll grad your gist and test it out.

Thanks again!

Matthew

Share this post


Link to post
Share on other sites

Greetings,

Just following up...

I made all the changes suggested above, but still no luck.  The form goes through with no errors, but nothing gets saved in the page tree.

Soma: when you ran this with the code you described, were you able to get pages saved with images in the page tree?

Continuing to investigate.

Thanks,

Matthew

Share this post


Link to post
Share on other sites

Matthew,

Might I suggest starting as basic as possible. Basic form, with one upload and one field.

Echo out everything as you go.

Share this post


Link to post
Share on other sites

Greetings,

I have used front-end forms to create pages without issues several times.  In my original post of this discussion, I showed the form with all the "basic" fields, and it works great.  it's only when I add the file-upload that things get thrown off.

If you have that working example you mentioned earlier, I'd be curious to see it.

I'm sure when this is done, it will all be obvious what the problem was!

Thanks,

Matthew

Share this post


Link to post
Share on other sites

Greetings,

Just following up...

I made all the changes suggested above, but still no luck.  The form goes through with no errors, but nothing gets saved in the page tree.

Soma: when you ran this with the code you described, were you able to get pages saved with images in the page tree?

Continuing to investigate.

Thanks,

Matthew

Yes it works. Page is added and image is saved to page. Working example is here: https://gist.github.com/somatonic/5207537

  • Like 1

Share this post


Link to post
Share on other sites

Greetings,

Thanks Soma for all your help.

I'm starting to wonder if there's something off in the server environment.  I have now tested literally the same form as the one you posted and it does not work.  I'm not sure what else would stop it from working.

Thanks,

Matthew

Share this post


Link to post
Share on other sites

Matthew,

Have you checked the template's family settings? 

Can this pages using this template have children?

Can this template be used for new pages?

I would imagine if either were set to "no" that you would get an error.

Share this post


Link to post
Share on other sites

Greetings,

Thanks renobird for helping!

There are no errors.  And pages get created successfully when the form only includes "regular" fields, without image uploads.  It's only when I add the image upload field that everything just stops working.

So it can't be an issue with the parent/children settings.

Still stumped,

Matthew

Share this post


Link to post
Share on other sites

Just to clarify,

Using the exact same code (just commenting out parts):

Works:

- When creating a new page that just has fields

- When you just upload an image (no additional fields)

Breaks:

- When you combine the 2

Edit

Also:

- Debug mode is set to true? (/site/config.php)

- no errors?

Share this post


Link to post
Share on other sites

Weird. That makes no sense.

Share this post


Link to post
Share on other sites

Like I mentioned in my PM, comment out the tmp folder clean up part, and verify the file makes it to the server.

Share this post


Link to post
Share on other sites

Greetings,

Thank you for analyzing this with me.  I really appreciate the help.

Interesting... I am seeing no file in the temp folder.

Write permissions are as open as possible.

One off-the-wall idea: does ProcessWire prevent non-logged-in users from submitting files?  This form is open to anyone, even if not logged in.

Just a thought.

Thanks,

Matthew

Share this post


Link to post
Share on other sites

u.forgett enctype

<form method="post" enctype="multipart/form-data">

Share this post


Link to post
Share on other sites

Greetings,

Thanks WillyC for helping...

I posted two versions of the form: (1) without file uploads and (2) with file uploads. The form with file uploads has the correct enctype.

So... Still searching for an answer.

If anyone wants to post forms where they have file uploads working along with other fields, plase feel free to do so!

Thanks,

Matthew

Share this post


Link to post
Share on other sites

Matthew, the primary problem I can see is this line:

if(!$contact_photo->getErrors()) {

The issue there is that getErrors() always returns an array, which always resolves to "true" in your if statement. In order for it to work properly, you would need to count() the return value of getErrors() rather than typecast it to a boolean like you are doing now. However, I don't think that getErrors() is a good way to check for success with WireUpload, because errors could occur while files were still uploaded. So it's better for your code to ask the question "were any files uploaded?" rather than "did any errors occur?". Then worry more about errors if no files were uploaded. 

There were also several other minor issues or concerns, but I think the issue mentioned above is the primary reason it wasn't working. I've attempted to re-factor your code and resolve all the issues/concerns that I would have had with it. This is written in the browser, so there may still be typos, but hopefully the intentions are clear:

<?php  

/**
 * Process the contact form
 *
 * Populate's ProcessWire's $notices API var with errors and messages
 *
 * @return bool Returns true on success, false on failure. 
 *
 */ 
function processContactForm() {

  $input = wire('input'); 
  $sanitizer = wire('sanitizer'); 
  
  // Set a temporary upload folder where the files are stored during form processing
  // RC: precede temp dir with a period to ensure it remains non-web accessible
  $upload_path = $config->paths->assets . "files/.temp/";
  
  // RC: create temp path if it isn't there already
  if(!is_dir($upload_path)) {
    if(!wireMkdir($upload_path)) throw new WireException("No upload path"); 
  }
  
  // New wire upload
  $contact_photo = new WireUpload('contact_photo'); // References name of HTML form field
  $contact_photo->setMaxFiles(5);
  $contact_photo->setOverwrite(false);
  $contact_photo->setDestinationPath($upload_path);
  $contact_photo->setValidExtensions(array('jpg', 'jpeg', 'png', 'gif'));
          
  // execute upload and check for errors
  $files = $contact_photo->execute();
      
  // RC: use count($files) as your decision whether to proceed not not, rather than getErrors()  
  if(!count($files)) {
    $contact_photo->error("No files received, so not creating page.");
    return false; 
  }
  
  // Save in the ProcessWire page tree; map submission to the template fields
  $np = new Page(); // create new page object
  $np->template = "contact_submission"; 
  $np->parent = "/customer-service/contact-us/contact-submission-listing/"; 

  // RC: for safety, only add user uploaded files to an unpublished page, for later approval
  // RC: also ensure that using v2.3+, and $config->pagefileSecure=true; in your /site/config.php
  $np->addStatus(Page::statusUnpublished);
                    
  // Send all form submissions through ProcessWire sanitization or just map a variable
  // RC: No need to have intermediate variables, I removed them--populating the $np page instead
  $np->title = $sanitizer->text($input->post->contactname);
  $np->name = $np->title;
  $np->contactname = $sanitizer->text($input->post->contactname);
  $np->email = $sanitizer->email($input->post->email); 
  $np->comments = $sanitizer->textarea($input->post->comments); // RC: assuming this is a textarea fieldtype
  $np->save();
  
  // Run photo upload
  foreach($files as $filename) {
    $pathname = $upload_path . $filename; 
    $np->contact_photo->add($pathname); 
    $np->message("Added file: $filename"); 
    unlink($pathname); 
  }
          
  // save page again
  $np->save();
  
  return true; 
}


// First, confirm that a submission has been made
if($input->post->contactname) {

  if(processContactForm()) {
    echo "<h2>Your page was saved!</h2>";
  } else {
    echo "<h2>Sorry things didn't work out!</h2>";
  }

  foreach($notices as $notice) {
    $class = $notice instanceof NoticeError ? "error" : "message";
    echo "<p class='$class'>$notice->text</p>";    
  }

} else {
  // display contact form
}                            
  • Like 7

Share this post


Link to post
Share on other sites

Thanks Ryan for the heads up, there's some nice examples for advanced coders.

Strange. Now, I also would have thought that with !$u->getErrors() it wouldn't work, but it still does! I went and did many tests after you posted this and I can't see any difference and it all works as it should. The code works with both and I haven't looked into it further (core). I wish to be proven wrong but it really does (at least for me here) :/

I think you got a valid point with checking for if there's files really uploaded at all... However this wouldn't work if image upload would be not required in your form. Also the example you posted is also not showing how you could make required fields and inline error/repopulating fields, prevent CSRF and double posts. It's still a great example but as said, not a "complete" example that can be used in a public front-end form. May or may not suiteable for people not knowing what they're doing and only copy paste.

What I also think could be the problem on Matthews side is that the PHP upload and post max size isn't enough to upload the file. I also tested this and it seems to fails silently with no errors and just shows the form again. Maybe there's a way to get around it, but thought it might be an issue since there's no error thrown as it's apache upload interrupting?

---

It can get somehow complex to add all checks and validation to a form server side, and the following post example is also just for showing what all there's involved to make a pure php form (using some PW internals).

Yet another example

I've spent couple hours creating a form upload example

 - with files (images) upload to a page file field
 - adds new page on the fly and adds uploaded images
 - prevents CRSF attacks, this also prevents double post by refresh page after submit
 - has required fields with error messages inline
 - repopulates form field in case an error happened or a required field was not filled in
 - sanitizing and saving values to a page
 - jquery example with disabled submit button on form submit

The gist repo can be seen here https://gist.github.com/somatonic/5233338

You can configure some variables and array's at the top and add remove fields as you wish to the html form markup.

Like this:

// --- Some default variables ---
$success_message = "<p class='message'>Thanks for your message!</p>";

// --- All form fields as nested array ---
// using html form field name => template field nam, from the page you're going to create
$form_fields = array(
  'fullname' => array('type' => 'text', 'value' => '', 'required' => true),
  'email' => array('type' => 'email', 'value' => '', 'required' => true),
  'message' => array('type' => 'textarea', 'value' => '', 'required' => true),
  'newsletter_subscribe' => array('type' => 'checkbox', 'value' => 0, 'required' => false),
  'images' => array('type' => 'file', 'required' => true)
);

// --- WireUpload settings ---
$upload_path = $config->paths->assets . "files/.tmp_uploads/"; // tmp upload folder
$file_extensions = array('jpg', 'jpeg', 'gif', 'png');
$max_files = 3;
$max_upload_size = 1*1024*1024; // make sure PHP's upload and post max size is also set to a reasonable size
$overwrite = false;

// --- Page creation settings ---
$template = "upload-entry"; // the template used to create the page
$parent = $pages->get("/uploads/");
$file_field = "images";
$page_fields = array('fullname','email','message','newsletter_subscribe');

// $page_fields = define the fields (except file) you want to save value to a page
// this is for the form process to populate page fields.
// Your page template must have the same field names existent

// ------------------------------ FORM Processing ---------------------------------------

include("./form-process.php");
 
To set this up.
 
1. Create a template upload-entry used to save the form submissions. With all the fields you'll have in the form, and name them the same as in the $form_fields
 

2. Create a form-upload.php template used to hold the form config and markup code:

(create a template in PW with this name and the page the form should be rendered)

https://gist.github.com/somatonic/5233338#file-form-upload-php

3. Create a form-process.php file in the templates folder with the processing code

(This is included in the template file above after the configuration part)

https://gist.github.com/somatonic/5233338#file-form-process-php

There's a basic styling CSS:

https://gist.github.com/somatonic/5233338#file-form-css

And the jQuery snippet used to prevent double posting when double clicking the submit.

https://gist.github.com/somatonic/5233338#file-form-js

This is some screen showing the form:

post-100-0-55537400-1364160069_thumb.png

post-100-0-73960600-1364160102_thumb.png

  • Like 7

Share this post


Link to post
Share on other sites

Greetings,

Thank you extremely Ryan!!! And thank you Soma for patiently analyzing all the details.

Of course, file uploads in any system are complex actions and should not be taken lightly.

Just wondering: would it be better to access the ProcessWire "files" module (the same one that controls file uploads in the admin form)? Not sure if this is even possible...

Again, my goal (besides using it in my projects) is to capture this routine and document it so others can use it. Together with "regular" fields, I think this moves us closer to a co,pkete picture of front-end page creation/management.

Thanks,

Matthew

Share this post


Link to post
Share on other sites

Thanks Soma and Ryan, really helpful stuff here. I've learned a lot. Posts like these once again proves why everyone loves this community.

  • Like 1

Share this post


Link to post
Share on other sites
Thank you extremely Ryan!!! And thank you Soma for patiently analyzing all the details.

Of course, file uploads in any system are complex actions and should not be taken lightly.

Just wondering: would it be better to access the ProcessWire "files" module (the same one that controls file uploads in the admin form)? Not sure if this is even possible...

So you got scared by that long complex basic form script? :)

Creating form using ProcessWire as a framework and it's form and inputfield capabilities.

Yes this would be possible and it's the way I use to make forms in front and backend whenever possible.

Then we are finally here http://processwire.com/talk/topic/2089-create-simple-forms-using-api/ where I explained how to do it along with some examples. 

Yet another form example

Since uploading files is a little special I went ahead and tried using the InputfieldFile to upload images to the temp folder and finally create a page and add those images same way as in the other examples. Then after success delete the temp files.

Now this example does all the previous "pure" php example does, just using PW forms API.

- required fields

- CSRF preventing

- inline error

Form example snippet: https://gist.github.com/somatonic/5236008

There's also a CSS file example to style the form, and for example hide the "Drag files here...".

This technique is the most simple to make front-end forms, and doing it this way allows you do add hooks to the form in case you need a custom validation or anything directly from within the template code.

For example, the $form can be used to attach any hooks to the form:

/* form hook example */
function hookEmail($event){
     $file = $event->return;
     echo "email value: ". $file->value;
}
$form->get("email")->addHookAfter("processInput", null, 'hookEmail');

---

Little change to InputfieldFile.module to throw error if maxFiles is reached

It works all well, but the maxFiles setting doesn't throw an error message when you choose more images than allowed. Since the InputfieldFile module is usually ajax based, it throws error via ajax and thus not in $form->getErrors() at all. It just proceeds and uploads only the max files and skips the rest. This could be changed in the module to also throw error on the field when no ajax is used. For this to maxFiles error to work I changed the /wire/modules/Inputfield/InputfieldFile.module a little:

https://github.com/ryancramerdesign/ProcessWire/blob/master/wire/modules/Inputfield/InputfieldFile/InputfieldFile.module#L288

From:

if($this->config->ajax) foreach($ul->getErrors() as $error) {
    $this->ajaxResponse(true, $error);
}

To:

if($this->config->ajax) foreach($ul->getErrors() as $error) {
    $this->ajaxResponse(true, $error);
} else {
    foreach($ul->getErrors() as $error) {
        $this->error($error);
    }
}

Maybe if Ryan can implement those to the Inputfieldfile to allow for front-end error to be shown, it would be great.

  • Like 4

Share this post


Link to post
Share on other sites

Greetings,

I'm not afraid of long forms and code. But of course I am interested in the most concise code possible. Also, I'm thinking from the point of view of documentation and putting it all in the context of general "front-end form" tutorials for all users.

Soma: I read your post on using the inputfield modules. It was on my mind when I started this discussion. The way I am documenting this, I want to show two general procedures for front-end forms: using modules or using "plain" HTML/PHP.

But you also wrote this: "Also file uploads isn't there, but maybe at some point there will be more options."

That's what made me wonder.

The other thing is, as I use ProcessWire, I simultaneously use Laravel. I am constantly impressed with how ProcessWire provides methods that do what a full framework does. Building forms, and all that go with that, is a crucial piece. So I'm looking at the way Laravel does file uploads as I write all this and looking for the equivalent methods in ProcessWire.

As long as we keep a good goal in mind, we'll be all right.

Thanks,

Matthew

Share this post


Link to post
Share on other sites

Ryan and Soma,

I would like to extend a huge thanks to both of you. You guys (along with many others) consistently take the time to not only decipher and debug code, but go well beyond that by trying to figure out what the person is "actually" trying to do and provide them with a revised/better solution—I applaud you both.

Soma, your examples above are amazingly thorough — I really appreciate the time you devoted to create them, and your willingness to share. 

Cheers.

  • Like 2

Share this post


Link to post
Share on other sites

Greetings,
I agree with renobird. This is a pretty complex area, so it's great to have people with the expertise and patience to work through it all.

I'm hoping that this discussion can be a source for documenting these methods for people at all levels of development expertise.

My goal is to be able to present a clear set of directions and explanations for the whole front-end form effort. With this discussion, I have some great material that I can put together and present down the line.

Thanks,
Matthew

  • Like 1

Share this post


Link to post
Share on other sites

I'd seen the original post a while ago, but at the time I was new to ProcessWire—so it didn't really sink in.

I just used that method to rebuild a frontend system that allows faculty to upload and edit course syllabi.

Took less than 10 minutes to get it up and running, and maybe another 20 to troubleshoot a few things unique to my needs.

The API was already allowing me to run with forms, now I feel like I have a jetpack.

:)

  • 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 VeiJari
      Hi, this is the first we are trying to make a page that has only one type of user that has access to every page. 
      The other users should only have a given access to specific pages, not to the whole template.
      My structure
      -Field -Organisation -Project -Report I want that the "measurer" role only has access to "project x" and it's children, but no view access to every project, organisation or field. I've tried to do this with https://modules.processwire.com/modules/page-edit-per-user/ but it still needs a view access to the whole tree to see the "project x" page. Or is there something I haven't figured out?
      Maybe I have to make it via the API: a select field in the "organisation" template where the admins could add the users and then I use hook to update the privileges?
      Have you done something like this and how did you accomplish it?
      Any help would be appreciated.
       
    • By cosmicsafari
      Hi all,
      Before I go potentially wasting time trying to achieve the impossible.
      Can anyone confirm if its possible to have a Page Reference field on a modules config page?
      I'm wanting to essentially just output a list of select able pages based on the a given selector (likely by template at this stage), wherein the select is the pages that the module should apply to etc. I was thinking a simple checkbox list would suffice is asmSelect isn't available.
      Essentially have it display the same way a Page Reference field would display on a template, where you can easily select a bunch of them.
      public function getInputfields() { $inputfields = parent::getInputfields(); $f = $this->modules->get('InputfieldPage'); $f->attr('name', 'testSelect'); $f->setAttribute('multiple', 'checkboxes'); $f->setAttribute('findPagesSelector', 'template=development'); $f->label = 'Test'; $inputfields->add($f); return $inputfields; } Figured something akin to the above would work but can't seem to get rid of this warning on the modules config screen though.

    • By 999design
      Hi all,
      Running into an odd error that I can't seem to get my head around.
      We have 2 separately created Formbuilder forms sitting on a single page.
      But we keep experiencing weird results with them, originally we couldn't get one of the forms to ever submit so we ended up disabling CSRF for them which let us get around this issue.
      However it then causes a problem in that with CSRF disabled, one of forms always records 2 entries on submission. Just a straight duplicate within the entries for that form.
      So trying to stop this happening we tried enabling CSRF again and although that does stop the duplicated entry, it ends up giving really weird feedback such as the attached screengrab.
      Hazarding a guess I assume whatever is trigger on submission is firing twice because of the presence of the second form, but I have no idea why this would be the case as they are 2 seperately named forms?
      Any ideas?

    • 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 marcus
      wireshell 1.0.0 is out    
      See Bea's post
       


      -------- Original post -----------
        Now this one could be a rather long post about only an experimental niche tool, but maybe a helpful one for some, so stay with me   Intention Do you guys know "Artisan" (Laravel) or "Drush" (Drupal)? If not: These are command line companions for said systems, and very useful for running certain (e.g. maintenance, installation) task quickly - without having to use the Admin Interface, first and foremost when dealing with local ProcessWire installations. And since it has a powerful API and an easy way of being bootstrapped into CLIs like this, I think such a tool has a certain potential in the PW universe.    It's totally not the first approach of this kind. But: this one should be easily extendable - and is based on PHP (specifically: the Console component of the Symfony Framework). Every command is tidily wrapped in its own class, dependencies are clearly visible, and so on.   ( Here was the outdated documentation. Please visit wireshell.pw for the current one )
×
×
  • Create New...