Jump to content

ryan

Administrators
  • Posts

    16,772
  • Joined

  • Last visited

  • Days Won

    1,530

Everything posted by ryan

  1. Good idea for sure. But not very easy to implement at this stage. Will keep it on my mind though in case a solution presents itself.
  2. Thanks for the follow-up here. Looks like you found a great way to handle this.
  3. Glad the answer turned up! I was really confused about this one. I'm surprised that any web hosts would be using a MySQL version with this issue. It seems like this would affect almost anything that uses MySQL.
  4. Don't worry about lack of time or resources - I personally use ProcessWire on all my client projects, so it's something I've been working on steadily for many years and will continue to. My business depends on it! Sometimes I get blocks of time where I can focus on it a lot, and other times I have to focus more on my client projects, but PW always moves forward because I use it almost all day every day. Though something I'd like to be able to do is less client work and more ProcessWire work. One thought that crossed my mind is to maintain another version called ProcessWire Pro (or something like that) that would basically be the same but include faster support by e-mail and several of my modules that I use in commercial projects. It might also include a separate support board geared for your clients, so they would also have a support resource should they ever need/want it. I was thinking something like this might appeal to the EE crowd that is looking for the guaranteed support and services beyond the typical open source project. The audience here would be the web designer/developer that does this for a living and wants something extra that they can't currently get from PW or other open source projects. But that in turn would help to open up more time for the project as a whole. Not everyone needs or wants this, but it might be nice to offer it for those that do.
  5. I'm not sure I understand. Can you post a screenshot of the output that you get?
  6. Jasper is right: it sounds like PHP/Apache doesn't have write access in your /site/assets/ dir.
  7. If you want your events index to list all the categories, you could just do thi: $categories = $pages->find("template=category, sort=name"); foreach($categories as $c) echo "<p><a href='{$c->url}'>{$c->title}</a></p>"; If you want to use URL segments to filter the listing of events by category, you could use URL segments with a URL structure like /events/category/cheese/. Then your events index could look for it like this: if($input->urlSegment1 == 'category' && $input->urlSegment2) { $name = $sanitizer->pageName($input->urlSegment2); $category = $pages->get("template=category, name=$name"); if($category->id) { $events = $pages->find("template=event, categories=$category"); foreach($events as $event) echo "<p><a href='{$event->url}'>{$event->title}</a></p>"; } }
  8. If you need those things to be in separate fields and searchable that way in PW, then Repeater would definitely be a good way to go. Not sure about this one. I'm using Shopify, but it's not free/open source. Antti is working on a really nice cart setup for ProcessWire, so I'd probably look there first. Assuming these users are not admin/trusted users, I would keep them out of the admin and performing basic edits on the front-end only. Automating creation of fields is not something I recommend unless it's a one-time thing. It seems like things could get messy or out of hand if the creation of fields, or adding fields to templates, was not part of your manual administrative process. Definitely feel free to post any code. I'm somewhat confused on the questions, so code often helps to clarify.
  9. What I mean by "the order is retained" is that it was consistent with how I ordered it. I was able to re-sort everything without any unexpected results. I tried about a dozen times just to be sure. Since I can't reproduce it here, is it something I could login to there?
  10. I would suggest grabbing one randomly from each page: $entries = $pages->find("template=gallery_entry, sort=random, images.count>0, limit=6"); $images = array(); foreach($entries as $entry) { $images[] = $entry->images->getRandom(); } foreach($images as $image) { $img = $image->size(80,60); echo "<a href='/albums/'><img src='{$img->url}' alt='Latest photos' /></a>"; }
  11. You can access any of the $pages fields like: $mypage->title. If you want to render the entire page and echo it to the user, you can do this: echo $mypage->render();
  12. If I had to build a site like that, I would use ProcessWire. The only part that I think PW may not be the ideal fit is in giving all the restaurants admin access. Unlike something like Drupal, PW's admin isn't really intended for broad/community access, but rather for trusted individuals administering a site. But that's easy to get around by just coding the restaurant's tools on the front-end instead.
  13. The above will never resolve to false, so doesn't do anything. That's because find() returns a PageArray(). Think of it like a bottle that might have beer in it. An empty beer bottle is still a beer bottle. So you have to check if there's anything in it: $categories = $pages->find("template=category"); if(count($categories)) { // there are categories foreach($categories) { // output category } } I suggest using a separate 'category' template to handle the display of a given category (rather than trying to do it all in your 'categories' template). Here's the code you might do it with in your category template. This assumes the categorized entries have a field called "categories" $entries = $pages->find("categories=$page"); if(count($entries)) { echo "<ul>"; foreach($entries as $entry) { echo "<li><a href='{$entry->url}'>{$entry->title}</a></li>"; } echo "</ul>"; } else { echo "<p>No entries in this category.</p>"; }
  14. This has come up a few times, so thinking I should remove that limitation and make it so that you can still paginate with a limit=1. I'll look into this.
  15. I agree. I need to get one or two open source profiles available for download on the site before venturing into commercial profiles. But this is a very high priority, and I'm just trying to get enough time off work to do it. Hopefully he doesn't use Joomla for these things? If there's a real specific need, I'm usually inclined to use a tool dedicated to the task, regardless of what CMS you use. For instance we use IP.Board for the forum here and I use Shopify for a cart. However, with time there will be more dedicated options in PW for these things. Apeisa has already done a lot in this regard.
  16. You could also do this: $events = $page->siblings->remove($page)->slice(0,3); but this may be better: $events = $page->siblings("id!=$page, limit=3");
  17. Technically you don't have to, as PW already has already sanitized the URL segments. But I think it's a good habit to sanitize anything is considered user input (as a URL segment would be). So rather than having to remember what you do or don't have to sanitize, I suggest just maintaining the habit of sanitizing everything that comes from input. They are not cached. Too many possibilities with GET vars in order to maintain a cache. Of course, you can always maintain your own MarkupCache if you want to. In the template cache options, you'll also see there is an option to make it bypass the cache when certain GET or POST vars are present. Sorry, my mistake. I think that the first part of the expression needs to have parenthesis: if(($value = $sanitizer->name($input->get->type)) && in_array($value, $allowedTypes)) $input->whitelist('type', $value);
  18. You don't need to create a new template for that unless you want to. It uses the default admin template, and the login form is created by the ProcessLogin module. The best place to modify it is probably in your admin theme's custom stylesheet. It's also possible to create a login form anywhere on your site (like on the front-end) and just use the $session API functions to authenticate the user. But if your intention is to create an admin theme, then it's best to let the existing one stay and customize it from the stylesheet.
  19. Just got a chance to test this here. Unfortunately I can't seem to reproduce it though. I tried drag-sorting child pages in both /tester/ and /promos/, but the order is retained regardless of what I try. I'm starting to wonder if we're looking in the wrong place. What web browser and version are you using?
  20. Thanks Landitus--got it. I'll take a look and let you know what I find.
  21. Not sure I totally understand the example, but maybe something like this would do it? $sql = <<< _SQL SELECT pages.id, ref_page.id, field_title.data FROM pages JOIN field_referenced_page AS ref_field ON ref_field.pages_id=pages.id JOIN pages AS ref_page ON ref_field.data=ref_page.id JOIN field_title ON ref_page.id=field_title.pages_id WHERE pages.parent_id={$page->parent->id} GROUP BY ref_page.id _SQL; $a = array(); $result = $db->query($sql); while($row = $result->fetch_row()) { list($id, $ref_id, $ref_title) = $row; $a[$ref_id] = $ref_title; } Written in the browser without data to test on, so it may not be in a working state, but something like this may provide the result you are looking for.
  22. If the users aren't administrative users, then it would be better to keep them on the front-end where you are in full control of any access control scenario. For instance, you could assign access just through a page reference field attached to the user. However, if they are administrative users, you can't currently restrict their access in the manner you've asked without creating a module to hook into the Page::editable and/or Page::viewable functions. This thread has a little more info about doing that, but let me know if I can expand on it:
  23. Not technically a supported feature at present, but I think you can get the result you want. You'd take a query like this: $pages->find("body*=something"); and convert it to this: $pages->find("body.data{$user->language}*=something"); That should return just the pages that match the current user's language, rather than including the default language.
  24. http_build_query is nice. You can also build them yourself if you want. I usually use PW's $input->whitelist() to store values after I've sanitized them. As an added bonus, PW's pagination/pager module knows to include any $input->whitelist() get vars in it's links. So you can have your GET vars persist through pagination. Here's an example where the GET vars get used in a $pages->find() query, and also use them in any links. $allowedTypes = array('item1', 'item3', 'item7'); $allowedSorts = array('title', 'date', '-title', '-date'); if($value = (int) $input->get->region) $input->whitelist('region', $value); if($value = $sanitizer->name($input->get->type) && in_array($value, $allowedTypes)) $input->whitelist('type', $value); if($value = $sanitizer->name($input->get->sort) && in_array($value, $allowedSorts)) $input->whitelist('sort', $value); $selector = "template=something, parent=456, "; $url = "./?"; foreach($input->whitelist as $key => $value) { $selector .= "$key=$value, "; $url = "$key=$value&"; } $url = rtrim($url, '&'); $selector = rtrim($selector, ", "); $results = $pages->find($selector); echo $results->render(); // link to another region but with all other vars the same $region = 123; if($input->whitelist->region) $url2 = str_replace("region={$input->whitelist->region}", "region=$region", $url); else $url2 = $url . "&region=$region"; echo "<a href='$url'>Region</a>";
  25. PW loads stuff on demand, so if you print_r $page, then that's going to trigger it to load a lot of stuff and perhaps even an infinite loop. It's best not to print_r or var_dump $page objects for this reason. A $page object is pretty light in it's default state. It gains weight based on the number of autojoin fields you have. Following that, all fields you access are loaded on demand and then become part of the page's data. To keep pages as lightweight as possible, you'd want to limit your autojoin fields to only those that you need for every instance of a $page (like the 'title' for example). While a $page is intended to be lightweight, it's obviously going to be heavier than just an ID. And by that logic you can store more IDs in memory than you could pages. Though it's rare that I would do so because an ID rarely provides much value on its own. But there are cases, and here's how you can do it. You can query any field_* table and expect that it will have a pages_id field. So if I wanted to find all pages that had the title 'Templates', I could do this: $ids = array(); $result = $db->query("SELECT pages_id FROM field_title WHERE data='Templates'"); while($row = $result->fetch_assoc()) { $ids[] = $row['pages_id']; } // ...if you later want to convert it to Page objects, there is a getById function: $matches = $pages->getById($ids); // returns a PageArray Note that getById function performs faster if it knows what template is used by the page. It is an optional param that can be specified like this: $pages->getById($ids, $template); Here's another scenario. Lets say that you want to do something like a $pages->find(), but get the IDs rather than the Page objects. Here's how you can do that: $finder = new PageFinder(); $query = new Selectors("title=Templates, template=basic-page, sort=-created"); $results = $finder->find($query); // $results is array $ids = array(); foreach($results as $result) { // each result includes: id, templates_id, parent_id and score (if rank sorting) echo "<li>Found Page ID $result[id] using template ID $result[templates_id]</li>'; } That's how you can use the PageFinder class, which isn't part of the public API, but may be useful in certain situations where you only need to interact with IDs. However, keep in mind that when you use this, you are bypassing PW's caching and such. So if you are using this to ultimately generate Page objects then you will likely lose performance by going this route. But if you have a use for thousands of page IDs and don't need to turn them into Page objects, this would be the way to go.
×
×
  • Create New...