-
Posts
16,793 -
Joined
-
Last visited
-
Days Won
1,540
Everything posted by ryan
-
Try to assign the superuser role when logged into your 'admin' user account. Unless your 'admin' also has the 'superuser' role, they won't be able to assign it. Yes, they'll see it as an option, but once you try to save it, it will throw an error. ProcessWire doesn't know what your roles mean to you (like one user being above another), but it does know what superuser means, so it's not going to let a non-superuser assign superuser to someone else (or yourself). Beyond that, you should consider a user with administration control of users a fairly powerful permission at present. Though I do like your idea of limiting the assignment capabilities to the roles that the user administrator also shares. It would mean giving that user additional roles purely for the sake of assignment permission, which would be a different factor for roles than we usually think. But it is an interesting possibility. Though it might conflict with what page permissions you want the user to have. But if we can assume a user powerful enough to assign a role is also powerful enough to have all the permissions of that role (like with page editing and viewing, etc.–a safe assumption I think) then it could work. I'll think more on this and perhaps it would be a good feature to add.
-
What version of ProcessWire, and have you already tried replacing your /wire/ directory with a fresh copy?
-
No worries, that's pretty much what I already do. Unless a block of code is instantly understandable to me, I generally recode anything that goes into the core so that I can fully understand and comment it. That's why it sometimes takes me awhile to bring in PRs. But since I've got to support the code in the future, I figure I need to go through the process.
-
I think you could modify that PageList label by hooking in after ProcessPageListRenderJSON::getPageLabel. Argument 0 to the method is the $page that you want to get the label from, and the method simply returns the label that will be printed. Here it is if you'd like to take a closer look.
-
getQueryAllowedTemplates is basically a way to bypass inclusion of pages that use templates the user doesn't have access to. It deals with what pages will be allowed to be returned in a find/get result, and not anything to do with edit access. I tend to think you'd be better off going less low level than that. If the goal is to get things working right with count and pagination, then I think this can be bolted on to how the CustomPageRoles already works. Pretty much all page queries get routed through $pages->find() (including $pages->count()), so you can take advantage of that by hooking in before it and modifying the selector string (argument 0) to limit the found results to those within the users view access. For example, you might append "view_roles=$user->roles" to that selector string. That's a theoretical starting point at least. But if you'd prefer to do something like getQueryAllowedTemplates, let me know and I can make that method hookable (and thereby replaceable).
-
Thanks for this module Martijn! A couple minor things to mention: You might want to limit your hook to running only when the template is 'admin'. That way it won't be attempting to insert code in regular page renders (not that it does now, but it looks to be executing on regular page renders even if it doesn't do anything). You could do that by moving your hook-attaching code to a ready() method: public function ready() { if($this->page->template != 'admin') return; $this->addHookAfter('Page::render', $this, 'rewriteJsConfig'); $this->addHookBefore('ProcessPageList::execute', $this, 'appendStylesScripts'); } The other thing I wanted to mention is that you may not necessarily need to search/replace the rendered output. You can access the values that will be populated to the 'config' JS variable, anytime before render, with: $all = $config->js(); // returns array of everything for the JS config var $config->js('key', 'value'); // populate 'value' to variable 'key' $value = $config->js('key'); // get existing value of 'key' I'm not positive about what your search/replace was doing, so if I've misunderstood you can ignore this. But just wanted to pass this along in case it is applicable, as it might be more efficient to set/modify the values directly with $config->js before render, rather than search/replace after render.
-
Good links from Kongondo there. I also want to mention that if you like to learn by example, have a look at Adrian's FieldtypePhone and/or FieldtypeMapMarker modules in the modules directory (among others). These are Fieldtype and Inputfield combinations that present objects as their value, similar to what you are talking about. The big difference in your case is that your need is simpler (though not as DB friendly), because you'll be bundling it all up into a single JSON string. The place where you would convert your object into a JSON string is in your Fieldtype's sleepValue() method, and the place where you'd convert it from a JSON string to an object is in your Fieldtype's wakeupValue() method.
-
I had to setup a similar thing for the cmscritic.com site. Previously it had been running WordPress, which had all the articles living off the root URL. We wanted the new site to maintain all the same URLs as the WordPress site, rather than setting up 301s. So all the articles still live off the root URL, despite the fact that they are actually located within the tree. This is the case for other pages in the site as well. As an example of how to do it, see the cmscritic case study, and the /site/templates/home.php template file code in particular.
-
PW Best Practices: Application Structure (form handling)
ryan replied to alexeld's topic in Getting Started
Since you are comfortable with using the MVC pattern, this may be the way you want to go in ProcessWire too. ProcessWire is very much supportive of the MVC pattern, it's just that it doesn't require it. ProcessWire is providing your models, your template files provide your controllers, and you provide the views with the TemplateFile class (or some other view loader of your own if preferred). You can also choose to target some template files/pages as views and call $page->render() on them. If you are interested, the Blog profile does use an MVC-style approach and would be worth looking at. But after you spend some time with ProcessWire, I recommend finding the approach that best suits a particular situation rather than locking yourself down to using the same one all the time. ProcessWire is giving you a lot more in some areas than a typical MVC framework does, so you may find even faster and more maintainable ways to structure your code, depending on the situation. -
I'm wondering if you might have one of those buggy MySQL versions that keeps turning up at some hosts? Can you tell what MySQL and PHP versions are running there? I also find the "undefinedpage" thing very odd–it makes me wonder where that's getting injected from, because I don't think it's coming from PW. I would open up our JS console and make sure there are any JS errors occurring when you see that "undefinedpage". It sounds like you've uploaded a new copy of DB, but you might also want to upload a new copy of the site itself. Rather then replacing into, remove or rename the existing /site/ and /wire/ directories first, creating new copies of them when uploading.
-
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.
-
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.
-
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.
-
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.
-
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
-
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.
-
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); } }
-
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.
- 27 replies
-
- 2
-
- multisite
- many pages
-
(and 2 more)
Tagged with:
-
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.
- 3 replies
-
- 4
-
- multi-site
- geo-targeting
-
(and 2 more)
Tagged with:
-
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?
-
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.
-
Thanks celfred–Glad you like the Pages Web Service module!
-
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).
-
Nice job NoDice, looks awesome!
-
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.