Jump to content

ryan

Administrators
  • Posts

    17,255
  • Joined

  • Days Won

    1,709

Everything posted by ryan

  1. This is one area where costs speak louder than words. Give them an estimate for your time on how long you think it will take to invent a new sortable checkbox field type, then give them the cost for using something that already exists and is designed for this purpose. I have a feeling they will be enthusiastic about learning how to use the new field.
  2. This problem has been fixed in the latest commit. The issue was actually that I moved some of this stuff into tabs. The tabs move some markup around, so any <script> tags in those tags get executed twice (once when page loaded, and again when tab draws). This is just something that happens in javascript when you move markup around. The solution was to remove <script> tags (via JS) before drawing the tabs. This is okay to do since those <script> tags had already been executed by the time they are removed. Thanks, Ryan
  3. If I'm understanding correctly, your client actually wants sortable checkboxes? There is not a way to create two fields and have them share the same data. I should say that 100+ checkboxes is usually considered a problem from an interface perspective. Such a solution can't scale forever and at some point you'll just run out of memory (though, you'd have to scale quite a bit larger before that became a problem). For something that is going to keep growing, you need some form of pagination in there. The PageListSelectMultiple is something that will scale indefinitely and it does support sorting. I don't know of any other solution (in or outside of PW) that supports that scalability and sortability together in one field. If you wanted to create sortable checkboxes, you could always create a new Inputfield type for ProcessWire, and use it along with the Page reference fieldtype. This would require getting into some PHP and deeper into the PW API, but it is doable and we're always here to help you figure it out. If you go this route, I would probably use the InputfieldAsmSelect module as a starting point to adapt from.
  4. Here is an example module for adding tabs to a page. I tried to cover a few things you might want to do after you've added the tab too, just as examples. If you want to download the module file (rather than copying/pasting), it is attached at the end of this message. <?php class PageTabExample extends WireData implements Module { /** * Provide information about this module to ProcessWire * */ public static function getModuleInfo() { return array( 'title' => 'Page Tab Example', 'summary' => 'Example of adding tabs to the page editor', 'version' => 001, 'permanent' => false, 'autoload' => true, 'singular' => true, ); } /** * Add the hook * */ public function init() { $this->addHookAfter("ProcessPageEdit::buildForm", $this, 'buildForm'); } /** * Hook called after PageEdit::buildForm is called * */ public function buildForm(HookEvent $event) { $form = $event->return; $this->example1($form); $this->example2($form); $event->return = $form; } /** * Add a simple tab to the page edit form * * Note that would technically add the tab link after the 'view' link on the form * See example2 to see how we get the view link at the end (assuming that's where you want it) * */ protected function example1($form) { // create the new tab $tab = new InputfieldWrapper(); $tab->attr('id', 'tabExample1'); $tab->attr('title', 'Example 1'); // create a general markup field as an example $field = $this->modules->get("InputfieldMarkup"); $field->attr('name', 'fieldExample1'); $field->label = "Example 1 field"; $field->attr('value', "<p>This can contain any markup you want</p>"); // add the field to the tab $tab->add($field); // add the tab to the form $form->add($tab); } /** * Add a tab before the 'view' link * * Also demonstrates setting or retrieving a value submitted to a field in the tab. * */ protected function example2($form) { // first we have to find and remove the view link, temporarily $view = $form->children('id=ProcessPageEditView')->first(); $form->remove($view); // create the tab $tab = new InputfieldWrapper(); $tab->attr('id', 'tabExample2'); $tab->attr('title', 'Example 2'); // now add our new tab and field $field = $this->modules->get("InputfieldTextarea"); $field->attr('name', 'fieldExample2'); $field->label = 'Example 2 field'; $field->description = "Enter some text. The text you enter won't get saved with the page, " . "so you'd have to do something with it in the same hook that displays this."; // since this isn't technically part of the page's fields, we have to // handle any input submitting to the field if we want it. if($this->input->post->fieldExample2 !== null) { $field->processInput($this->input->post); // we'll store in the temporary session var just an example. // using session just for example, you likely would save your value elsewhere. $this->session->fieldExample2 = $field->attr('value'); } else { // retrieve the value from the session var. $field->attr('value', $this->session->fieldExample2); } // add the field to the tab $tab->add($field); // add the tab to the form $form->add($tab); // now add that view link back to the form at the end $form->add($view); } } PageTabExample.module
  5. @jbroussia: PW is writing all new fields when you do $page->save(). Since we set it's ID as 0 and called $page->setIsNew(true), we tricked ProcessWire into thinking it was a brand new page that it had never saved before. So from that point it is creating all new fields when you save it. Also, when we did "$cloned = clone $page;" it automatically cloned all the fields in memory too, so $page and $clone aren't sharing the same memory even for that moment. This occurs because PW implements PHP5's __clone() method and specifically sets up new fields at at that time. Admittedly, this is one of the first opportunities I've had to actually use it. You are right that file fields are different because they have corresponding files on the disk. PW needs to know where to place those files, and there's no way for it to know until the page has actually been saved (since the directories are based on the page's ID). So this is one of the details we would have to take care of with a $pages->clone function by saving/creating the page, then copying the files, then saving again.
  6. Perhaps we shouldn't have a template called 'page' in the default profile. That was just the naming convention I used there to mean that it was for use by any generic/general/non-specific page. But it has no real relation to the PW term 'page', other than that. And thinking about it more, Drupal also has a template-file called 'page.php', which likewise means something different. You are right, this is a bit confusing. Thanks for pointing it out. I'm going to rename that 'page' template to something else (maybe 'general') in the default profile.
  7. I'm assuming you are using PW 2.1 for all of this. But let me know if not. You are working with stuff that is somewhat different between PW 2.0 and 2.1, and I would definitely recommend sticking with 2.1 if you are creating new modules since we're just about to the point of making it the current stable version. You shouldn't have to clone any of the fields (or database entries), PW will do that for you. I just tested the example here and it did work for me (cloning the page and the fields). Though I should note I did have to add $cloned->setOutputFormatting(false); before I saved it. That would only be necessary if you put the code snippet in a template file, as I did. The only field I can think of that it would not currently work for is a file or image field... but I'll work on that. You don't have to clone any role/permission stuff because those are assigned at the template, not the page. So your clone will simply inherit the same roles from the template as the original did. Do you need the recursive/children cloning like jbroussia mentioned? If so let me know because I will want to get that new $pages->clone function in place this week so that you don't have to wait for this.
  8. Well it just started happening on my computer this morning. So I'm able to reproduce it here now. No idea why it just started occurring, but I should be able to fix it now.
  9. I may be confused, because think the previous example Antti posted should do this? The only thing I can think of is if you don't want it to expand the Gallery or Delta menus (assuming they have subpages) or if you want it to include/exclude certain items from the Contact menu. The example you posted is how you want it to look, is this correct? If so, can you post another example with how it appears using that treeMenu function? Also note in that treeMenu function you'll want to exclude this text "template!=post, template!=faq-item, template!=gallery", which is specific to the context Antti posted, but wouldn't be to yours. I think once we see what's different from your desired result you posted earlier, then it would be simpler for us to solve it. I think that you will just want to call that function like this: echo treeMenu($page);
  10. ryan

    Checkbox

    Here is the recommended way to do this in ProcessWire (using your example): 1. Create a page: /options/favorite-foods/ (for example). Though call it whatever you want and place it wherever you want. 2. Add child pages: /options/favorite-foods/chocolate /options/favorite-foods/pizza /options/favorite-foods/gum /options/favorite-foods/waffles /options/favorite-foods/ice-cream /options/favorite-foods/donuts /options/favorite-foods/chips 3. Add a new "Page" reference field in Setup > Fields. Call it 'favorite_foods' (or whatever you want) For 'Dereference in API as', choose 'Multiple Pages' For 'Parent of selectable pages' select '/options/favorite-foods/' For 'Input field type' choose 'Checkboxes' 4. Add the new favorite_foods field to whatever templates you want, and you are set. More info: Need to add a new option? Add a new page under /pages/favorite-foods/ Want to do something cool with the template your favorite foods are using? Add this: <?php $links = $pages->find("favorite_foods=$page"); echo $links->render(); That would list all pages that had that particular favorite food selected. Perhaps this is a useful page in your site? Once you get used to the power of creating options this way, you won't want to do it any other way.
  11. Thanks Matt, this is awesome. Thanks for making this new version so quickly. Btw, my comment about the cache was a compliment for your solution. I was comparing to the context of another solution I saw that provided no limits on the number of cached/resized images... thousands of size variations per image could either turn into a DDOS attack or fill up a drive before long. I completely agree about drive space being cheap–might as well use it. ProcessWire works the same way your script does in that it only allows the target image dimensions to be specified by the developer.
  12. That code snippet above wouldn't clone a tree, just a single page. When this is implemented in the API, we'd let it be optional as to whether to clone the tree (i.e. be recursive). But we'd definitely provide that option, just like the delete() function provides that option (though requires it if the page has children). That setIsNew function isn't part of the public API, but it would be necessary in this case to tell PW that this is a new page it should create when it comes time to save. Otherwise the cloned copy would still remember that it was originally loaded from the DB. I can't think of another situation where you would ever need to use the setIsNew function, so that probably won't ever make it into the public API.
  13. Soma this seems like a great solution for when it's needed. Given that PW lets you specify image fields as "fields to show" in the pagelist (in each template's settings), it seems like it should do something like what you've put together here. If you don't mind, I'll implement something similar for when someone specifies an image field to appear in the pagelist.
  14. Pete, since I still can't duplicate here, I'm wondering if there may be some other module involved. What non-core modules do you have installed in PW? Btw, I tried in FF5 not FF6, and IE8 rather than IE9, so will try in FF6 tomorrow, just in case there's something there. Also, can anyone else duplicate this? Thanks, Ryan
  15. Assuming I'm reading it right, I think the only thing that seems different here is the classes you are applying on the opened 'Contact Us' link. What do those classes "dir rtl" mean in terms of how they should affect the behavior of this nav? Thanks, Ryan
  16. If you are starting a new site I would go ahead and use 2.1. But since we're still wrapping up some details, you would just want to test any changes locally (stage them) before pushing to your production server. However, that workflow applies regardless of version or CMS, so if you are using best practices with your workflow then use 2.1.
  17. @MattWilcox–thanks for your posts here. It sounds like the solution you've put together is intended to only send the target image size, rather than the result I was getting (both large & target). When exhibiting the intended behavior, it seems like this would be ideal especially for the situation we were talking about (images in a richtext field). My other concern about a similar approach (from another site) was the security of creating any number of resized images... filling up the drive. But yours only outputs predefined sizes, so that is great. @kunane–given that I recommended this as a possible solution [with reservations] even when I thought we had to live with both images coming through, now I would definitely recommend this solution [without reservations] for the question you had. Here's a few impressions about the different solutions. I don't think I would use both solutions together. If you are using Matt's solution already, I don't think it would be worthwhile to use the <noscript> solution with it because all the JPG requests are already going to be routed through Matt's PHP script (unless you exclude certain dirs). My impression is the <noscript> solution may be one to consider in cases where you have markup control (like in PW templates), already have full image size control (again, like in PW templates), want no server overhead (routing image requests through script), don't want to install anything, and/or want to be able to fine tune the various sizes used in a per-image basis. The <noscript> solution may lose some of it's convenience outside of a system like PW, because you may have to manage the various image sizes manually. Matt's script takes that role if your site is compatible with globally predefined sizes, which could be really convenient. That's my impression based on what I know so far, but I've not used any of these techniques on a production site yet. What are the other situations where you would use one solution over another?
  18. Since you guys need this sooner rather than later, I'll put it higher up in the priority list. Cloning a page will be relatively easy. Haven't tried it, but I think this may work: <?php $cloned = clone $page; $cloned->setIsNew(true); $cloned->id = 0; $cloned->name = $cloned->name . "-clone"; $cloned->save(); Assuming that much works, what I can say for certain would not work is file fields. This is where the process would become more complex than this, though shouldn't be bad. I'm adding this to the to-do queue on GitHub. Adding another tab (like a 'language' tab) to the PageEdit screen is going to most likely involve hooking into the ProcessPageEdit::buildForm function and appending another InputfieldWrapper to the form it returns. Probably best for me to setup an example for this–let me know when you are at the point where you want it and I'll get it going. Thanks, Ryan
  19. The images/files really aren't meant to function independently of a page. All of their ownership comes from a page. As a result, I would suggest maintaining a page for each image, and PW is designed for this. For instance, you wouldn't want an image field to have 1000 images on it because that's going to be really difficult to manage without pagination and such. But if you are using pages as images, no problem. To put it another way, pages can scale indefinitely, but file/image fields aren't intended to at present. As for keeping track of which admin user uploaded a particular image/file, that certainly makes sense. Though it also makes sense with any kind of field. The current plan is that we'll be keeping track of this stuff with a page revision manager and logs, so that you can have a history of all page edits and be able to see where every edit came from (and revert to it if you want). This is actually already functional, but hardly production ready so I'm continuing to work on it and targeting it for v2.3. Be cautious dealing with public data input, especially files. PW isn't designed to have it's admin tools exposed to untrusted users. The needs for anonymous/public data input are different from admin input. For instance, image uploads really need to have original files quarantined (not web accessible) and only processed/resampled versions of images web accessible. Yet this would be a counterproductive approach for admin needs. PW's fields are designed for administrative and trusted users. Uploaded files go right into the /site/assets/files/ directories and not into a quarantine area. As a result, when I'm implementing some kind of public file upload on a site, I usually write the code for that with security specific to the need–it usually involves a quarantine area and babysitting the uploads.
  20. I think that makes sense. If they've specified certain child templates as allowed in the template settings, then I think it should follow what ever order they've specified. Whereas alpha order makes sense if they haven't specified anything. But since the order is sortable in that part of the template editor, we might as well retain it. I've added this to the GitHub issues list. Thanks, Ryan
  21. Those tabs are being generated by javascript from the existing markup. The tab label appears in the 'title' attribute of markup like this: <li class='InputfieldWrapper ui-widget' id='ProcessPageEditContent' title='Content'> As a result, I would maybe suggest a search: id='ProcessPageEditContent' title='Content' Replace with: id='ProcessPageEditContent' title='Inhalt'
  22. I think we'll have to build a module to provide this functionality in the near future (or include it as a configurable option in the PageEdit module, if necessary). I've run into the same need a few times when adding a bunch of pages. It would be nice to just create one right after the other. At the same time, I don't really like having a control like that permanently fixed to the interface like it is in modx. So I think we'll make it something that the powerusers can enable when it suits the need.
  23. Glad you got it working. It's pretty unusual for a webhost running PHP5 to not have JSON support, as it's part of PHP's default installation–they would have to specifically disable it. But I know there are some that install PHP and basically exclude everything possible... that usually means bigger problems than just missing JSON support. There are workarounds for missing JSON functions. You can always define your own json_encode/json_decode functions and solve the problem that way. A good JSON library is the one included with the Zend framework. Years ago I dealt with a client's server that didn't have JSON support, so used Zend's framework and created the functions that way. It works, but much better to have them native in PHP (faster running).
  24. Thanks Pete! I did the same thing before our little one arrived–got as much work done as possible. My work hours pretty much got cut in half afterwards. But it's definitely worth it. I just like to keep up with the forum as much as possible. I don't like killing anyone's momentum by making them wait days for an answer on a simple question. Luckily I've got a few minutes at the computer this morning, so hoping to get caught up.
  25. Several new messages I want to reply to came in since Friday night here. Apologies I've been unable to reply yet. My wife and daughter are very patient with me during the week, but don't like me near the computer on the weekend. So I've been reading on my phone but can't properly reply till back in my office at my computer. So thanks for being patient with me this weekend and I'll reply by Monday (or tomorrow if anyone takes a nap at my house) I just didn't want anyone to think I was ignoring their message--my computer access is just limited on the weekend, some weekends more than others.
×
×
  • Create New...