-
Posts
664 -
Joined
-
Last visited
-
Days Won
18
Community Answers
-
Jan Romero's post in Moving pages in tree: A bug or a feature? was marked as the answer
I agree it's not optimal either, but the best way to do this is to click on "Jo" to highlight it before dragging "Dateityp" under it. Think of it as expanding the tree below "Jo". Even though it has no children yet, you have to "open" them before you can put one in. It makes a lot of sense but I agree it's not the most intuitive experience. With Ryan adding long-click actions now, I think this would be a use case worth considering. I. e., dragging and holding a page on top of another page for one second could make it expand.
-
Jan Romero's post in Load page via AJAX and redirect to parent was marked as the answer
Existing pages always take precedence over urlSegments. You have several options:
Use urlSegments that don’t exist as children of /site/teachers/, for example by adding a string, or by using 2 urlSegments. E.g. /site/teachers/selection/teacher1/. Use GET parameters instead: /site/teachers/?teacher=teacher1. You could either process the parameter with PHP or catch it with JavaScript and use your existing AJAX solution. Which would probably be the simplest option. Just add one or two lines of JS. Or, if you don't want the actual page under /site/teachers/teacher1/ to be reachable at all, just display /site/teachers/ in that template. Example below: template of /site/teachers/teacher1/:
$options['teacher'] = $page; //pass the teacher to the parent page using options array echo $page->parent->render($options); //render the parent page (/site/teachers/) template of /site/teachers/:
if(isset($options['teacher'] && $options['teacher'] instanceof Page) { $aside_teacher = $options['teacher']; } //Now render the page as you normally would, and you can use $aside_teacher to put its contents where you need them This also has the added bonus that you can use standard page caching for the child pages.
-
Jan Romero's post in Button on dashboard that creates new page with a specific template was marked as the answer
You can set a default template by supplying the GET parameter “template_id”, or the POST parameter “template”:
http://example.com/processwire/page/add/?parent_id=1024&template_id=46 I’m not sure about forcing the template. You could probably specify a default name format in order to bypass the page-add screen directly, or hook into ProcessPageAdd to manipulate the form.
-
Jan Romero's post in sorting pages with exception was marked as the answer
Hi ngrmm,
the value of a checkbox is 0 for unchecked and 1 for checked, so to have checked pages at the top, you have to sort in descending order. Simply prepend a - to the field:
$articles = $pages->find('template=x|y, sort=-highlight, sort=creation'); -
Jan Romero's post in Frontend filtering people advice was marked as the answer
You can build your selector string like any normal string before you pass it to the find function. If a field has been left empty, you can simply not include it in the selector.
$selector = "template=user, roles={$role}, include=all"; //fixed part of the selector that is always used if ($input->post('country')) { //sanitize etc. $selector .= ", country={$inputcountry}"; } //repeat for other inputs -
Jan Romero's post in Small performance question was marked as the answer
Might be faster to just do a simple for loop from 2010 (depending on how far back your archive goes) to 2100 (or, say, the current year) and just check the page count for each year. That way you’re not loading any pages at all, and you don’t have to do any date magic. It would also probably result in shorter code.
for ($i = 2010; $i <= date('Y'); $i++) { $c = $pages->count("template=artikel, publish_from>={$i}, publish_from<" . ($i+1)); if ($c > 0) $out += "<a href='/{$i}'>{$i}</a>"; } Maybe even throw limit=1 into the selector, or display the count for free.
-
Jan Romero's post in 404 Error behavior for index.php/foo (Soft 404) was marked as the answer
Jumplinks can handle this. I’ve had the same problem recently. I do also think ProcessWire should 404 these kinds of URLs, though.
-
Jan Romero's post in How to learn syntax, specifically $page was marked as the answer
Hi Jonah, welcome to the PW community!
Your issues mostly seem to pertain to PHP, not ProcessWire specifically. To answer #3, you are correct in that there is no special ProcessWire syntax. In the code you show, there is nothing really “PW-specific”. What ProcessWire does here is provide you with variables you can use in your template, namely $page to access data related to the requested page. The PW-specific knowledge you need is not of syntax, but of those variables, their classes and their methods. In the example, you need to know what kind of object the field image_details is, so you can know to access it with foreach.
In #1, be aware of PHP’s assignment and equality operators! In your if condition, you want to compare values, so you must use == or ===, but never =! You should also wrap the conditional blocks in {curly brackets}. It is not necessary if you only need one statement, but good practice if you ever need to add some more.
Since it is a PHP question, I’ll let StackOverflow explain the difference between 'single' and "double" quotes: http://stackoverflow.com/questions/3446216/what-is-the-difference-between-single-quoted-and-double-quoted-strings-in-php
Basically, it doesn’t really matter, but double quotes give you more functionality.
I assume #2 is related to #1 in that you have overwritten $page->title with the string "home", because you used the assignment operator = instead of comparing with ==.
-
Jan Romero's post in Save new page as first of the children list with manual drag 'n drop sorting was marked as the answer
It is thanks to Horst.
http://modules.processwire.com/modules/page-tree-add-new-childs-reverse/
-
Jan Romero's post in [HannaCode] (PW+ZF5) no header image was marked as the answer
You need to echo the html markup within your outer php tags as strings. Or you can probably just get rid of the outer php tags.
<?php
echo '<div class="row fullWidth img">';
echo ' <img src="' . $config->urls->templates . 'img/header.jpg" alt="header-picture">';
echo '</div>';
?>
<!-- OR simply: -->
?> //just a closing tag here
<div class="row fullWidth img">
<img src="<?php echo $config->urls->templates; ?>img/header.jpg" alt="header-picture">
</div>
-
Jan Romero's post in How could I assign specific admin page for user role? was marked as the answer
If you have created your own ProcessModule for this, you can add the “permission” property to its module info. Only users with the set permission will load the module. The admin page will be hidden for everyone else.
You can also set up your module so that it creates the permission on installation, and automatically removes it when it is uninstalled.
-
Jan Romero's post in AJAX and JSONP to do cross-domain calls with ProcessWire? was marked as the answer
$config->ajax uses $_SERVER['HTTP_X_REQUESTED_WITH'], which isn’t sent with JSONP requests. You can just check for $input->get->callback on the server side to determine if it’s a JSONP request. -
Jan Romero's post in PageTable: Buttons above the pages was marked as the answer
Indeed. Without really looking into it, the Javascript must depend on the position of the buttons. Try this to insert the buttons inside .InputfieldPageTableContainer:
public function PageTableRender($event) { $return = $event->return; $from = strpos($return, "<div class='InputfieldPageTableButtons"); $to = strpos($return, "</button></span></div>", $from); $buttons = substr($return, $from, $to-$from) . "</button></span></div>"; $insertAt = strpos($return, "<table class='AdminDataTable AdminDataList'>"); $event->return = substr_replace($return, $buttons, $insertAt, 0); } Instead of this hackish string trickery, perhaps a better way to clone/move the buttons would be to use Javascript in the first place. I’m not sure how to best pull that off. Just append a script tag to $event->return?
-
Jan Romero's post in How to use find() on child-array? was marked as the answer
Interesting approach to tagging
You’re trying to specify the parent by name, but I’m pretty sure ProcessWire would much rather have a page ID or a path (meaning, wrapped with forward slashes).
Because PW can tell “genre” is not numeric (so not an ID), it treats it like a path, as if the slashes were there, but there are no tags under “/genre/”. They’re under “/tags/genre/”. So try that and it should work. Alternatively, specify that you’re selecting by name:
$genres = $track->tags->find("parent.name=genre"); I can see how this can seem confusing, because when if you were looking for a direct child of the homepage, it would work. In that case, the path is the same as the name with slashes.
Because you’re not really selecting “dynamic” pages here, but rather pages that are a fixed part of your site’s structure, you might want to use IDs instead. That way, if you later want to change a page name/path, you can do it comfortably in the admin, and don’t have to go around fixing your selectors.
-
Jan Romero's post in 404 Page was marked as the answer
Check out the folder called “errors” in your template directory. You’ll find 500.html and a readme.txt. This html file will be displayed when a fatal error occurs, and you can customize it.
To manually cause the 404 page to show, you can throw this exception in your template code:
throw new Wire404Exception(); However, it sounds like this recipe might suit your needs better than a 404 error page: First child redirect on ProcessWire Recipes. It’s just a single line:
if($page->numChildren) $session->redirect($page->child()->url); die(); -
Jan Romero's post in incorrect echo still works was marked as the answer
This is a feature of PHP. String literals with double quotes (") will evaluate the variables within. For clarity, you could also enclose the variable in curly brackets ({}) like so:
echo "You must be the pride of {$subject_hometown}!"; Only if you use single quotes (') the string will be parsed as-is, and you must use concatenation or other string operations to change it. Note that this means that within single quotes, escape sequences will not work either, so you can’t do the following, even though there are no variables in there:
echo '\r'; ----
Added by Nico:
More infos: http://stackoverflow.com/questions/10512452/php-using-a-variable-inside-a-double-quotes (and I marked it as solved)
-
Jan Romero's post in "Profile not saved" problem was marked as the answer
Does your problem persist after removing the dependency, logging out and back in again? If I do that, the error is gone. It seems that the error just doesn’t get cleared properly.
To fix this right now, you can hack the core. Open the file wire/modules/Process/ProcessProfile/ProcessProfile.module and change the following line:
if(count($form->getErrors())) { To this:
if(count($form->getErrors(true))) { The argument clears the errors that occurred during form validation. It should be safe. The errors are not used anywhere else as far as I can tell.
Instead of hacking the core directly, it’s probably better to use the new multiple-modules feature. Funnily enough, Ryan uses the exact same file as an example in his blog post.
-
Jan Romero's post in External url rewrited was marked as the answer
If you compare the link on your site with the example you posted in the OP, you will see the problem. It’s missing the scheme part http://. If you add that it should work.
-
Jan Romero's post in How to increment file download counter? was marked as the answer
Because of the $, $download_counter is a variable here. You’re not accessing the page field “download_counter”, but a field by the name of whatever that variable contains.
You should also disable output formatting before modifying a field. Use $page->setOutputFormatting(false) or $page->of(false).
Lastly, it’s possible to save just the field by calling $page->save('download_counter').
Untested:
wireSendFile($page->download_file_link); $page->of(false); $page->download_counter = $page->download_counter + 1; $page->save('download_counter'); $page->of(true); -
Jan Romero's post in Best practice for displaying content with ajax was marked as the answer
I assume you have a special template for /functions/ and you have set up your config.php to auto-append _main.php. You can exclude templates from auto-appending and auto-prepending in the “files” tab of the template settings. If auto-append is active, there will be a checkbox called “Disable automatic append of file: _main.php”.
Regardless, it’s always a good idea to die() as soon as possible. In your case, I would advocate putting a die() at the end of each if ($command ...) block, unless there’s something you need to do afterwards. Probably a good idea to use a switch, too, then.
-
Jan Romero's post in Sort with select dropdown was marked as the answer
Your code looks very mixed up.
We’ll assume that we’re working on the parent page of Bassisten, Fluitisten, and Trombonisten. Thus, those three pages are in $page->children. We’ll refer to them as $categories. Each category has a number of artists as its children (grandchildren of $page).
Each category should have one <ul> element containing the artists. We’ll call an artist page $muzikant and create an <li> element.
First of all, let’s get the categories. Create a $categories variable and fill it with the children of $page.
$categories = $page->children(); Now loop over these categories and create a <ul> for each one.
foreach($categories as $category) { echo "<h3>$category->title</h3>"; echo '<ul>'; echo '</ul>'; } Inside the foreach we now have the variable $category, which refers to a single category. Let’s get its children and call them $muzikanten. Then loop over $muzikanten the same way and echo <li>s. Our complete code now looks like this:
$categories = $page->children(); foreach($categories as $category) { echo "<h3>$category->title</h3>"; echo '<ul>'; $muzikanten = $category->children(); foreach($muzikanten as $muzikant) { echo "<li>$muzikant->title</li>"; } echo '</ul>'; } This should just give us all the categories and all the artists in whatever order they come in.
To get only one specific category, we need a selector. If you’re unfamiliar with selector strings, take a quick look at the docs. We’re going to use the "sort=" selector to order our $muzikanten, and the "name=" selector to filter the $categories.
For example, to get only Bassisten, the selector would be "name=bassisten" (provided that’s the actual name of the page).
Let’s put that between the parentheses of $page->children():
$categories = $page->children("name=bassisten"); Now the page shows only Bassisten, but there’s still no order (probably). To sort, we have to know by which field to sort. We’ll use the title field. The selector for that is "sort=title". To sort Z-A instead of A-Z, it would be "sort=-title", with a minus/hyphen symbol.
So we have:
$categories = $page->children("name=bassisten"); foreach($categories as $category) { echo "<h3>$category->title</h3>"; echo '<ul>'; $muzikanten = $category->children("sort=title"); foreach($muzikanten as $muzikant) { echo "<li>$muzikant->title</li>"; } echo '</ul>'; } The next step would be to use $input->get to determine what goes into our selectors. Let’s assume our address should look like this at the end:
?selectedcategory=bassisten&sortby=-title (You will want to do this differently in reality, but let’s roll with it for now)
As soon as you add that part to the address in your browser, $input->get will have two new properties: selectedcategory and sortby. Store them in some variables.
$selectedCategory = $input->get->selectedcategory; $sortby = $input->get->sortby; Now we can use these variables inside our selector strings. Our finished code:
$selectedCategory = $input->get->selectedcategory; $sortby = $input->get->sortby; $categories = $page->children("name=$selectedCategory"); foreach($categories as $category) { echo "<h3>$category->title</h3>"; echo '<ul>'; $muzikanten = $category->children("sort=$sortby"); foreach($muzikanten as $muzikant) { echo "<li>$muzikant->title</li>"; } echo '</ul>'; } -
Jan Romero's post in page selector offset was marked as the answer
There is start?
$posts = $pages->find('template=news, sort=-created, start=80, limit=40');
-
Jan Romero's post in check roles when outputting menu was marked as the answer
Because you want a user to see a menu item if they have one or more, i. e. any of that item’s roles, you want to break out of your foreach as soon as the first matching role is found. Otherwise, any missing role will set $menuVis to false. That would be a good idea if you wanted a user to require all of the item’s roles, in which case you would have to break out of the loop at the first missing role, lest any further iteration sets $menuVis to true again.
if($child->menu_roles->count()) { $menuVis = false; //Assume false in case the foreach doesn't find any matching roles and sets it true foreach($child->menu_roles as $cmr) { $cmrRole = wire('roles')->get("$cmr->name"); if (wire("user")->hasRole("$cmrRole")) { $menuVis = true; //has this role, so no need to check more roles break; } } } if($menuVis == false) continue; -
Jan Romero's post in My site was working fine, but now Admin takes for ever to load. debug=on, what next? was marked as the answer
Well, as you can tell from the warnings, it seems like PHP’s safe mode is preventing the HTMLPurifier from accessing the file system. More info on Safe Mode: http://php.net/manual/en/ini.sect.safe-mode.php
Since you haven’t changed anything, you should probably talk to your hosting provider about this. Maybe they changed the PHP settings? Seems odd that they would enable safe mode, since the docs already call it deprecated and “architecturally incorrect”. http://php.net/manual/en/features.safe-mode.php
-
Jan Romero's post in Search pages for value contained in a pages field? was marked as the answer
It depends on what you have. If you have the specialty as a string, you can select for the page’s title field like so:
$pages->find('template=physician, specialty.title={$search}'); If you know the specialty’s page-id or path, that should work as well. For example on a specialty page, you would want to list all physicians that have that specialty:
$pages->find('template=physician, specialty={$page->id}');