Jump to content

ryan

Administrators
  • Posts

    17,240
  • Joined

  • Days Won

    1,703

Everything posted by ryan

  1. We'll support adding more user templates in the near future. Though if you don't mind changing a few lines in the core, I can show you how to do it now. But either way, you can always create your own new templates and use a page reference to associate them to a user. Another option is to add the fields that all users need to your user template, and use your front end logic to show and populate only the relevant fields for a given type of user. I would suggest using roles as a way to assign user types. Also keep in mind that PW's user system in it's default state is for access control. Since it doesn't produce markup for your site, it's not a ready-to-go solution for a turnkey social site. The framework for it is there, but not the interface. So if you are building a site where non-administrative users are managing profiles and such, then PW will happily handle the data, but you'll still have to write the markup and use the API like you would in any other part of your site.
  2. I think we were working at the same time because I've also got some updates, though mine don't yet incorporate yours. I'm not too worried about max filesize. PW doesn't keep track of filesize … I see it as a non-issue for the admin usage that these fields were built for. But for the AjaxUpload, it does seem like a nice convenience. Could be a nice thing for those with servers that have 5 meg limits on their php.ini settings and they are trying to upload a 500 meg file. PHP does keep track of max filesize, so I think that's where we should get it (per the ini_get settings you mentioned). I couldn't leave the image preview thing alone. Every time I used the upload, I wanted to see it right away. So I went ahead and added it. So now it shows you the image immediately after it's been uploaded. It accounts for thumbnail settings and/or post-image resizes too. I've also made several other updates so that you can edit the description and sort the images right away too. Lastly, uploads to a single-file field now support replacement. No longer do you have to delete the image before you can upload another. Now you can just drag in the new one and it'll replace the one that's there. Attached is the latest version (AjaxUpload3.zip). If you already have the AjaxUpload2.zip installed, then you only need to replace the files in the InputfieldFile and InputfieldImage directories. Antti: Is it relatively easy for you to paste your code updates into this version? If not, I will update my version with your updates, but may need assistance figuring out all the spots that need to be updated. I may be able to figure it out with some diff action, but just wanted to double check so that I don't miss anything. Thanks, Ryan --- Edit: php.net's ini_get() page Example #1 shows how to convert PHP's size notations (like 5M, 1G, etc.) to bytes. This is probably what we need for the upload_max_filesize? http://php.net/manual/en/function.ini-get.php AjaxUpload3.zip
  3. Thanks for testing it. I was wondering about this too, and I think we can. So far this solution is all part of InputfieldFile, so its behavior is currently going to be the same whether dealing with a regular file(s) field or an image(s) field. I was thinking the JSON response could optionally include some markup that would get shown after a file is uploaded. So InputfieldImage could create a thumbnail and return a little markup with an <img> tag. I think it'll be relatively easy to do. But getting this ajax upload was the last "new" thing I wanted to get committed before putting PW 2.1 out, so will add this thumbnail preview afterwards in an incremental update.
  4. Looking a little closer, I think the simplest solution will be for you to extend InputfieldImage.module, creating a new module. The module won't need much code in it. It'll just have to override two methods (outlined below). I've included some sample code in this message and it's written in the browser and untested. So you may have to adjust it and play around a bit to make it work. Unless you want to also create a new Fieldtype, you'll need to work within the data available to FieldtypeImage, and that means just a single 'description' field. You'll use that 'description' field to hold an encoded version of multiple fields. I would suggest using JSON (with PHP's json_encode() and json_decode()) or XML, whatever you prefer. But here's an [untested] example of the two methods you would override in your new module that extends InputfieldImage.module: <?php protected $descriptionTemplate = array( 'your_field1' => '', 'your_field2' => '', 'your_field3' => '', // or whatever you want ); protected function renderItemDescriptionField(Pagefile $pagefile, $id, $n) { $description = json_decode($pagefile->description, true); if(!$description) $description = $this->descriptionTemplate; foreach($description as $key => $value) { $description[$key] = htmlentities($value, ENT_QUOTES, "UTF-8"); } $out = <<< _OUT <label for='your_field1_$id'>Your Field #1</label> <textarea id='your_field1_$id' name='your_field1_$id'>$description[your_field1]</textarea> <label for='your_field2_$id'>Your Field #2</label> <input type='text' name='your_field2_$id' id='your_field2_$id' value='$description[your_field2]' /> <label for='your_field3_$id'>Your Field #3</label> <input type='text' name='your_field3_$id' id='your_field3_$id' value='$description[your_field3]' /> _OUT; return $out; } Then you'll also need to override ___processInputFile with something like this (example): <?php protected function ___processInputFile(WireInputData $input, Pagefile $pagefile, $n) { $changed = parent::___processInputFile($input, $pagefile, $n); $id = $this->name . '_' . $pagefile->hash; $description = $this->descriptionTemplate; $description['your_field1'] = $input['your_field1_' . $id]; $description['your_field2'] = $input['your_field2_' . $id]; $description['your_field3'] = $input['your_field3_' . $id]; $description = json_encode($description); if($description != $pagefile->description) { $pagefile->description = $description; $changed = true; } return $changed; } Once you've created and installed your new module, you'll select it as the "Input field" in field's settings, for your image(s) field. You'll also want to make sure that you set it to "no" for entity encoding the description field, in the field's settings. The main drawback of this approach is that you'll need to decode the fields from the image's description field every time you want to access them. So if you are iterating through some images in your template, you'd do it like this: <?php foreach($page->images as $image) { // decode the description field to an array $description = json_decode($image->description, true); // if there's nothing there, then skip it if(!$description) continue; foreach($description as $key => $value) { // you decide if this is necessary for your intended use (usually I would say Yes) $description[$key] = htmlentities($value, ENT_QUOTES, "UTF-8"); } echo "<p>Field 1: $description[your_field1]</p>"; echo "<p>Field 2: $description[your_field2]</p>"; echo "<p>Field 3: $description[your_field3]</p>"; } We can get around this drawback by implementing a hook to do this for you once a page has finished loading. However, if it's that important, I would suggest looking at creating a new Fieldtype instead, as that would be ultimately more efficient, and probably easy to do. If you want to take that approach, let me know because you won't need to do any of this encoding/decoding, instead we'll just have the Fieldtype's DB schema keep the fields instead. So with that approach, the corresponding Inputfield would be a little different.
  5. Jasper, I didn't want to leave you empty handed, especially after you've tried this a few times and my suggestions didn't work. Here's an updated version of the ImportPagesCSV module that supports file and image filed importing. It supports both single and multi-file fields, so there aren't any limitations in that area. https://github.com/ryancramerdesign/ImportPagesCSV To import a multi-file field, place each filename or URL on it's own line in your spreadsheet, OR separate each by a pipe "|", OR separate each by a tab (you decide) – basically, you are delimiting the filenames/URLs within the field. In my own tests, I used the pipe "|" to separate the URLs and all seemed to work well. Of course, if there is only one image/file, you don't need anything other than the filename or URL (no delimiter necessary). I ended up changing quite a bit of code, so please let me know if you run into any error messages or anything – it may not be perfect yet, but hopefully close.
  6. The field wasn't really designed for that particular use, so there currently aren't instructions on how to do that, but it's certainly possible (and probably not too difficult). But there isn't any easy answer to this question short of modifying the existing Fieldtype/Inputfield or creating a new one that extends it. I imagine that we'll have this built in eventually.
  7. Sorry, I neglected to think about that before (how pages have to be created before you can add images to them). One possible way around it is to try to first import without the image field, then import the same spreadsheet again but with the image field (updating the existing pages that were created). You'd need to choose the option to "modify existing page." But it's possible that might work.
  8. Thanks–fixed. Old school uploading should work now too. I also made some additional updates for keeping track of max number of files. Original message with the file AjaxUpload2.zip. If you've already installed the previous one, these are the files that changed in the latest version: /wire/modules/Inputfield/InputfieldFile.module /wire/modules/Inputfield/InputfieldFile.js /wire/core/Upload.php
  9. Attached is the completed AjaxUpload, though I'm sure there are still a few small tweaks. The attached zip has all the files that need to be replaced in your PW install (organized by PW's dir structure). In this version, after you upload, messages and errors are reported back for each file. Also, if PW changed the filename, you'll also see the status indicate the final filename. For an example of an error message, try to upload a non jpg/gif/png file to an image field. It also works with ZIP files! If your file field and platform support ZIPs, then drag in a ZIP and it'll extract all the files and show them to you. (As far as I know, PW's zip file support doesn't work on Windows… though someone correct me if I'm wrong). Files uploaded go through the same path as regular uploads, so things like max image resizing (at upload time) also work. Please give this a try and let me know if you run into any errors. I'm hoping to get this bundled into PW 2.1 this week. Once I get confirmation from a couple people that all works good on their end too, then I'll go ahead and commit to the source. Antti-- also want to get your eye on all my changes to the JS and make sure all is good. Please make any updates as you see fit. Thanks, Ryan AjaxUpload2.zip
  10. I'm curious to know what you find here. I had to add this to your JS in order for PW to recognize it as ajax: xhr.setRequestHeader("X-REQUESTED-WITH", 'XMLHttpRequest'); Should I be having PW core detect the presence of ajax by some other method? Here's how it currently does it: $config->ajax = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'); For the code I'm working on here, I settled with keeping the headers method you are already using. I don't know the non-jQuery ajax syntax well enough, and it sounds like we can't send separate POST vars anyway, so might as well just stick with the header. Though PW will check POST vars as a secondary option if there is no header. (I'll worry about things like checkboxes when and if the issue ever comes up). For now, stick with the HTTP_X_FIELDNAME. I'm still working on other updates here, but hope to post soon. Thanks, Ryan
  11. Sounds great, I look forward to seeing it. As promised, here's a full example of a simple contact form. This is bare bones, but safe. I've left out spam prevention measures, which I'll be happy to follow-up with if you'd like. Below is an entire template file. I figured it was simpler to show this way rather than splitting into multiple files. Though when forms get really large, I tend to split them in multiple files (and include them). But for smaller forms, I do it like the example below. /site/templates/contact.php <?php $sent = false; $error = ''; $emailTo = 'nikola@company.com'; // or pull from PW page field // sanitize form values or create empty $form = array( 'fullname' => $sanitizer->text($input->post->fullname), 'email' => $sanitizer->email($input->post->email), 'comments' => $sanitizer->textarea($input->post->comments), ); // check if the form was submitted if($input->post->submit) { // determine if any fields were ommitted or didn't validate foreach($form as $key => $value) { if(empty($value)) $error = "<p class='error'>Please check that you have completed all fields.</p>"; } // if no errors, email the form results if(!$error) { $msg = "Full name: $form[fullname]\n" . "Email: $form[email]\n" . "Comments: $form[comments]"; mail($emailTo, "Contact Form", $message, "From: $form[email]"); // populate body with success message, or pull it from another PW field $page->body = "<h2>Thank you, your message has been sent.</h2>"; $sent = true; } } if(!$sent) { // sanitize values for placement in markup foreach($form as $key => $value) { $form[$key] = htmlentities($value, ENT_QUOTES, "UTF-8"); } // append form to body copy $page->body .= <<< _OUT $error <form action="./" method="post"> <p> <label for="fullname">Your Name</label><br /> <input type="text" id="fullname" name="fullname" value="$form[fullname]" /> </p> <p> <label for="email">Your Email</label><br /> <input type="email" name="email" id="email" value="$form[email]" /> </p> <p> <label for="comments">Comments</label><br /> <textarea id="comments" name="comments">$form[comments]</textarea> </p> <p><input type="submit" name="submit" value="Submit" /></p> </form> _OUT; } // include site's main template which outputs everything include("./main.php");
  12. I don't think a multi-image field will work, but a single image field may very well work if you want to try it. To try it, backup your PW database and site first. If it doesn't work, you want to be able to restore to where you were. Though, chances are you won't have to do any kind of restoring files, but you can never be too safe. Next, make sure you are dealing with a single image field. Edit your field (in Setup > Fields) and make sure it's "max number of files" is set to "1". Next edit the ImportPagesCSV.module file and locate this (near the top, and add the lines indicated at the bottom). <?php protected $fieldtypes = array( 'FieldtypePageTitle', 'FieldtypeText', 'FieldtypeTextarea', 'FieldtypeInteger', 'FieldtypeFloat', 'FieldtypeEmail', 'FieldtypeURL', 'FieldtypeCheckbox', 'FieldtypeFile', // add this line 'FieldtypeImage', // add this line ); Save, and try it out. Let us know if it worked?
  13. Wow that's surprising... rather bloated for what it does. On the other hand, every one of their demos has loaded fast and I would have never guessed about the file size. So maybe it's not the issue that it appears to be at first, given that it's for admin rather than public users. I'm just thankful for browser JS caching. When it gets down to it, all web-based rich text editors seem problematic for one reason or another. It's always a compromise… just the nature of the beast I guess.
  14. Great example, thanks for posting it. There are definitely some things I like about that approach. The only problem is that it's static. You can't go back and make changes directly to the form (without copying and pasting the whole thing, or parts of it again)? And if you've customized the markup further, then copying and pasting may then be out of the picture. Still, seems like a worthwhile compromise and it really may be the best way to go. But I see this approach as being one more aimed at people that already know how to build their own forms and are just using this as a convenience. So this is one area where I'm still leaning towards more automation and less markup control, just to keep things dynamic, and within reach of clients. But providing the copy/paste markup like this seems like a good option to provide regardless.
  15. Glad you got it working. Thanks for posting the final code.
  16. You are right. Looks like I must have had the PageLinkAbstractor plugin installed when I last saved those pages, and they ended up in the recent DB update. I'll re-update today. Thanks for finding this.
  17. Pretty cool! Somehow I completely missed that, thinking it was a background image or something. Nice, I've not experimented with the multi-column stuff... looks interesting.
  18. Thanks I have updated for 2.1 and placed on GitHub: https://github.com/ryancramerdesign/FormTemplateProcessor Somewhere around ProcessWire 2.3 we'll be including a formal form builder. Not yet sure if it's going to use the same approach as this one. This can be used for public facing forms. But the person creating the forms should be an administrator in PW (whether the developer or the client).
  19. Not sure I understand? Looks like this is one giant field to cover the entire page. Pretty impressive with the 3 columns actually. That's not something I'm used to seeing in HTML. Definitely not something I've seen in TinyMCE. This 1-giant-field for the entire page is probably not something you'd see much of in the real world, beyond a demo. Aloha seems pretty useful even if just used for multiline fields. Though it'd be great if it had some option to place limits on the markup a user can use, for single line fields at least. But I don't see anything like that, looking through their site. We can always just strip the block-level stuff.
  20. Shane, glad that did the trick! Thank you for your inquiry about donations, that's very nice of you. We don't have anything like that at present, but maybe will set it up someday. I certainly don't expect people to donate anything. But if they are wanting to, time donations are always appreciated. Time can mean anything, whether blogging about PW, sending the occasional tweet, helping out others on the forum, linking to processwire.com, writing PW modules/templates/code to share, helping to find and nail bugs, getting involved in the code, etc. So I guess that translates to anything you are interested in towards improving the project or sharing it with others. But of course, nothing is expected or required.
  21. It sounds like you've now got both the first() added and the single image fields. You want one or the other, not both. The first() was just to grab the first image from an image array. If you have the field set to contain a max of 1 image, then it's just going to have that image, and no array. So if you are going to keep the "first()" in there, then change it to a multi-image field (set the max to 0 or greater than 1). If you want to keep it a single image field, then get rid of the "->first()". If it still doesn't work, we need to take a closer look because the error message you posted sounds like work_thumb may not be a variable on the page (or there may be no image attached). One thing you can do is: var_dump($web_work->work_thumb); Just to see what it is. I'm guessing it's null, and it's coming from a page with no image attached. Another thing you might want to do is place some more limits on your $pages->find(). Right now it's pulling all pages with the work_web template, no matter where they are. There's no problem with that, but it might be pulling a page you've forgotten about somewhere else in the tree. I would suggest something more specific: $work = $pages->find("parent=/work/projects/, template=work_web, sort=-date"); Or: $work = $pages->get("/work/projects/")->children(); // assuming all children use work_web template Or: $work = $pages->get("/work/")->find("template=work_web, sort=-date");
  22. I've just depreciated the Textformatter::format($str) function in favor of Textformatter::formatValue(Page $page, Field $field, $value). I guess I didn't consider the things we'd be using Textformatter for in the future. But it should be ready to go now. Just grab the latest commit and implement the 'formatValue' version rather than the 'format' version in your Textformatter module. You can now get the field name from $field->name. I see what you mean, though am surprised they don't provide built in capability to deal with single-line (titles) vs multi-line (textareas) markup. We could always strip paragraph and heading tags from the single line fields. So long as they are both dealing with the same kind of markup tags, I think we'll be fine here. Though not positive. I'm excited to see how this goes! Thanks, Ryan
  23. I'm not sure how to reproduce the first issue you brought up. I've tried several times dragging trees into the trash and out again, but no luck. Please let me know if you are able to reproduce it again at some point. I was able to reproduce the second issue you brought up, which was a loss of status when trees as trashed all at once. It would just give them all a "trash" status, removing any previous unpublished, hidden or locked status they may have had before. I've just fixed this in the latest commit. Thanks for finding it! Sorry for the lost status in your tree. Btw, it can sometimes be dangerous changing stuff in the DB directly, outside of PW's API. It sidesteps several other things that occur when a page is saved. There are other tables involved in every $pages->save() so manipulating the data directly, even a simple parent change or status change, can cause problems. Not major problems, but still, it's best to try and make the change from the API. And if that still doesn't do it then post here and we'll figure out a safe solution.
  24. Shane, it sounds like you have a multiple-images field rather than a single image field. Two ways you can solve it. First would be to convert to a single image field. Go in Setup > Fields, and edit your work_thumb (and work_full) fields. On the 'details' tab of each, enter "1" for "maximum files allowed". That will make your field dereference in the manner your code is written, making your code example work how you'd expect. The other solution is for you to change the first line in your foreach() to this: $image = $web_work->work_thumb->first(); You may also want to add a check to deal with pages that don't yet have an image attached, i.e. if(!$image) continue;
  25. I'm not sure which solution we're talking about, because there have been a few posted. Can you post the code for the solution you were using? I'm guessing it would be an easy fix, but just need the context. The above will only cycle through the first 16 images on any page. Then it would move on to the next page in your $photos->children loop and display the first 16 photos from the next page. But it's not going to do anything for pagination. If you want to keep things from getting overly complex, I'd recommend either focusing on paginating the images from a single page (like the example below) or paginate multiple pages where each page has 1 image. I think we can find straightforward solutions for either of those. <?php $limit = 16; $start = ($input->pageNum-1) * $limit; $images = $page->images->slice($start, $limit); foreach($images as $image) { // ... }
×
×
  • Create New...