Jump to content

ryan

Administrators
  • Posts

    16,715
  • Joined

  • Last visited

  • Days Won

    1,516

Everything posted by ryan

  1. That code snippet doesn't really have anything to do with dependencies. Sorry I thought it was just a side question about repeaters, not dependencies. If you want to show/hide a repeaters field (the entire thing) based on the value of some other field in the form, you should be able to do that. Or if you want to show/hide some field within a repeater (all of them at once) based on the value of some field outside the repeater, that might possibly work too. But if you want to build-up dependencies based upon values within the repeater items, I don't think you'll be able to do that at present.
  2. Thanks for the updates Manfred62. Timeline to release is whenever the dev source can sit for a few days without needing any bug fixes or updates to it. We were getting close, but I've lately been adding more to it, so not yet sure on a release date. But I would like to do a lockdown for additions pretty soon, so that we are only updating for bug fixes, and that should present a release date soon after.
  3. Sorry, writing in browser, I forgot the quotes around the value. It expects an array or a csv string, but maybe I should update it to support a single integer as well. But currently any of these should work: $p = $pages->getById("123", $template)->first(); $p = $pages->getById("123,456,789", $template)->first(); $p = $pages->getById(array(123), $template)->first(); $p = $pages->getById(array(123,456,789), $template)->first(); This may be possible (though not yet sure how). But it assumes you are specifying a template because you know what template it should use. This is why it can increase performance: because it doesn't have to go determine that for itself. It may give you a frankenstein page by specifying the wrong template. There is a reason why this function is not meant for the public API–it's low-level and really meant to be accessed through the other API functions. So if you use it, and aren't certain of the template already, then it's best not to specify the template. Most of PW's internal calls (resulting from a find or a get) do use this optimization, passing the template and the parent to getById(). It needs to know the template in order to know which fields are contained by the template's fieldgroup. This is so that it can determine which fields should be joined with the main page loading query (autojoin). A few years into this, I find that I don't really need to use autojoin fields all that much (perhaps MySQL has gotten faster), so we may be able to change or get rid of this down the road.
  4. Diogo and Horst's suggestion to add that bit of code to a template file–temporary–is probably the fastest way to find out what the admin URL is: echo $pages->get(2)->url; Also, double check that you are using a trailing slash on your admin URL.
  5. Thanks for the PR Soma! I will pull this in within the next day or two and make any necessary updates to the CKEditor plugin as well. Default language is required. But you could always add your own checkbox field to the page as a toggle to disable it. Your head.inc or _init.php or whatever your common initialization file is could check: if($page->disable_default_language && $user->language->isDefault()) throw new Wire404Exception(); You'd also have to consider it with navigation generation, perhaps skipping over pages that have the toggle set while in the default language, or adding it to your selectors when querying pages. Edit: you could also just choose to not use the default language at all. if($user->language->isDefault()) $user->language = $languages->get("en-us"); // or whatever you want your default to be
  6. ProcessWire already keeps a references to the users that created the page and last modified the page, so you don't need to maintain that separately yourself. They are present in $page->created_users_id and $page->modified_users_id (to get the ID) or $page->createdUser and $page->modifiedUser to get the User objects.
  7. It might be feasible to do something like Soma's function above, where it populates the old (valid) value back when an invalid value is received. But rather than throwing out the old value, remember it a session variable. Then your module would also hook after ProcessPageEdit::buildForm and cycle through the any saved session variables, populating back the values it recorded (and removing them from the session). It's necessary to use session variables here just because there is a redirect between saving an editing again, something that is not obvious when you are using PW to edit pages. I would recommend something like: $values = array( 123 => array( // indexed by page_id 'date_from' => 'October 33, 2013', // invalid date 'body' => 'some bad words here', // invalid value ); $session->set('PageEditBadValues', $values); Also wanted to recommend hooking ProcessPageEdit::processInput rather than InputfieldForm::processInput, just so that you are limiting the action to the PageEdit form and not getting involved with other InputfieldForms unnecessarily. Your after(ProcessPageEdit::buildForm) function might look like this: function hookPageEditBuildForm($event) { $form = $event->arguments(0); $page = $event->object->getPage(); $values = $this->session->PageEditBadValues; if(empty($values) || empty($values[$page->id])) return; $values = $values[$page->id]; foreach($values as $fieldName => $value) { $inputfield = $form->getChildByName($fieldName); if(!$inputfield) continue; $inputfield->attr('value', $value); } }
  8. Technically I suppose you could have thousands of templates, but that's not where the scalability focus is. PW is designed to scale to unlimited pages, but not templates or fields. There's also the development factor–I don't think one could effectively develop a site with thousands of templates because that's just too much to keep track of. Consider the computer dictionary definition of Template: "a preset format for a document or file, used so that the format does not have to be recreated each time it is used." That describes templates in ProcessWire–something common so that you don't need huge quantities of them. Mary–do you think you need thousands of templates for layout reasons, field reasons, or access control reasons (or something else)? I think you'll be able to achieve what you need while only having a few templates, but want to better understand the foundation of the need.
  9. It sounds like this is more multi-language/similar-site, rather than actual multi-site. You mentioned all the domains describe the same content (for the most part) so I would probably take the "multi-site" out of your thinking about it, because it's only multi-site so far as it is multi-language. I'd use the dev branch, purely because it's going to take you a lot farther on the multi-language side. It should be plenty stable, but you'll just have to use extra care when updating (i.e. test things out on your own before upgrading a live server). If you could, I would try to do this all on 1 domain rather than split among multiple domains, but I'll assume that's not an option. But it'll be workable either way. If using multiple domains (or subdomains), you'll only need to install the LanguageSupportPageNames module if you want to have the same pages use language-specific names. I'm guessing you'll want that. However, you'll want to set the $user->language yourself, based on the domain/subdomain, rather than any other factor. You can do that with code like this at the top of a common include/file for all site template files: // grab the subdomain, i.e. "en", "de", "at", etc. list($languageName) = explode('.', $config->httpHost); // sanitize it just for good measure $languageName = $sanitizer->pageName($languageName); $language = null; // attempt to find a language with the same name if($languageName) $language = $languages->get($languageName); // if no language matches, then we'll assume 'default' language. if(!$language || !$language->id) $language = $languages->get('default'); // set the language to the user $user->language = $language; The above is essentially serving as your "multi-site" code, forcing the language to match the subdomain. You'd want to remove any other multi-site solutions. You'd want to use multi-language text fields where possible. When using multi-language textarea fields where you need rich-text editing, I suggest installing the InputfieldCKEditor module and using it in inline mode. This scales much better for multi-language environments than TinyMCE. For situations where you need different images per language, you can use the tags feature to devise your own matching method (perhaps using the language name as the tag), or you can use language alternate fields. For situations where you have a page available in one language and not another (or some and not others) then you can simply make them active or inactive from the checkboxes on each page's "settings" tab. To summarize, I would treat this site purely as a multi-language site, and would probably develop it without considering the multiple domains/subdomains. Then when it comes time to launch, point all those domains at the same site, but use the $config->httpHost trick above to set the language based on the subdomain its being accessed from.
  10. I'd be curious to know how you created the non-working field, just so that we can prevent that from happening in the first place?
  11. It does kind of depend on how many users we're talking about here too. I would not be so enthusiastic about creating caches on a per-user basis, and more likely to focus any caching efforts on common content, that's the same for all users. But if it makes a major difference in performance, then the tradeoffs might be worthwhile, but still something to be cautious with.
  12. Thanks celfred–Glad you like the Pages Web Service module!
  13. I think that's okay, but it could be problematic in some cases like when file locations are different between master and dev, or when dev is using an updated DB schema from master. I don't think that either is the case right now, but just something to watch out for. The safest bet is to run them on separate databases. In your current setup, worst case is probably that you could end up being only able to run dev (with some part of the DB schema not compatible with the older stable branch). The changing file locations is not so much of an issue, but if you get errors you might need to manually clear the Modules cache (i.e. remove all /site/assets/cache/Modules.* files).
  14. ryan

    Half way there

    Nice job NoDice, looks awesome!
  15. Thanks for the description, this may help me to reproduce. I don't yet have a good test case setup–I want to debug it now, but still have 3 pages of messages to get through, so may not get time today. But this week I was experiencing the same error you were, though in an entirely different situation. But it did reveal a problem where $pages->save() was catching an Exception that it shouldn't have, and this was leading to fieldtypes trying to save, presenting the familiar "Unable to save to 'field_title' for page that doesn't exist...". This is now corrected on dev, as of yesterday. I don't think it will fix the problem you are experiencing, but the result of the exception might very well reveal what the problem is. If you have a moment to try the latest dev sometime with the same situation, please let me know what you find. Otherwise, I will work to duplicate the issue here soon.
  16. I'd tend to agree with you that it might be specific to that version of MySQL or something else specific to the server. But I'm going to keep an eye out for anyone else reporting something similar. If there's a problem there, it'll appear elsewhere, and that'll be a good signal to start debugging it. But so far I can't duplicate, so am thinking we should avoid debugging this too much until there's some indication it goes beyond 1 server.
  17. Thanks for the testing and reports maba and Raymond, I'll experiment here and see what I can find/fix. But regarding the image field, I don't think you'll be able to use that as a live dependency because the ajax upload isn't submitting the entire form, just a single field. So when it gets processed, the context of other fields is not known. Only the existing page state is known. So that dependency would probably only come into play after the page is saved in full. As a result, image/file fields may not be good candidates for dependencies, unless we turn off the ajax upload for that situation. A repeater is a PageArray, so you'd have to extract an element from it first. Like if you wanted the first element: if($page->contentblock->first()->contentblock_headline != '') { // something }
  18. Those above are actually translated with the individual modules (ProcessUser, ProcessRole, ProcessPermission), though looks like I didn't yet it have it translatable for ProcessLanguage. Though there's no harm in having them translatable there too, but just not sure it's necessary. Good catch–thanks, I have added this and they'll be on dev shortly.
  19. Can you describe your scenario? Here's a common scenario: Lets say you've got a section called /articles/ and you want to have authors that can edit articles: 1. Create new role called "author" and check permission box for "View" and "Edit". Assign this role to one or more users you've created. 2. Edit your "Article" template (Setup > Templates > edit), the one represented by /articles/some-article/, etc. 3. Check the "yes" box on "access" tab to enable access control. 4. Next to the "author" role, check boxes for: View, Edit Want your authors to be able to create new articles too? 1. Edit your "Article" template again, check the box for "Create" for the author role. 2. Edit your "Articles" template (the one represented by page /articles/). Enable access control and check the box for "Add Children" for the author role. Want authors to only be able to create new articles but not to publish them? 1. Add a new permission (Access > Permissions > New) and call it "page-publish" 2. You don't have to do anything else. Since the author role doesn't have page-publish permission, they can't publish pages. They can still edit and create unpublished pages. Tell me more about your scenario and I'll outline instructions.
  20. I don't think it's related to field dependencies. Sounds like that floatval() at the end needs to come out, but somehow we need to get the value converted to a real float/decimal number that MySQL will accept. You could try commenting out the floatval() at the end of the sleepValue() function in /wire/modules/Inputfield/FieldtypeFloat.module. Maybe we can just pass it to the DB as a string? i'm reluctant to do that since wakeupValue is meant to return a value in it's native state, but if it fixes this issue it'd be worth it. Thanks for your testing with this btw.
  21. Like mentioned above, urlSegmentStr is your ticket. Note that it has no trailing slash, so you may need to add one to it in some instances. Also want to mention that the $input->urlSegments Array is not useless at all – I use it all the time. Just one small example is to count the number of urlSegments: count($input->urlSegments);
  22. While true that you've got a lot of options there (and perhaps more than most people need), I don't think it interferes with the regular use of the module either. Testing it out here, all seems to work nicely and didn't present any configuration challenges. While I didn't need the ability to define custom formats just yet, it's always nice to know that I can.
  23. I agree with you on this. It would be tricky and problematic. You'd have to enforce use of separators, likely both client side and server side. Having them split in two fields is a way of doing that already, while eliminating the possibility of errors. It does make it harder to enter and/or paste in a phone number, but it's ultimately more bulletproof. I can update the logic of the wireEncodeJSON function to detect a 0-prepended string, but that won't help with past versions. Since you aren't calling wireEncodeJSON yourself, I'd suggest maybe prepending something uncomming to your format before the 0 (like a "~") and trim()'ing it out when using it. Silly I know, but I can't think of another way around that short of requiring a specific version of PW. That might make sense, as I'm thinking an individual installation will probably want to standardize on one format rather than revisiting it for each field. Thanks for your updates, I am going to download now!
  24. Sevarf2, you are correct about something here in that theoretically, supplying the template to the find() call should enable it to run faster. ProcessWire needs to know the template for a page before it starts loading it. So it'll query the DB for the page's template if it doesn't already know it. However, we don't have that optimization in place for $pages->find() at present, so your $pages->get("id=123, template=book"); doesn't benefit from that. But you can take advantage of that optimization by using the $pages->getById() method. It would technically be the fastest way to retrieve a page, but it's rare that I would be up for using it when developing a site (I only use it for core development). But it may be worth trying if you are trying to optimize a large amount of page retrievals. I'm not sure it'll make much difference in the end, but it's worth a shot. $template = $templates->get('book'); $page = $pages->getById($page_id, $template)->first(); The getById() method is really meant for retrieving multiple pages, which is why it returns a PageArray. If you have multiple pages using the same template, you can retrieve all of them here: $pageArray = $pages->getById(array(123,456,789), $template); If you can also supply a parent_id to the method (meaning, you already know all the provided page IDs have the same template and parent), it can use that for a little further optimization: $pageArray = $pages->getById(array(123,45,789), $template, $parent_id); Btw, the purpose of $pages->getById() method is as a support for all the other get(), find() and children() methods in ProcessWire (or anything else that returns a Page or PageArray from the DB). All pages loaded from the database are loaded by the getById() method, so all the other get/find methods are actually front-ends to it. getById() was never intended to be part of the public API though.
  25. Selector may be a good way to go in that case. We'll have to look closer at this. But if you are interested in experimenting with different options, one way to go would be having a module add a new hook function to the Pageimage class, like this (warning: written in browser, not tested): public function init() { $this->addHook('Pageimage:mySize', $this, 'mySize'); } public function mySize(HookEvent $event) { $pageimage = $event->object; $selectorString = $event->arguments(0); $selectors = new Selectors($selectorString); $settings = array(); $width = 0; $height = 0; foreach($selectors as $selector) { if($selector->field == 'width') $width = $selector->value; else if($selector->field == 'height') $height = $selector->value; else $settings[$selector->field] = $selector->value; } if(count($settings) || $width || $height) { return $pageimage->size($width, $height, $settings); } else { return $pageimage; // nothing to do, return original } } Usage: $thumb = $page->image->mySize("width=300, height=200, upscaling=0, sharpening=medium");
×
×
  • Create New...