-
Posts
16,772 -
Joined
-
Last visited
-
Days Won
1,531
Everything posted by ryan
-
Waiting for "ProcessWire 2.2 [HARD launch]" (Release date?)
ryan replied to Nico Knoll's topic in Pub
ProcessWire 2.2 is already released, so the term "hard launch" would refer to the date when we send out press releases to various sites to announce it. Before that happens, I want to get an official language pack section setup on the site and wrap up a bit more documentation. I would say we'll do a hard launch in two weeks, roughly. But don't wait to upgrade to PW 2.2, as it is now considered the stable version. -
That's great to hear Google can execute JS and index stuff from it. That's quite a technical feat, I'm impressed. I did some testing a couple days ago with Disqus and found Google wasn't indexing them. But it may just depend on the site, widget version, etc. But the fact that they CAN definitely changes my opinion about javascript-based comments. However, I still have to believe there are major advantages to staying in control of the markup and accessibility of your comments… but just not as many as before. Things are always changing for the better.
-
Sorry, I misunderstood. If those files are only going in the places that need it, then the concern I had is not applicable. Not necessarily. When a file is on a protected page, ProcessWire could spit out a link to the passthrough script as the $file->url(), like domain.com/files/123/somefile.pdf, rather than to its protected location in /site/assets/files/.123/. The $file->filename() property would still refer to the actual disk path since htaccess limits aren't applicable there.
- 27 replies
-
- private
- protected files
-
(and 1 more)
Tagged with:
-
Thanks Dave, you are right, that's a typo on my part -- it should be explode().
-
No matter where you use a selector like "parent=/path/" in the API, it's always going to refer just to direct children of that parent. The selector used in this field setting exhibits the same behavior as the rest of the API. I think what you might be looking for instead is the "has_parent" selector option, which is a way to refer to a page having a parent anywhere in it's ancestor tree. You won't see "has_parent" used in the API very much (or ever?) because you'd typically do this instead: $pages->get('/products/')->find('template=product'); But behind the scenes, that actually translates to this: $pages->find('has_parent=123, template=product'); 123 is the ID of /products/. The "has_parent" has to be used with an ID rather than a path, though I'll probably change that, now that there's an external use for it.
-
It does work for me. Are you sure you don't have one of the other fields populated, like parent or template? Let me know if you can think of anything else I might try to duplicate here. Also, regarding Antti's question -- are you using an asmSelect with a 1-page reference? asmSelect is only meant for multi-page references.
-
Nevermind about this, I was wrong as that limitation never made it into the code at GitHub (was already fixed before I pushed it to GitHub). I tried this as my selector with a multi-page field using asmSelect: parent=/building-types/, template=airports|aquariums It worked for me, showing the selectable pages I wanted it to. Is there anything else I need to do to duplicate?
-
I couldn't duplicate this until I tried with changing it to a single-page field rather than multi-page field. That did it, I could duplicate it. I looked closer and see we have an optimization that enforces the parent at load time, but only for single-page mode. Usually this optimization would be good, as it gives a slight performance edge. But obviously it's not good with PageListSelect, so I removed it. Thanks for finding this. I've committed the update to the 2.2 source. Is this paired with one of the PageListSelect inputfields? You mentioned asmSelect, but since PageListSelectMultiple also uses an asmSelect style sort list, I'm not sure. You probably saw the note with 'selector' and 'template' where it says "This is not compatible with PageListSelect inputfields". However, it should be compatible with a regular asmSelect Inputfield. But you might need to use parent=123 (page ID) rather than parent=/produckte/, though not for long (already a fix for that but still tweaking it).
-
Oliver, I'm not certain without seeing some code. If you'd like, PM or email (ryan at this domain) and I'll be glad to take a look. Is the page you've added your Process module to using the default 'admin' template, or something else? If not the 'admin' template, then note that you'll probably want to have URL segments turned 'off' in your template settings I think you already understand this part, but I'll describe how Process modules work with regard to URLs. If you have a Process module you've assigned to page /languages/ and you access that page, then the execute() method of that process will be called, and whatever it returns will be displayed. But if you access the URL /languages/add then it's going to call executeAdd() instead, and likewise if you access /languages/edit then it's going to call executeEdit() instead. There are no predefined segments, so it doesn't have to be "add" or "edit", but it can be whatever you want it to be, so long as maps to an execute[segment] function in your Process module.
-
check_access just refers to view access, and this is assumed if you omit check_access. So the only reason to ever use check_access is if you want to include pages the user doesn't have access to view, due to access control settings. To list the pages you mentioned, you'd just use "status=unpublished". If $user->isSuperuser() then don't bother performing any checks, because they will have access. You could cycle through the templates, see which ones are defining access, and of those, which ones have editRoles that are consistent with the users roles. Then include those templates in your $pages->find() selector. But this leaves out those pages that inherit their access. That's because that access is inherited through the hierarchy at runtime, so not possible to determine without actually loading the page and following it's inheritance path. As a result, this is a complex question to which there isn't a simple answer... at least not one I can think of yet.
-
I don't think it will. Once that "include=all" appears in there, that pretty much overrides anything else you might set in there. I think it would probably be unusual to ask PW to check access and include unpublished pages, but a potential need might involve including 'hidden' (but not unpublished) pages and disabling access checks. So in that case, you'd do: include=hidden, check_access=0
-
Antti's right about what that example is doing, but let me do another. Lets say we've hooked in before $session->redirect(). If I go look at the function definition in /wire/core/Session.php, I can see it has two arguments: $url and $http301. So lets say I want to hook into that and automatically add a GET variable to every redirected URL, like "url.com/path/?is_redirected=1", I'd do this: public function hookSessionRedirect(HookEvent $event) { $url = $event->arguments('url'); // get the existing value $url .= (strpos($url, '?') === false ? "?" : "&") . "is_redirected=1"; $event->arguments('url', $url); // set the new value that gets sent to $session->redirect } Btw, there is some overhead in using the argument names as opposed to the position (it involves using Reflection), so in most cases I think it's still better to use the argument position rather than the name. But have wanted to make both options available because I think some people will find it more straightforward to to use the argument names... and it no doubt makes code examples more readable.
-
Evan, make sure you sanitize $_POST['email'] before putting it into the selector. Since you are dealing with a page name, I recommend this: $name = $sanitizer->pageName($input->post->email); $my_page = $pages->get("template=template-photo, name=$name, include=all"); "check_access=0" will cause it to include pages that the user doesn't have permission to view as a result of access control. It's what you'd want to use if you wanted to (for example) generate public listings for pages, but only full members could view the whole page. In that fashion, you could have the page appear in lists to everyone, even if only the members could view it. The non-members could get a login page when they click on it. "check_access=0" won't cause unpublished or hidden pages to be included. Whereas "include=all" will include everything regardless of access, publish or hidden state. Any function that returns a PageArray (like $pages->find or $page->children) will have this access checking enabled by default, unless you turn it off with include=all. But functions that return a single page (like $pages->get) don't check for access/status since they are returning a pre-determined (by you) item and quantity, and aren't likely to be used for making navigation.
-
Nico, this has been added in the latest commit of 2.2. To make use of it, have your hooked function (getPage in your case) do this: $event->replace = true; // now original function won't be called $event->return = 'you are now providing the return value'; Also your hook obviously must be a 'before' hook in order to replace the original. So you'd init the hook like this: $this->addHookBefore('ProcessPageView::execute', $this, 'getPage'); Unrelated to the above, but another cool addition: I upgraded the hook system so that it will let you set or get hooked function arguments by name rather than just by position. So if you'd hooked into Pages::save, and you wanted to refer to the 'page' argument, you can now do this: $page = $event->arguments('page'); Before you could only do this, having to know what position the argument was in: $page = $event->arguments[0]; You can also set arguments back to the event by name if you want to, i.e. $event->arguments('page', $mypage);
-
Autocomplete and Other Search Enhancements
ryan replied to Michael Murphy's topic in Getting Started
This is the case with template, but not parent. If you set a parent, then PageListSelect assumes that to be the starting point in the tree. The pages don't have to have that parent directly. They just have to have that parent as an ancestor. This is the way it's supposed to work, and the way it worked here just testing it. Are you getting a different behavior? But you are right with regard to template. PageList doesn't take template into account because PageList is designed to list hierarchy not type. It's feasible in the future that template could be combined with parent as a constraint within the hierarchy defined by parent, but that ability isn't there right now. As a result, template constraints shouldn't be used with PageListSelect inputs. It's not just a matter of an Inputfield here. The paths for pages don't actually exist anywhere that can be searched. Paths are constructed and determined at runtime, and only for pages that are loaded. There's nothing to strpos() or find(). So we'd need to find a place for them to be cached before such a solution could search them (using that 'mypath' field, for example). I'll keep thinking if there's other ways. -
I love the utility of solutions like Disqus. But I also think one of the reasons (for some) to have comments on your site is to have more indexable content for Google, etc. When people are posting comments, your site is generating it's own content, and Google is picking that up. When you use something like Disqus, IntenseDebate, or FaceBook widgets, your comments are JS-powered. When spiders index the page, they don't see those comments and they don't become part of that page's indexable content … they don't contribute to your search performance. As a result, I think JS-based solutions like this are good for function, but not for performance. I care a lot about the search accessibility of content in my sites and wouldn't consider using a JS-based comments solution in my own sites, except as a temporary solution. Though in fairness, I've been using IntenseDebate on my own site for years (put in before PW's comments modules existed), but have always viewed it as temporary solution. My site has been ready for a re-do for a few years.
-
Autocomplete and Other Search Enhancements
ryan replied to Michael Murphy's topic in Getting Started
I think I might need to see an example, because the way you describe it, it seems to me like you'd want to setup the searchField as 'title', and the label as 'path'. That's something you can already do. But if you literally want to be dealing with paths for the search portion, you can search with the components of a path (page names). You can set it to use 'name' as the searchField. But because 'name' is just a word and not technically a fulltext field in ProcessWire, it's not in a fulltext index. That means you have to type the name, like 'about' (rather than 'abo') before autocomplete will return matching pages. But if you want to give it a try, edit your Page field using the autocomplete, and do this: 1. Leave all the selection fields blank so that it's searching your whole site (assuming that's what you want) 2. Choose 'path' for the 'label field'. 3. Under 'Autocomplete advanced options' choose '= Equals [exact]' for the operator and enter 'name' for 'Fields to query for autocomplete'. Note that '=' is the only operator that will work with the name field, so don't bother trying the others. Another route you can take is to create a new text field, call it 'mypath' or something like that, and have a module hooked to Pages::save that auto-populates mypath with $page->path() when the page is saved. Then tell the autocomplete to use mypath as the searchField. Just note that if one of the parent pages is moved or renamed, that mypath will be out of date. This may not be an issue on site where the structure is already concrete. But on an existing site, you'd have to make a script that goes and saves every page the first time to initially populate that mypath fields. Currently if you choose a parent and use a PageListSelectMultiple (for example) it'll let you select (and it will keep) anything within that parent's decedents. I just tested it here, and think that's the way it's always been? If I recall, you were asking about the 'template' selection, which PageListSelect Inputfields don't work with at present. When it comes to the Autocomplete combined with a parent selection, then it's only going to search the parent you specify (which may or may not be the behavior you want). But if you want it to search the entire structure contained by that parent, then you'll want to use the Parent in addition to the 'Custom selector to find selectable pages' option (just added it yesterday). Put anything in that selector, like "id>0" or "sort=name" or whatever you want. When you use that selector with parent selected, then it'll do a $parent->find($selector) rather than a $pages->find($selector)... meaning it'll return results for that parent and anything below. Another way you can do the same thing is to have no parent selected, and then enter "has_parent=123" for the selector, where 123 is the ID of the parent. -
That's correct that you should be able to change these things in /index.php (though I've not tried it out). However, I don't think you'll find any extra security in doing that. So long as you keep your htaccess file up to date with your PW version, ProcessWire's .htaccess is already blocking access to everything relevant in it's structure. Though there wouldn't be anything useful to a hacker even without the htaccess. Modifying index.php will also make upgrades a little more difficult, since it's considered a core file (one that is overwritten during upgrades). Unless you can think of something I've missed in this regard, and assuming your using a solid web host, I don't think it's worth the time/trouble to relocate directories. Years ago, it used to be (and may still be) considered good security to move the file with your DB password outside of the web root, and perhaps include it separately into the CMS's config. That was just on the off chance that PHP stopped working and Apache kept going, and started serving PHP files as TXT files. I have never seen this happen in the decade I've been using PHP, and don't think it's even possible with today's software. There was also the concern that some other user on a shared hosting platform could code up a script (running as apache) to file_get_contents() your config.php and see what your DB password is. I think there is merit to that concern on some web hosts, but most hosts are now sufficiently jailed to prevent such access from other users on the same server.
-
Autocomplete and Other Search Enhancements
ryan replied to Michael Murphy's topic in Getting Started
It'll work with any text field (or combination of text fields). But url or path is not actually a DB field that exists anywhere in PW. Instead it's determined at runtime for each page... so it's not one that can be queried. Title is probably the best way to go in most cases. Excellent point -- this is a great way to go so that you can use the same template for regular and ajax results. -
There's no getting around people using fake names, regardless of Twitter or Facebook. But at least we've got Akismet to provide some level of spam protection. I think remembering the user's info in a cookie is a good idea either way.
-
Thanks guys, this is good to know. I will definitely plan to implement in FieldtypeComments. On a related point, any idea how we can automatically identify the users info if they are logged into Twitter or Facebook? Obviously we won't be able to get their email, but perhaps we can get their Twitter/Facebook name and maybe gravatar hash automatically? I have no idea if it's possible, I really haven't played around with the APIs of these services at all. But seems like I've come across sites that were identifying me in this fashion (or I might have mistaken JS-based widgets originating from Twitter/Facebook).
-
Thanks Nico, that is nice and simple. I think we'd also need to cache the avatars locally for some period of time, to avoid DOS'ing the gravatar servers. One page with a dozen comments would fire of a dozen requests to gravatar.com. Maybe that's okay? Are you aware of any rules or best practices in this regard?
-
Glad they were able to turn off safe_mode for you there, and that all is working now. However, I think there is something more than just safe_mode at play here, because it really shouldn't be preventing PW from creating its assets folders. Having the install script create the assets folder doesn't help us here because then that would just throw the question back to the previous directory. If we can't create /site/assets/files/ then it's reasonable to assume we also can't create /site/assets/ ... all the way back to the web root. And ProcessWire can't create the web root. I'm guessing Apache was running under something other than your account, and the fix under safe mode would have been to change the /assets/ directory ownership to whatever user Apache was running as. But I can't say for certain. Just glad you convenced them to turn off safe_mode, as I think they are a lot better off now.
-
Autocomplete and Other Search Enhancements
ryan replied to Michael Murphy's topic in Getting Started
This inputfield uses the ProcessPageSearch AJAX API, which is accessible to logged-in users only that have administrative access. Meaning, it can't be used on the front-end of a site, unless for an administrative user. However, this Inputfield is mainly just a front-end to the jQuery UI autocomplete, with some tweaks to make it consistent with PW's admin style and offer some configurable options. So one could very easily implement the same sort of functionality on the front-end of a site by creating a page with it's own template to handle the ajax calls, translate them to a $pages->find() operation, and return the matches. It doesn't need to do any more than this: /site/templates/search.php <?php $resultsArray = array(); if($input->get->q) { $q = $sanitizer->selectorValue($input->get->q); $results = $pages->find("title*=$q, limit=50"); foreach($results as $p) $resultsArray[$p->id] = $p->title; } echo json_encode($resultsArray); From there, the rest is just jQuery UI autocomplete: http://jqueryui.com/demos/autocomplete/#multiple-remote -
Good feedback, thanks Nico. The comments module is kind of weak right now, so it needs some attention very soon. The long-term plan for the 'Comments fieldtype improvements' is to convert the comments system over to use pages instead. The goal with converting them to pages will be to make them really accessible and searchable from the API standpoint. It'll also mean that you'll have a 'comment' template that you can add whatever fields you want to. However, we'll likely make improvements to the existing Comments fieldtype before this. In fact, I've already built a new ProcessComments module that adds a 'Comments' option to your admin top nav, and lets you manage comments separately from pages... just haven't committed it to the core source yet. I will take your suggestion to add a website field and keep track of the email/website in the user's session. Some of this is at the discretion of how you utilize it. I recommend doing your comments output generation and processing before you send any output. When a comment is added, make your page redirect back to itself to both prevent reload-duplicates and start with fresh DB-loaded data. This also ensures that the user will see their comment rather than a "thanks" message (great if you aren't using a moderation queue). This is not already in place. I thought I saw this on your stadtpirat site? Do you know how to do it? I'll add it if you tell me how....