-
Posts
16,793 -
Joined
-
Last visited
-
Days Won
1,540
Everything posted by ryan
-
It seems okay to me. I would double check that you aren't getting any errors by enabling debug mode. But if it works, I can't currently think of any problems with doing it.
-
Okay I think I've got a better idea of what you are seeing now. But it still looks like the request "http://mywebsite.com/en/sitemap.xml/" has a trailing slash. Though I'm guessing that's actually the second redirect and that the LanguageSupportPageNames module is issuing them. LanguageSupportPageNames is actually not meant to work with the trailing slashes turned off (yet). So in your case, I would go ahead and enable trailing slashes for your sitemap-xml template and try again. Meanwhile, I'll work to get LanguageSupportPageNames compatible with trailing slashes.
-
I've yet to come across a host that doesn't have iconv support. This one comes with PHP and the only way to remove it is to specifically disable it when you compile PHP. Sometimes when dealing with smaller hosts (or those running their own server/VPS) they disable everything they don't recognize. Since iconv is part of PHP's core distribution, it's not something a host should disable unless they are only hosting a single site that they know doesn't need it. Most likely LiquidWeb does have it enabled, but the VPS owner compiled PHP without it. I think the best thing to do here is to ask them to enable it, along with any other PHP core features they may have disabled. Though since your installer didn't report anything else, iconv may be all you need. I don't think ProcessWire uses iconv() anywhere other than the pageName sanitizer, so if you don't want to wait on the host, you could always try modifying that line to an alternate solution.
-
[solved] moved Local-PW online: Error=Call to a member function hasRole()
ryan replied to horst's topic in General Support
Thanks Horst. I can't come up with any theories on why that particular error would occur, and have never seen it anywhere else. So if it's not holding you up, I think I may wait a bit to see if anyone else reports the same thing. -
Fieldtypes have a getInputfield() method that returns the Inputfield needed by that Fieldtype. So what Inputfield a Fieldtype uses is defined by the developer of the Fieldtype, not the user. Though the developer of the Fieldtype can decide that they might make that configurable to a limited set of other Inputfields that are known to be compatible. This is the case with the Page fieldtype, which is compatible with any Inputfield that is derived from InputfieldSelect. But that's kind of an exception, as the vast majority of Fieldtypes are married to a specific Inputfield.
-
Happy Birthday Roope! I personally don't like having arrays in GET variables (they are overly verbose and make ugly URLs). But if you want the MarkupPagerNav to keep arrays in their native GET variable state, you can tell it to by using the 'arrayToCSV' option and setting it to false. echo $mypages->renderPager(array('arrayToCSV' => false));
-
Why does $page->rootParent identify current section?
ryan replied to isellsoap's topic in Getting Started
I don't think parenthesis affect the logic here. I like to wrap ternary blocks in parenthesis just for readability, containing it to a visual open "(" and close ")" to the statement. But I don't think ternary operators and/or parenthesis aren't the issue here. The original issue is that the poster was comparing an object to an ID, which was probably failing. Later it was followed up with one where "==" are being used to compare two objects. That's not an ideal way to compare page objects because that double equals goes in and compares all the properties of both objects. If they are two different copies of the same page, it will fail. The best way to compare pages is to compare the ID (per my post above). Though if one literally wants to compare that two objects are the same instance then 3 equals "===" should be used, since that will compare the memory pointer (efficient) rather than every single variable in the object (not efficient). But I recommend comparing only the 'id' property, just on the off chance that you've got two different instances of the same page. It's also easy to remember, always works, and adds clarity that you are dealing with page objects.- 16 replies
-
- 1
-
- current section
- semantics
-
(and 2 more)
Tagged with:
-
Index template aspecific of 'sub' template? // Hello!
ryan replied to jtborger's topic in Getting Started
Beyond being a CMF/CMS, the goal of ProcessWire has also been to provide utility to PHP like jQuery does to Javascript. That means we accept PHP best practices as our best practices, rather than inventing proprietary, usually more complex and short lived alternates that do the same thing. It also means using very simple, yet tried and true PHP like functions and includes for code reuse rather than snippets, blocks, chunkers, snaggers, widgets, tagalongs, bangers or whatever concepts are being pushed out there. ProcessWire provides tons of structure when you want it to, and gets out of your way when you want it to as well. For me it means template files that rarely have much code in them (occasionally none), unless the output need is different from the rest of the site. Most of the site's markup gets generated either from a "main" output file, or from shared render functions. As a result, most template files tend to have limited or no markup and look like the example at the bottom of this post. It also means that I don't usually have more than 2-3 other PHP files, beyond the template files. See the template file structure section of this post for details on how I structure my template files–I've found this method to work best for me through several sites. The delegate approach and some of the others I've seen don't suit my needs as well, but seem to work very well for others. The Blog profile uses an MVC style approach that may appeal to those looking for lots of predefined structure, though I still prefer approaches that involve fewer files. For small stuff, the approach taken in the default profile (included with ProcessWire) is about as simple as it gets, even if it's not as elegant. But when it suits the need, I don't see any reason to shy away from it. Regardless of how you structure your site, the important thing is to aim for DRY (don't repeater yourself). home.php $body = renderSlideshow($page->features) . $page->body; $side = renderNews($pages->find("template=news, sort=-created, limit=5")); The example above uses the /site/config.php 'prependTemplateFile' and 'appendTemplateFile' options to include an _init.php (prepend) file that initializes variables like $body and $side with defaults, and a _main.php (append) file that outputs them in the predefined places within the context of an entire HTML file. The template files get executed in between those two and modify $body and $side as needed specific to the data and needs of the template and page. -
Sounds like something is getting paginated that you don't want paginated. Add a "start=0" to your children() selector, i.e. <?php foreach ($pages->get("/article")->children('sort=-created, start=0, limit=5') as $articles) { ?> See the "side effects" section in the pagination documentation.
-
Here's more information about how to use and implement module dependencies: http://processwire.com/talk/topic/778-module-dependencies/
-
I just posted version 5 of Hanna Code. The primary additions here are: Predefined (default) attribute values There is a new Attributes field present in the Hanna Code editor. From here you can define what attributes your PHP or Javascript Hanna Code expects. This can also be used to set default values for attributes. Use of this is optional. However, I think it's a good idea to use it as it helps communicate what the options are for a given Hanna Code. It also saves you some code as you can assume your attributes will be defined as variables, ready to access. The main listing page now shows Hanna Codes with their attributes so that they can be copied/pasted into your body text with all attribute options known and ready to fill in. Support for Export and Import of Hanna Codes Now you can export any Hanna code and import it somewhere else using copy/paste. You'll see the Export option when editing a Hanna Code. You'll see the Import option on the main listing page. Below is a predefined Hanna Code you can import if you'd like: Jumplinks Hanna Code (example for import) This Hanna code is meant to be used in your body copy. It collects all the headline tags in the text and turns them into anchor jump links while outputting a linked table of contents. It will put the table of contents wherever you type the Hanna code. See the anchor jump links on this page for an example of what this Hanna Code does. Import Data: !HannaCode:jumplinks:eyJuYW1lIjoianVtcGxpbmtzIiwidHlwZSI6IjIiLCJjb2RlIjoiXC8qaGNfYXR0clxuZm9yPVwiaDIgaDNcIlxuaGNfYXR0cipcL1xuJGZvciA9IHN0cl9yZXBsYWNlKCcsJywgJyAnLCAkZm9yKTtcclxuJGZvciA9IGV4cGxvZGUoJyAnLCAkZm9yKTtcclxuZm9yZWFjaCgkZm9yIGFzICRrID0+ICR2KSAkZm9yWyRrXSA9IHRyaW0oJHYpO1xyXG5cclxuJGZvciA9IGltcGxvZGUoJ3wnLCAkZm9yKTtcclxuJGFuY2hvcnMgPSBhcnJheSgpOyBcclxuJHZhbHVlID0gJGhhbm5hLT52YWx1ZTsgXHJcblxyXG5pZihwcmVnX21hdGNoX2FsbCgnezwoJyAuICRmb3IgLiAnKVtePl0qPiguKz8pPFwvXFwxPn1pJywgJHZhbHVlLCAkbWF0Y2hlcykpIHtcclxuICBmb3JlYWNoKCRtYXRjaGVzWzFdIGFzICRrZXkgPT4gJHRhZykge1xyXG4gICAgJHRleHQgPSAkbWF0Y2hlc1syXVska2V5XTtcclxuICAgICRhbmNob3IgPSAkc2FuaXRpemVyLT5wYWdlTmFtZSgkdGV4dCwgdHJ1ZSk7XHJcbiAgICAkYW5jaG9yc1skYW5jaG9yXSA9ICR0ZXh0OyBcclxuICAgICRmdWxsID0gJG1hdGNoZXNbMF1bJGtleV07IFxyXG4gICAgJHZhbHVlID0gc3RyX3JlcGxhY2UoJGZ1bGwsIFwiPGEgbmFtZT0nJGFuY2hvcicgaHJlZj0nIyc+PFwvYT4kZnVsbFwiLCAkdmFsdWUpOyBcclxuICB9ICBcclxuICAkaGFubmEtPnZhbHVlID0gJHZhbHVlOyBcclxufVxyXG5cclxuaWYoY291bnQoJGFuY2hvcnMpKSB7XHJcbiAgZWNobyBcIjx1bCBjbGFzcz0nanVtcGxpbmtzJz5cIjtcclxuICBmb3JlYWNoKCRhbmNob3JzIGFzICRhbmNob3IgPT4gJHRleHQpIHtcclxuICAgIGVjaG8gXCI8bGk+PGEgaHJlZj0nJHBhZ2UtPnVybCMkYW5jaG9yJz4kdGV4dDxcL2E+PFwvbGk+XCI7XHJcbiAgfVxyXG4gIGVjaG8gXCI8XC91bD5cIjtcclxufSBlbHNlIHtcclxuICBlY2hvICcnO1xyXG59In0=/!HannaCode Usage Examples: [[jumplinks]] Locates all h2 and h3 headlines, turns them into anchors, and generates a table of contents. This is the default behavior with no attributes. [[jumplinks for=h2]] Here we specify a 'for' attribute. It produces the same behavior as above except only anchors h2 headlines. [[jumplinks for=h2 h4]] Same as above except only anchors h2 and h4 headlines.
-
It's now hookable in the dev branch.
-
I think that this is for folks that prefer to copy/paste stuff. But for people that fully read and understand the docs, they can make their own examples, tips and tricks. They are the ones here having the most fun and responding to all the questions. Many assume the system to be much more complex than it actually is simply because they are giving more weight to tutorials and copy/paste snippets of code from the forum rather than the bigger picture that is emphasized by the docs. Though I know everyone learns differently. For me personally, I don't learn well from tutorials or snippets… even I get lost in most of the ProcessWire tutorials I've tried to follow. I need to know the big picture. And ProcessWire's big picture is really, really simple. Other systems are far more complex… I think an issue is that people aren't used to understanding the big picture because they assume a level of complexity that isn't there with ProcessWire. They want to know how to do this or that little thing, without considering that they really can know how to do everything. The closest path to knowing how to best develop in ProcessWire is to read the docs. The pre-requisites are knowing front-end development (HTML & CSS), and optionally a little PHP. Though even people that don't know any PHP can do more than they could with a template engine. But for people that do know a little PHP, anything is possible. If I recall, Diogo mentioned that he printed out all the pages in the /api/ section of the site, took them to a park, and read them in an hour or so. Despite not starting out as a coder, he came back here knowing how to do anything. He can literally answer any question because he knows the big picture. This is a good way to put it. My opinion is that even someone with no understanding of PHP will still be able to create more on their own with ProcessWire than they could in another system. But for those that really want to "drive fast" and see how far they can push it, they'll have a much stronger engine at their disposal than they might in another system. For those people, php.net becomes a valuable documentation resource too.
-
I recommend adjusting your MySQL fulltext minimum indexed word length. Search this forum for "ft_min_word_len". Phrases should work with %= but the phrase you are searching for would have to be identical to the words it matches. Meaning if you searched for "white tea", it would only match pages containing the phrase "white tea", and not pages that have the words "white" and "tea" separated. Another thing to mention is that your full query above included "path", which is not query-able since it is generated at runtime (not in the DB). You can make it query-able by installing the PagesPaths module included with the core, but I don't think it can be part of an OR "|" set of fields. I recommend removing "path" from your query logic, as chances are the path is based on the title anyway. It sounds to me like what you really want is the "~=" operator, which will match all the words regardless of where they appear in the copy. Given that, tweaking your MySQL fulltext minimum index size (ft_min_word_len) would be worthwhile. See more details about how the different operators work here: http://processwire.com/api/selectors/#operators
-
[solved] moved Local-PW online: Error=Call to a member function hasRole()
ryan replied to horst's topic in General Support
No problem Horst. Actually I hadn't started trying to work on this yet, but was going to yesterday afternoon. Then I got your message that it sounded like the issue was resolved, so I didn't look further. But just wanted to double check that the issue is resolved and you don't still need me to look at anything there? -
What version of ProcessWire are you using? 2.3 and newer (at least) should supporting sorting by multiple fields in WireArray / PageArray.
-
I originally missed the issue with language switchers not working on the 404 page because all the instances where I'm using language switchers, I was only have it show the language switcher if the page was not the 404 page. The reasoning there is just that in my case, there wasn't much point in being able to show different language versions of a 404 page. If your situation is similar, I recommend simply not showing the language switcher when on a 404 page. Though if you want the switcher to redirect back to the homepage, that seems like another decent approach. But here's what I did: if($page->id != $config->http404PageID){ // render the language switcher }
-
ProcessPageAdd::getAllowedTemplates() now hookable on the dev branch.
-
If you are telling it to render using a specific template file, and that file doesn't exist, than an exception would be the right behavior. If there's a possibility the template might not be there, you should check yourself before asking it to render. Example: $file = 'markup/layouts/package.php'; if(is_file(wire('config')->paths->templates . $file)) { echo $package->render($file, array('layout' => 'package')); }
-
There is no FieldtypeName, and FieldtypeText is only going to use InputfieldText (it's not configurable for this particular fieldtype). So what I'd recommend doing us using the 'pattern' property of the field (which is supported by FieldtypeText) to require a name format: $field_templates->pattern = '^[-_.a-z0-9]+$'; If you want it to accept spaces too, then add a space immediately after the 0-9.
-
I'm using the default theme, so not positive what method it's using to show you 'latest updates'. But assuming it's showing pages with the most recent 'modified' date, chances are that some module hook somewhere updated that page. Either that, or it's limiting them to a specific time and you fell in that time one time and not another. This may be a question for that theme's thread.
-
That's essentially what I posted above, though in a different context (module config rather than ProcessPageEdit). If you wanted one in ProcessPageEdit, you'd probably want to create a new Fieldtype for it. Actually, just checked and it looks like Hani already has.
-
labelFieldName is specific to InputfieldPage. It identifies the field that you want to use as the selectable label. Typically this would be 'title', but for something that doesn't have a title 'path' would be a good choice.
-
The biggest issue that I can see here is that you don't have page numbers enabled for your template. ProcessWire putting in the "page=2" is a signal of that. So before you do anything else, go and enable page numbers by editing your 'search' template–you'll see the option to enable page numbers on the URLs tab. When it comes to dealing with your 'vendor' field, I recommend whitelisting it to a string in whatever format you want to extract it. For instance, maybe you want to use commas as a separator rather than pipes. You can whitelist it like this: $input->whitelist('vendor', implode(',', $vendors)); // if vendors is an array $input->whitelist('vendor', str_replace('|', ',', $vendors)); // if vendors is a PageArray Though you could certainly stick with "|" pipes if you preferred. But what I don't want to see you do is bundle that right from $input->get->vendor into a selector without validating it first. So switching to another separator makes that intention a little more clear. For instance, your form processor might capture and sanitize the vendor variable like this: if($input->get->vendor) { if(is_array($input->get->vendor)) { // array from form submission $dirty = $input->get->vendor; } else { // convert from your CSV string to array $dirty = explode(',', $input->get->vendor); } $vendor = array(); foreach($dirty as $id) $vendor[] = (int) $id; // sanitize to INTs $vendor = implode('|', $vendor); // convert to 123|456|789 string, ready for selector } else { $vendor = ''; }
-
The way you do it is to first add a new integer field to your 'brand' template. Call it something like 'num_products'. You might choose to make it hidden, so that it doesn't appear in the editor (if you prefer that). Next edit your /site/templates/admin.php and add this above the include() line that's already there: $pages->addHook('saveReady', null, 'updateBrandQuantities'); function updateBrandQuantities($event) { $page = $event->arguments(0); if($page->template == 'brand') { // a 'brand' page is being saved $page->num_products = wire('pages')->count("template=product, brands=$page"); } else if($page->template == 'product' && $page->isChanged('brands')) { // a 'product' page is being saved and 'brands' changed foreach($page->brands as $brand) $brand->save(); } } The trick is that if you already have a populated site, then you have to establish the quantities for the first time by saving all the 'brand' pages. You could temporarily add this code to one of your site's template files and view the page to populate them. After that, remove the code as it would no longer be needed. foreach($pages->find("template=brand") as $brand) { $brand->save(); }