Jump to content

ryan

Administrators
  • Posts

    16,715
  • Joined

  • Last visited

  • Days Won

    1,516

Everything posted by ryan

  1. Let me know when you think it's stable/ready, as I'd really like to have this built-in to the core. It doesn't seem like there's any real overhead to this, just a very handy tweak to have when you want it. I can see using this quite often. One question: when you are copying/pasting, say from Photoshop, where does the JPEG compression actually take place? Does Chrome compress it as it pastes, or how does that work? Great screencast BTW!
  2. Absolutely! That sounds great. Thanks for getting it working in nginx.
  3. Subdirectory vs. root doesn't matter. Most likely ProcessWire can't get sessions started. Try removing your /site/assets/sessions/ dir completely, and then re-creating it. Give it whatever permissions are necessary for ProcessWire to write to it. If you do 777, and this is not a dedicated server, then check with your systems administrator to see if you can lock that down a little better.
  4. Soma is correct. You need to replace "limit = 10" with "limit=10".
  5. Very cool Diogo! Tested out here and works beautifully. Did a flat copy from Photoshop and went straight into the site. So useful, seems like this belongs in PW's core InputfieldFile.js, if that's alright with you? Because this only affects the JS side, it doesn't seem like there would be any potential security concerns or problems to worry about. A few questions: Do you know how broad browser support is for this? Is there any benefit to making it configurable? (i.e. "do you want to support pasting of images? yes/no"). I'm thinking that would be unnecessary configuration, but just checking. For broader theme support, I'm thinking the text shouldn't be yellow or caps, but just the same as before except with 'paste' linked: "Drag or paste files in here"
  6. Awesome work! One of the coolest PW sites I've seen.
  7. Actually that error message does make sense. Though this might be something that wouldn't behave the same way in all PHP versions. But it's something that should be changed in InputfieldCropImage either way. Starting on line 27 of InputfieldCropImage.module, can you change this: protected function renderItem($pagefile, $id, $n) { $out = parent::renderItem($pagefile, $id, $n); with this: protected function ___renderItem($pagefile, $id, $n) { $out = parent::___renderItem($pagefile, $id, $n); Basically, prepend three underscores "___" to the renderItem definition and call.
  8. ryan

    Crowd Fund new tutorials

    I have to admit that I like learning from videos and books. They help to get across bigger picture concepts much better than copying and pasting. They build a foundation. So when it does come time to writing code (or copying pasting it), you've got the understanding of it. The problem with copying/pasting is that it's like building without a foundation, which can be dangerous. When you've got the foundation, all the other pieces just kind of fall into place. I think this is especially true of ProcessWire. If you understand the big picture and how simple it is, the rest of it becomes simple as well. And there's no reason not to learn the foundation, because it's so darn simple. It seems like a lot of people start working with ProcessWire while thinking of it in the context of some other CMS. So there is inevitable "un-learning" that has to take place, as people are looking for complexity where there isn't. This is a recurring theme. What I think would do an even better job of establishing the foundation would be two printable PDF documents that are maximum 1-printed page each: ProcessWire in a nutshell, a cheat-sheet – Covers everything you need to know to understand a typical site profile. Pages, Fields, Templates, then $page, $pages, and PageArray. All you need to know about PHP to use ProcessWire – This one would focus on the general PHP concepts necessary to use it like a template engine with ProcessWire. Covers things like PHP tags, double-vs-single quotes, echo, if(), foreach(), and comparison vs. assignment.
  9. I don't totally understand what that option does, but I've gone ahead and added it. You should see it in the latest commit. So long as you aren't using inline mode, it should allow you to specify the styles? Though to be honest, I don't use these options myself. I like to keep the client thinking about content and not design when in the editor. So displaying the same styles on the front-and-back end is counterproductive towards that.
  10. Not sure what the issue was with GitHub, but their ZIP download URLs have changed a bit. Rather than the filename "master", it is "master.zip". I'm guessing they setup static redirects to ensure that the "master" links would continue working, when they made this change. But that redirect is pointing to PW 2.2.9 rather than 2.3, so thanks for letting me know Peter. I have added ".zip" to the end of the URL and now it seems to be pointing to the right version. Also fixed the GitHub summary text, thanks interrobang.
  11. Thanks u-nikos! I think that nginx support would just be a matter of finding the equivalent rewrite rules. These are a fairly small part of ProCache (only a few rules necessary). So one simple route would be to remove write access to your .htaccess file (so ProCache can't modify it) and then take the rules that it says you should paste, and translate those to the equivalent nginx rules, before pasting them in. I'm not exactly sure what the issue is, but Soma had mentioned that there was an issue. I don't know the inner-workings of the LanguageLocalizedURL module well enough to understand what the issue might be. I've got a few to-do items on my ProCache list before I can focus on the LanguageLocalizedURL issue. But if anyone has the time to experiment with the LanguageLocalizedURL module and ProCache sooner, to see what the issue is, I can attempt to make updates/tweaks per your feedback. Btw, ProCache should work with the new LanguageSupportPageNames module included with the core. I've not actually tested it yet, but don't see any reason why it wouldn't work.
  12. I agree, and I actually have tried to implement this before. I could never get jQuery's double click event register and work here. I suppose it's because we are already using the click event. But if someone else figures out how to get both double click and click working for it, I think it would be worthwhile to have.
  13. 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 }
  14. There really isn't a lot of code involved. But you might find it helpful to look at these files, which is basically what boils it all down: /site/templates/blog.inc - shared functions for finding and rendering posts, comments, and navigation. /site/templates/markup/*.php - view (output) files used by the functions in blog.inc Everything else in the profile calls upon those functions, which is what you would want to do when using the blog profile code in an existing site.
  15. There really is no maximum page capacity. If MODX Evo had a limit on quantity of pages, then I'm guessing they were keeping some reference to all pages in memory at once. We don't do anything like that with pages, so any limits have more to do with the server itself… mysql, disk space, file system. I don't see any reason why you couldn't have millions of pages in ProcessWire. Chuck Forsberg and ZMODEM, good times. The BBS I ran was Data Connection BBS between 1989-1995, and wrote software called DataView for viewing inside ZIP (and ARC, RAR, etc.) archives online. Also wrote a software called Oneliner …kind of like Twitter for BBS times. __ \ | __| | _) | | _` | _| _` | ( _ \ \ \ -_) _| _| | _ \ \ ____/\__,_|\__\__,_| \___\___/_| _|_| _\___\__|\__|_\___/_| _| RENAISSANCE WHQ, FUTURE CREW, LEGEND DESIGN, IGUANA, EMF, PRIME - Node 1: (703) 506-8598 - 16.8k HST DS v.32bis Node 2: (703) 847-0861 - 28.8k HST DS v.34 - Sysop: Ryan Cramer [Iguana/Renaissance] Located in McLean, Virginia, USA Online since 1989 No Lamers (had to say that =)
  16. There's really not much to it, it's nice and simple. This article is a great intro to Composer: http://blog.fortrabbit.com/handle-your-dependencies-with-php-composer/
  17. Once the multi-language page names module is stable and in production use. So will probably start developing the namespaces stuff in May. Namespaces are the primary aim, with PSR-0 being a natural extension of that. I plan to shoot for PSR-1 too if it looks like it'll benefit our audience. Also as a natural extension to these updates, I am interested in supporting Composer, and will do so if possible. I agree it's a great asset for PHP, though am less certain if it's as much of a draw for ProcessWire's primary audience. Throughout all of these 2.4 updates, I feel a lot of care will have to be taken to balance these updates with other improvements to the system. After all, our audience is primarily web designers and developers, and less purely PHP coders. I think a majority of our users doesn't actually care about namespaces, PSR standards and Composer, so I don't want to get too far off track, even if I personally have a strong desire for these things. But the driving aim of 2.4 is to help ProcessWire benefit from PHP 5.3+ as much as possible. This likely includes all of the things outlined. I've always been interested in this. PW started as just the content framework, and underneath it still is. I'd like to retain and reinforce those roots. But don't think I want to actively maintain PW as two projects until there is real need for it (just as a matter of resources). I'd like to make it easy for people to integrate components if they want to, and I think Composer is probably the way to do that. But don't currently see a need for any of our core components to come from another framework. Though I'm always open to the idea if there is a real benefit to our users. IoC is not a new concept. ProcessWire was written with an emphasis on best practices, patterns and concepts like this, everywhere beneficial to the project goals. The primary need for unit tests in PW has been with the selector engine, both DB and in-memory, and the consistency of the two. Luckily this is an active project, and it has already been hugely helpful and influential in ProcessWire 2.3 (thanks to Nik). In fact, I would probably consider the issues discovered and resulting solutions the most important upgrade to come with ProcessWire 2.3.
  18. You probably already know this, but you can also specify a path to your own "contents.css" file. It's basically the same as in TinyMCE, where you would want to copy out the default copy and place it somewhere in your /site/ structure, and then modify it to suit your needs.
  19. In addition to what Nik mentioned, I would see if you can narrow down where the bottleneck is. Add the following to the beginning of each function: $timer = Debug::timer(); And add the following to the end of each function: echo "<p>" . __FUNCTION__ . " with page $category->path executed in " . Debug::timer($timer) . " seconds.</p>"; That might help to narrow it down. But if these function calls really are generating navigation with 400+ items, I probably wouldn't expect it to be lightning fast. It would be a good candidate for using MarkupCache. To use MarkupCache, replace all your "echo string" lines in the function with "$out .= string", so that you are populating a variable with the output rather than echoing it. Ideally your functions return the output so that the caller can do the echo, but you could also just put your echo at the bottom of the function. Once you've done that, you can use MarkupCache by putting this at the top of your function: $seconds = 86400; // 1 day, or 3600=1 hour $cache = wire('modules')->get('MarkupCache'); $out = $cache->get("homeHeader($category)", $seconds); if($out) return $out; // or echo $out; // ...the rest of your function code... $cache->save($out); return $out; // or echo $out;
  20. Actually it has support now, and it's there in 2.3. But it's considered "beta", so I don't recommend using it on production sites until I'm at least using it on a production site (which should be about a month from now). But I think it's perfectly fine to go ahead and work with it now for testing and/or development.
  21. In this case, you'd probably have the reverse the logic of the addable() hook. You'd give them the template access. But your addable() and editable() hooks would take it away. That's one approach you could take anyway... But if the blank templates list was the only issue before, you might just want to edit that /wire/modules/Process/ProcessPageAdd/ProcessPageAdd.module file and prepend the getAllowedTemplates() function with 3 underscores, renaming it to: ___getAllowedTemplates(). Then it becomes hookable, and you can modify the value that it returns from your module. Currently in your case, it's returning nothing (since they have no edit access on the template). So you'd want to make your hook modify the return value to include the templates you want them to be able to select from. If you find this worthwhile, let me know and I will update the core to have that function hookable.
  22. I think that some kind of aggregate fieldtype that encompasses others would be a fine way to go. I don't see it as something I would personally use all that often, but I can understand why others might find it useful–it's a worthwhile idea. From the implementation side, a single item repeater probably would be the quickest/simplest way to implement such a type of grouping. But there are some significant differences to the point where it may be better off as it's own fieldtype, perhaps that extends FieldtypeRepeater. Either that, or something new that just takes a similar approach. After all, an aggregate field wouldn't need but 1 "ready page", it wouldn't need a repeater parent page, and could be built around the Fieldtype class interface rather than the FieldtypeMulti interface. It would have less overhead than repeaters would in some areas. There are surely even more efficient ways it could be built, but the repeater-model approach would be the most likely way to make it something tangible in a shorter period. I'll keep marinating on it here.
  23. Glad you figured it out. We give first choice to $config->uploadTmpDir (if set), but prefer to use PHP's 'upload_tmp_dir' setting since this will presumably be somewhere outside the web accessible structure. It sounds like in your case, the server did not have PHP's 'upload_tmp_dir' setting defined. Now we could have uploadTmpDir set to something like /site/assets/uploads/ by default. But that's under the htdocs structure (though we do block it in htaccess) and I think it's a little more secure to have the server tell us where these files should go… at least as a default.
  24. Not sure I understand the question (if it's still a question?) but want to mention that MarkupAdminDataTable is just a markup generation helper, and you shouldn't feel confined to it. If you have some table generation needs that aren't being covered by it, there's no harm in generating your own table markup.
  25. I'm not sure I understand all the code examples or what the structure is underneath well enough to say what's wrong. The logic here is difficult to follow. But I see a few things I would change with the code: This block of code has problems with the $thisCategory variable: // Grab the page name from the url $thisCategory = wire("page")->name; // If the category is not called "news" then output the category name as a selector for the find. if($thisCategory !="news") { $category = "article_category.name=" . $thisCategory; } // Get the news posts - limited to ten for later pagination $newsposts = wire("pages")->find("has_parent=$thisCategory, template=news, sort=-date_time, limit=10"); Note that the $category variable above never got used–was it supposed to go somewhere? I'm making the assumption that was supposed to become $thisCategory, but don't know for sure. Double check that your "has_parent" shouldn't really be a "parent" instead? I can't say without knowing the structure, but the use of has_parent seems unusual here to me. Also, I don't think there's any reason to have $thisCategory be the page name. You should just keep that as the page object instead. This becomes a problem in particular where you are using it in that last find() because find("has_parent=$thisCategory") is resolving to something like "has_parent=some-page-name", and that's invalid syntax because has_parent expects a page ID, object or path. So I would change it to this: // Grab the page name from the url $thisCategory = wire("page"); // If the category is not called "news" then output the category name as a selector for the find. if($thisCategory->name != "news") $selector = "article_category=$thisCategory"; else $selector = "has_parent=$thisCategory"; // or maybe: parent=$thisCategory ? // Get the news posts - limited to ten for later pagination $newsposts = wire("pages")->find("$selector, template=news, sort=-date_time, limit=10"); I would also recommend passing in $thisCategory as an argument to the archivesNewsList() function, rather than pulling it from wire('page'); just because pulling it from wire('page'); means that the archivesNewsList() function can only be used on category pages, and maybe you'll want to use it somewhere else? Next up is an observation or a question. But if this is valid PHP syntax, I didn't know it: $out .="<img class='align_left' src='{$newspost->article_newsimage->getThumb(listingthumb)}' Does that really work? If so, I guess I didn't realize you could make a function call like that from within a string. So if that really works, then I guess I've learned something new. But if it doesn't, I'd suggest changing it to this: $out .="<img class='align_left' src='" . $newspost->article_newsimage->getThumb("listingthumb") . "'>"; You really don't need to redefine all the markup for the pager unless you want to. This is unnecessary extra code since it's already outputting an unordered list with these same labels: $out .= $newsposts->renderPager(array( 'nextItemLabel' => "Next", 'previousItemLabel' => "Prev", 'listMarkup' => "<ul>{out}</ul>", 'itemMarkup' => "<li>{out}</li>", 'linkMarkup' => "<a href='{url}'>{out}</a>" )); You can just do this: $out .= $newsposts->renderPager(); Last thing to mention is that there's no point concatenating everything into an $out variable when you are just echoing it at the end of the function. The purpose of stuffing into a $out variable is so that the function can return the value, to be output by the caller (which is what I usually do). So I would suggest making your function return $out; rather than echo it, and making the function call: echo archivesNewsList($categoryPage). If you'd rather have the function echo it, then don't bother with $out, just echo the strings as you go.
×
×
  • Create New...