Jump to content

Jan Romero

  • Content Count

  • Joined

  • Last visited

  • Days Won


Jan Romero last won the day on May 28

Jan Romero had the most liked content!

Community Reputation

439 Excellent

About Jan Romero

  • Rank
    Sr. Member

Profile Information

  • Gender
    Not Telling
  • Location

Recent Profile Visitors

13,828 profile views
  1. According to the docs repeaters are just PageArrays, so both first() (method) and first (property) should work. Looking at your code very hastily, I think you’re looking for this: echo $child->repeat_body->first->body; Does this line not work already? <li><a href='{$child->repeat_body->first()->url}' class='button'>Pokračovať</a></li>
  2. Indeed, sorry. For the record, selecting by grandparent would work like this: $products = $pages->find('parent.parent.path=/shop/products/');
  3. With your code you’re only getting the children of /shop/products/’s FIRST child. Is that what you expect? If you want all grandchildren of /shop/products/, you could do something like $products = $pages->find('parent.parent.path=/shop/products/'); (Sorry if that’s not 100%, I just got up lol)
  4. Please teach Mirja the difference between ´, ` and ’, or install Super Smartypants.
  5. Technically, the username isn’t needed at all. Unless it’s exposed to users, it might as well be the the same as numeric page ID. If the email address is sufficiently unique, that’s all you need to look up the User object like $users->find("email={$email}") and call $session->login() with it. That is to say, you can pass the username to $session->login() as a string, but you can also pass a User object. https://processwire.com/api/ref/session/login/
  6. I dunno, I also get annoyed when I lose my session. It doesn’t happen every couple of minutes, but sometimes it still happens from one day to the next, even though I set the lifetime to a year. If ignoring IP and user-agent changes is so insecure, how does this forum do it, or pretty much all big websites for that matter?
  7. I figure this could lead to a collision if there were someone with the e-mail jim@ex-ample.com and someone with the e-mail jim-ex@ample.com.
  8. If you must use these files it would probably be best to call the php file from a ProcessWire template. For instance the same template that outputs the form. You could change the form’s ACTION from “contactform-process.php” to “/” and check if the form was submitted at the top of the template file (for instance, if $input->get or $input->post contains some value or possibly if $config->ajax is true, depending on what the form does). If so, include the contactform-process.php file. If you tell us what you’re trying to achieve, we might be able to help you do it with ProcessWire, though.
  9. Mh, it works for me. I believe 'autoload' => true must be set for it to call ready(). Have you tried reinstalling the module?
  10. I mean, you could do something like this: //in site/ready.php $this->addHook("Page::renderBlock", function($event) { $page = $event->object; if ($page->template->altFilename) $blockPath = $page->template->altFilename; else $blockPath = $page->template->name; $blockPath = "blocks/{$blockPath}.{$this->wire('config')->templateExtension}"; $event->return = $page->render($blockPath, $event->arguments(0)); }); Now you can call $page->renderBlock() or $page->renderBlock(['this' => 'that']) and the block’s template path will be determined automatically according to the template settings. Or this, maybe: $this->addHook("Page::renderBlock", function($event) { $page = $event->object; $templatePath = $this->wire('config')->paths->templates; $templatePath = substr_replace($page->template->filename, 'blocks/', strlen($templatePath), 0); $event->return = $page->render($templatePath, $event->arguments(0)); });
  11. Step 1: Change your form element’s action attribute to <?php echo $page->url; ?> Step 2: There is no step 2. edit: sorry, I didn’t read the whole thread either. This same answer had actually been posted by Soma two posts ago.
  12. I think this is a bug in ProcessWire. When you use the ~= operator, ProcessWire translates it into MySQL’s select /*[…]*/ match(field_title.data) against('+New York' in boolean mode) as _score_field_title_data1 /*[…]*/ order by _score_field_title_data1 desc The score it uses to sort is generated by the database according to the number of times the string appears in the text (probably more complicated than that, but whatever). The problem is that several results will have the same score, so the order among them is not deterministic. The database just does whatever it wants at that point, so the order may change inbetween queries, even if the queries are the same, but especially if they differ, even just in LIMIT and OFFSET. If you add "sort" to your selector string, ProcessWire will still use the score to sort, but only after your specified fields. What ProcessWire should do is ALWAYS sort by page id at the end, to keep the order deterministic. It might also be nice to make the relevance scores accessible in selector strings, so you could do something like "title|trader~='New York', sort=-title_relevance, sort=-trader_relevance, sort=-modified, sort=-id" Now you could have results in order of textual relevance, and if the relevance is equal, get the most current ones first, or whatever you desire. Obviously the id is a pretty stupid way to sort, but since it’s strictly unique, it’s a stable way to break ties, so I’d always put it last.
  13. Yes, that would be very un-databasey. You basically have three entities you care about: Chairs, Brands and Adapters. At first glance (I may be wrong about this) it looks like each Chair has exactly one Brand and exactly one Adapter. For each Brand there are multiple Chairs and multiple Adapters, and for each Adapter there are multiple Brands and multiple Chairs. Make three templates, Chair, Brand and Adapter. The Chair template has one page field for a Brand page and one page field for an Adapter page. Now you can structure your page tree any way you like. If you want your URLs to look like http://example.com/e-drive/netti-i/, put Chairs under their Adapters as children. Now you can drop the Adapter page field and just use the Chair’s parent instead. If you want your URLs to look like http://example.com/alu-rhab/netti-i/, put Chairs under their respective Brands as children. Now you don’t need the Brand page field. Assuming the latter, finding all Alu-Rhab Chairs is easy: $pages->find("template=chair, parent.name=alu-rhab"). Finding all E-Drive Chairs: $pages->find("template=chair, adapter.name=e-drive"). Finding all E-Drive Brands: $pages->find("template=brand, children.adapter.name=e-drive"). Not sure about finding all Alu-Rhab Adapters, but if it comes to it, you can just get the page ids with SQL and do $pages->findIDs() on them. Or loop over all Adapters and check if there is at least one Alu-Rhab Chair for each one.
  14. I’m guessing header and footer come from prepend and append files. You’ll have to figure out a way to disable those in Ajax requests. For example, if you use $config->prependTemplateFile, just condition that with $config->ajax. //in site/config.php if (!$config->ajax) { $config->prependTemplateFile = 'head.inc'; $config->appendTemplateFile = 'foot.inc'; } You may need to set request.setRequestHeader('X-Requested-With', 'XMLHttpRequest') on your Ajax request for ProcessWire to automatically detect it as Ajax.
  15. Tbh for one-off imports I usually transform the csv (or whatever it is) into PHP or SQL using regex replace in Notepad++ and then just run that. 1500 rows should be nothing, unless they’re absurdly long. edit: nvm, I missed the 1.000.000 figure, but still, writing to the database directly should be an efficient option. In MySQL might want to use LOAD DATA INFILE, but you’ll have to adjust the input data first.
  • Create New...