Jump to content

Jan Romero

Members
  • Posts

    680
  • Joined

  • Last visited

  • Days Won

    18

Everything posted by Jan Romero

  1. Can you not just load the page and access the repeater items from there? Not sure if there is a way to do this with a $pages->find() selector, seems like it would be useful though.
  2. Have you considered using the custom user template and parent feature? That way you wouldn’t need to link the profile page to a user. You could just put user pages in the appropriate place in the page tree ans use those as profiles.
  3. Are you talking about ethicalby.design? Because there the form’s action points to "./" regardless of the page you’re on, so if you only process the form submission on the home page, it should always be directed there, i. e. "/".
  4. How to add a new method with a hook. So if you take your that code from Pagefiles->findTag(): /** * Return all Pagefile objects that do NOT have the given tag(s). * * Given tag may be any of the following: * * - `foo` (single tag): Will return all Pagefile objects not having the specified tag. * - `foo|bar|baz` (multiple OR tags): Will return Pagefile objects having not having ANY of the tags listed. * - `foo,bar,baz` (multiple AND tags): Will return Pagefile objects having NONE of the tags listed. * - `['foo','bar','baz']` (multiple AND tags array): Same as above but can be specified as an array. * * @param string|array $tag * @return Pagefiles New Pagefiles array with items that didn't match the given tag(s). * @see Pagefiles::getTag(), Pagefile::hasTag(), Pagefile::tags() * */ wire()->addHook('Pagefiles::excludeTag', function (HookEvent $event) { $pagefiles = $event->object; //the Pagefiles object. For every instance of $this from the original code we will use $pagefiles instead. $tag = $event->arguments(0); //the argument passed to the method. so it will be e.g. $images->excludeTag($tag) $items = $pagefiles->makeNew(); foreach($pagefiles as $pagefile) { if(!$pagefile->hasTag($tag)) //the only real change is introducing this exclamation mark to negate the condition $items->add($pagefile); } $event->return = $items; }); Now because we just negate the result of $pagefile->hasTag(), we need to be aware of the inverted logic. If you pass multiple tags it should act the way I described in the comment above, which is just Ryan's comment inverted. So if you pass 'foo,bar,baz', you may still get images tagged as 'foo'. (i haven't tested any of this. i may have done it completely wrong.) Edit: Apologies, I did indeed do it wrong. Fixed the code above. @Andi
  5. The code says no. Arguably the function should use $options['allowSchemes'][0] if present, or something. I would suggest just replacing it: $url = substr_replace($url, 'https://', 0, 7);
  6. In a template $page is the current page that your visitor has requested and is being output for them. $pages gives you access to all pages in the system by calling methods like $pages->find() or $pages->get(). “Child” is only one child. When you call $page->child() it will give you the first child. If your page has multiple children, you may want all of them. That’s when you call $page->children(). If you want only some children, you can pass a selector to the method. See the docs herehttps://processwire.com/api/ref/page/child/ and here https://processwire.com/api/ref/page/children/. “Render” usually implies that the method generates markup aka HTML code for you. When you use get() you simply get the thing you asked for. It may be a Page object or the contents of some field or something else, depending on the context. ProcessWire has the concept of “Output Formatting”, which means that field values can sometimes also generate/contain markup themselves, without the word “render” showing up anywhere. So it’s not all that clear cut, but that’s the basic idea. ”Rendering“ means taking something that can’t be output to the browser directly and formatting it, usually as HTML. Sometimes ProcessWire makes its features available to you as properties AND as methods. This can be convenient but also confusing. You’ll have to consult the docs for each individual case, or just test out what works. If you want to pass arguments/options, you must use the function way. If you’re not familiar with the concepts of properties and methods/functions, perhaps familiarize yourself with PHP basics before reading the ProcessWire docs, or just read the PHP docs as you go along. Or ask in the forums here, PW has an exceptionally friendly community. Welcome to ProcessWire ? Edit: To answer your actual question, you cannot do $page->children->image->url, because children is a PageArray. It's a way to collect multiple pages, in this case all the child pages of $page. So when you call children->image, it doesn't know which child page to take the image from. You could do $page->child->image->url. That would give you the image from the first child page. Be aware that there may be no children, or the first child may not have an image. These cases may need to be considered as your website grows.
  7. Indeed, that’s because the the message is set before the admin controller actually runs and saves the the change. Basically, every page in the admin backend executes a specific “Process”. You can hook into the base Process class to add your message only after a process has been executed: $this->addHookAfter('Process::execute', function($event) { if ($this->wire('user')->isLoggedin() && $this->wire('config')->myCrazySetting) $this->message("Hope you know what you’re doing with that setting!"); }); This can be put in the same file, above the controller line.
  8. You could just put it into templates/admin.php. The file should already be there. Here is the entire default file plus a line for the notice: <?php namespace ProcessWire; /** * Admin template just loads the admin application controller, * and admin is just an application built on top of ProcessWire. * * This demonstrates how you can use ProcessWire as a front-end * to another application. * * Feel free to hook admin-specific functionality from this file, * but remember to leave the require() statement below at the end. * */ if ($user->isLoggedin() && $myCrazySetting) $this->message("This is the notice text"); require($config->paths->adminTemplates . 'controller.php');
  9. This is what it should look like on page 4, I assume? I’m not sure this will be possible with a single call to renderPager(). MAYBE you’ll be better off just rolling the pagination markup yourself. For example you could do this: $totalPages = ceil($posts->getTotal() / $posts->getLimit()); for ($i = $input->pageNum+1; $i <= $totalPages; $i++) { echo "<li><a href='{$page->url}{$input->urlSegmentString}/page{$i}'>{$i}</a></li>"; } for ($i = 1; $i <= $input->pageNum; $i++) { echo "<li><a href='{$page->url}{$input->urlSegmentString}/page{$i}'>{$i}</a></li>"; } Mostly you’ll need to look out for the href attribute, i.e. my code throws away any GET variables and uses the default pagination prefix “page”. Also you don’t get any of the niceties ProcessWire gives you by default. If you rely on those, maybe use renderPager() and rearrange the generated Markup. Both options are pretty hackish. You’ll have to choose which one is the least pain in the butt for your system…
  10. Btw, if you’re going to do $page->references()->count(), you will be better off telling references() that you just need the cound directly. In the end, these methods and properties all end up in FieldtypePage and provide some efficiency tricks like this. However, this will always query the database for every page in your array and every page field in your system, so if you want to get real gainz, you're probably best off just asking the database for your pages and the count somewhat like this: $query = wire('database')->prepare('select data, count(paged_id) from field_yourpagefield group by data'); $query->execute(); $results = $query->fetchAll(\PDO::FETCH_KEY_PAIR); $brands = wire('pages')->getById(array_keys($results), ['template' => wire('templates')->get('brand') , 'findTemplates' => false , 'getNumChildren' => false , 'joinSortfield' => false]); echo $brands->each(function ($brand) { return '<li>' . $brand->title . ' was referenced ' . $results[$brand->id] . ' times.'; }); At least that is what I was going to write reflexively before checking the core for something ready-made. That's the amazing thing about ProcessWire, that something like this just already exists and makes everything super easy.
  11. It’s actually really easy: $brands = $pages->find('template=brand'); echo $brands->sort('-numReferences')->each("<li>{title}: {numReferences}"); Whether it’s very efficient is a different story. I wouldn’t know. Be aware that you have to sort the PageArray. Putting it in the find() selector won’t work. Edit: actually, you probably want hasReferences, as per the documentation: $numReferences Total number of pages referencing this page with Page reference fields. $hasReferences Number of visible pages (to current user) referencing this page with page reference fields.
  12. To take the last element of a WireArray and put it at the beginning, you can do this: $products->prepend($products->pop()); To get only pages after the current product, you can do this: $products = $pages->find("sort>{$page->sort}") Maybe post some of your code?
  13. Your code as well as eelkenet’s should work if you set output formatting to false at the top instead of at the bottom. AFAIK, without output formatting, File fields always return a WireArray, or rather, a Pagefiles array, which inherits from WireArray. In general the reason you disable output formatting is that you can work with the “raw” data before saving. Changing the formatted data and then only disabling output formatting before the save() should be pointless and/or introduce errors. For example, if you have a field with Markdown formatting and you modify its contents without disabling output formatting, you’re modifying and saving the rendered HTML, destroying your original Markdown markup.
  14. An easier way to set the status code: http_response_code(303); Available since PHP 5.4.
  15. @Robin S Thanks for confirming that! I submitted an issue and a PR I’m not too sure about. https://github.com/processwire/processwire-issues/issues/1143
  16. But ProcessWire’s WireShutdown class considers everything hitting it with X-Requested-With: XMLHttpRequest to be CLI use. The way I see it, from a security perspective that makes the differentiation between public and detailed error messages completely useless: if you’re shown the public error, you can just resend the request with the header and any PW installation will gladly tell all. It kinda didn’t occur to me to even look through the source, because I figured something like this would have a prominent setting somewhere, but now I think it just might be a bug? WireShutdown does this: $useHTML = isset($_SERVER['HTTP_HOST']); // is this an HTTP request where we can output HTML? […] // use text-only output if an http request that is ajax if($useHTML && $config->ajax) $useHTML = false; […] if($config->debug) { $why = $this->labels['debug-mode'] . " (\$config->debug = true; => /site/config.php)."; } else if(!$useHTML) { $why = $this->labels['cli-mode']; } […] if($why) { $why = $this->labels['shown-because'] . " $why $who"; $message = $this->amendErrorMessage($message); $this->sendErrorMessage($message, $why, $useHTML); } else { $this->sendFatalError($who, $useHTML); } So for this purpose, sending two headers in your request is essentially equivalent to the site being in debug mode. That can’t be right?
  17. In case anyone else hates it when websites do that, set these to false in Firefox about:config: layout.css.scrollbar-color.enabled layout.css.scrollbar-width.enabled And perhaps this one to true: widget.disable-dark-scrollbar
  18. Hi. This is kind of a dumb question, but I’ve been searching for days and couldn’t find an answer. I’m using an XMLHttpRequest to fetch some JSON from a page. This works as expected as long as I don’t send the header X-Requested-With: XMLHttpRequest. With the header, ProcessWire decides that I’m using the command line API and if something goes wrong, it shows detailed error messages to guest users (“This error message was shown because: you are using the command line API”). I appreciate that when debugging, but it would be nice if I could limit it to just superusers. Is there a setting for this? Thanks
  19. Tbh, I find this whole “virtual field” business somewhat unfortunate… The announcement of custom image fields filled me with joy, and I thought the idea of using templates seemed pretty ingenious (although I don’t like how it introduces magic strings into template names, and generally restricts their naming, and doesn’t allow multiple image fields to share a template. Feels icky to me. Why not have a template selector in the field settings?). However, I was disappointed to find that values are just serialized and dumped into the image-field table. Seems like this data is treated as some kind of second-class citizen. If the custom fields were stored in their own database columns, as suggested by using templates and fields, it would have been a trivial INSERT to migrate from the ImageExtra module. Now I needed to use the PW API to move values from one field to the next, which involves all kinds of voodoo behind the scenes. Wouldn’t it be much less work to just store a page reference with each image and have the custom image fields stored in their respective field-tables? Surely that way it would be easier to make everything play nicely with selectors and everything? Of course, I have to admit I don’t have a lot of MySQL experience. Maybe there are easy and performant and reliable ways to query serialized fields like this and I just need to read up a little ?
  20. @webhoes yeah, your javascript wants to put the search results into the element #content, and you don’t have one. If you add id="content" to your container div, it works. The search is doing something weird though. It will only find whole words, so if I look for guitars, the “g” gives me “Marshall MG 10 G Combo”, then everything disappears until I finish “guitar”.
  21. In accordance with the gist identified by Kongondo, I’ll comment that I figure most of the complexity will probably lie in your envisioned front-end. I’m certain that PW will work just fine as far as it is concerned, but it won’t help you any displaying a zoomable map and all that. This is an ambitious project if you’re really going to involve native mobile apps and payment processing. I would probably suggest keeping it simple for now, and just worry about getting your data from the user to your database and back. Working with data and users is pretty much a breeze with PW. While there may be more suitable products for your particular use case (you’d have to ask someone more broadly versed), I wouldn’t worry about the ProcessWire side of things too much. It’ll probably the part you’ll need the least help with. My tip would be to look into front-end people if you really are looking to hire. I should mention that my personal MO online is Hemingway-inspired, i.e. post drunk, browse sober, and right now I’m, like, really posting.
  22. Indeed. I just upgraded an old site from 2.7.2, *cough*, and MySQL complained about some query on the edit page. Turns out this module failed to get the name of the path history table, and then it just goes “from where pages_id”. The problem appears to be that it uses constant() to get PagePathHistory::dbTableName, but that has long since moved into the namespace ProcessWire. It seems to work fine once you remove line 74 here and replace it with: $this->dbTableName = $this->wire('modules')->getModule($moduleName)::dbTableName; At least, that’s the quickest fix. Sorry for unearthing this old thread…
  23. I don’t know your site, but wouldn’t you want to count only the siblings whose templates are also in $preventTpls?
  24. Well, uh, FWIW I’ve encountered a problem today that may or may not be similar. My backend sessions were working as fine as ever, but users on the frontend would get logged out immediately after logging in. Basically, they would get their welcome page but their next request would fail. After disabling Session Handler Database sessions would persist nicely. Now when I saw you mention the Multilanguage setup, I had a look at my prepend file, where for some reason I can’t really remember I had put this: $session->language = $user->language; I’m sure once upon a time this fixed something about Language settings getting lost in between requests or something, but apparently it doesn’t play nice with the Session Handler Database module. So after removing that line everything is back to normal, DB sessions enabled and all. I have no idea about the mechanics behind the effects I’m observing here, unfortunately, but I thought I’d throw it out there, I guess.
  25. Actually, I just experienced this “problem” where I’m saving an image field using $page->save('images') and even in non-quiet mode it didn’t invalidate the one-week template cache. That’s on a 2.7.2 installation. So the answer to your question seems to be Yes, it does prevent the cache from being cleared. I’m putting “problem” in quotes because I don’t really care one way or the other in this particular instance, but my user got confused (as always with caching).
×
×
  • Create New...