Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 06/27/2020 in all areas

  1. Version 3.0.161 on the dev branch continues with the updates optimizing our support for the new selector operators introduced in last week's blog post for 3.0.160. Last week I was still kind of figuring it out and the code still needed some refactoring and optimization. This week several parts have been rewritten and it's been improved quite a bit. Though the end result is still very similar to what was demonstrated last week, but now it's a lot more performant and solid. One thing new this week that's also kind of fun: you can now use more than one operator in any "field=value" selector expression, at least from the API side. And it works anywhere that you might use a selector, whether querying the database or something in memory. I think the best way to explain it is with an example. Let's say that you want to find all pages with a title containing the phrase "hello world" — you'd do this using the "contains text/phrase" operator: *= $pages->find("title*=hello world"); But let's also say that if you don't find any matches, you want to fallback to find any pages that contain the words "hello" and "world" anywhere in the title, in any order. We'd use the "contains all words" operator "~=" to do that. So now you can add that operator to the existing one, and it'll fallback to it if the first operator fails to match. So we'll append the "contains all words" operator to the previous one: ~= $pages->find("title*=~=hello world"); Cool huh? But maybe we still aren't finding any matches, so we want to fallback to something even broader. So if the phrase match fails, and the words match fails, now we want to fallback to find any pages that contain the world "hello" OR "world", rather than requiring them both. For that we can use our new "contains any words" operator: ~|= $pages->find("title*=~=~|=hello world"); This example is getting a bit contrived now, but let's say that if we still haven't found a match, we want it to find any pages that have any words starting with "hello" or "world", so it would find pages with words like "helloes", "worlds", "worldwide", etc. That's a job for our new "contains any partial words" operator: ~|*= $pages->find("title*=~=~|=~|*=hello world"); Okay last one I promise—you probably wouldn't stack this many in real life, but stay with me here. Let's say the query still didn't find anything, and as a final fallback, we want it to find any words LIKE "hello" or "world", so that those terms can match anywhere in words, enabling us to find pages with words like in the previous example, but also words like "phellogen", "othello", "underworld", "otherworldly", etc., and that's a job for our new "contains any words like" operator: ~|%= $pages->find("title*=~=~|=~|*=~|%=hello world"); So that looks like a pretty complex operator there, but as you've seen by following the example, it's just these 5 appended operators to each other: *= Contains phrase ~= Contains all whole words ~|= Contains any whole words ~|*= Contains any partial words ~|%= Contains any words like I think a more likely scenario in a site search is that you might stack two operators, such as the *= followed by the ~|*=, or whatever combination suits your need. By the way, you can do this with any operators, not just the text searching ones. But if you didn't read the blog post last week, also be sure to check out the other new operators in addition to those above: *+=, **=, **+=, ~*=, ~+=, ~~=, ~%=, #=. I think these new operators help out quite a bit with ProcessWire's text searching abilities. But there's one thing that's kind of a common need in search engines that's not easily solved, and that's the handling of singular vs. plural. At least, that's a common issue when it comes to English (I'm assuming so for other languages, but not positive?) MySQL fulltext indexes can't differentiate between singular and plural versions of words, so they index and match them independently as completely different words. This can be unexpected as clients might type in "goose" and expect it's also going to match pages with "geese". I've already got something in the works for this, so stay tuned. Thanks for reading and hope you have a great weekend!
    9 points
  2. First of all: I definitely agree with your first point. I need to do some testing and probably add additional configurability to the SearchEngine module after these updates. Some pretty interesting options we've got now! In the past I've steered away from the full-text index because it has resulted in way too many "oddities", i.e. some queries just don't work either due to stopwords or something else, and it seems to be (in my experience) particularly problematic if the site is authored in some other language than English. You've given me a reason to revisit this, though ? As for plurals, it sure is an issue with other languages as well. I have no idea what you've got planned in that regard, but one problem here is that it gets pretty complex if you want to support other languages than just English (which is, actually, one of the easiest languages in this regard). And then there's of course the bigger issue of stemming — considering your goose example, if a client was searching for "hanhi" (goose in Finnish), it's true that they would likely expect it to also match "hanhet" (plural), but if that works then why not other forms such as "hanhia", "hanhen", "hanhien", "hanhesta", "hanheen", etc. Anyway, very much looking forward to what you've got planned! Just wanted to point out that this can be a pretty big issue to tackle, at least unless limited to English only, or perhaps made so modular that each language can have its own set of rules. Also it's a slippery slope, and once things like stemming come into play we're in really deep waters ?
    5 points
  3. Hi there, another one finished, up and running. https://bots4you.de/ The website informs about bots4you which is a German based Chatbot creator. Special with this chatbot is its b2b purpose, that means it is pretty decent in "knowing" what customers of several industries (real estate, insurances etc.) want to know and describe their efficiency with nearly 80% of success for common customer inquiries. From the ProcessWire perspective I mainly use Repeater Matrix with which I only have one template (even for home) but 8 content modules that can be arranged like the customer wants to create different pages. Other than that I used TailwindCSS for the first time, but I am not convinced, at least in a PW environment. Downsides where: build time when in dev mode (hot reload takes up to 6 seconds) purge of my php files was less than reliable. I ended up putting most of the classes on an allow list in the tailwind config. Could be my fault, but the overall experience wasn't that great. Anyway, client is happy, and I am, too: ?
    3 points
  4. Got to agree with Kongondo here. In my case the dev hot reload takes < 2s, and that's with some recent slowdowns (not sure what's going on in my system, but it used to be < 1s). Of course this also depends a lot on what you're doing at dev stage: are you running purge here as well, what else are you running on each rebuild (pre- or postprocessors and whatnot), which files are you watching, etc. Depending on your setup there may be steps you can take to get it down considerably. In our gulp based workflow, for an example, one major bottleneck was solved by adding gulp-cached — on a moderately large site this took dev build time down from what was originally probably 6-10s to 1-2s. Never had this issue either. There could be something else wrong, but usually this would mean either that you're actually not going through all those PHP files in the purge step, or you're using some sort of "constructed" class names (px-<?= $x ? 1 : 2 ?>). Not saying that you're doing something wrong, but again: this has been working perfectly for us. Note: I've got some beefs with Tailwind myself, but those are all about the general methodology. Tech wise it's been really, really slick ?
    3 points
  5. /** @var InputfieldCheckboxes $f */ $f = $modules->get('InputfieldCheckboxes'); $f->name = 'foo'; $f->label = 'Foo'; $f->addOptions([ 'red' => 'Red', 'green' => 'Green', 'blue' => 'Blue', ]); // The value will be an array e.g. ['red', 'blue'] $f->value = $this->foo; $inputfields->add($f);
    3 points
  6. Have you thought of writing a Textformatter module? They're really very straightforward - you don't even need to use hooks. There are good examples to copy in wire > modules > Textformatter (for instance, TextformatterNewlineBR.module is a nice starting point). Once you've put your module in the site > modules and installed, apply the Textformatter on the Details tab of the fields where it's needed.
    2 points
  7. Man Ryan. This just phenomenal. Truly great job.
    2 points
  8. $wire->addHookBefore('InputfieldFile::fileAdded', function($event) { /** @var InputfieldFile $inputfield */ $inputfield = $event->object; $page = $inputfield->hasPage; if($page && $page->template == 'your_template') { // ... } });
    2 points
  9. @schwarzdesign, I agree with your suggestion in the GitHub issue, but in terms of working around it double-check that you have the HTML Entity Encoder textformatter applied to the title field (it is by default after installing PW, and should be applied to all plain text fields). Because with that applied I don't experience the issue on a clean PW installation:
    2 points
  10. This is unusual. How does your setup look like?
    2 points
  11. This is a module that is similar in purpose to the Runtime Markup module. I made it primarily for my own use but am posting it here because I had a request to add it to the modules directory. Fieldtype Runtime Only Not a proper fieldtype because it doesn't save data to the database. The fieldtype only exists to provide a convenient way to add an inputfield to templates that will render some markup at runtime. For a field named "my_field"... Inputfield markup will be rendered from a file at /site/templates/RuntimeOnly/my_field.php. In addition to the standard ProcessWire variables this file receives: $page - the page being edited. $field - the Field object. $inputfield - the Inputfield object. JS file /site/templates/RuntimeOnly/my_field.js will be added to admin if that file exists. CSS file /site/templates/RuntimeOnly/my_field.css will be added to admin if that file exists. Tips Output formatting Output formatting for $page will be off in the context of Edit Page so if you want to use the formatted value of a field in your RuntimeOnly code you should use $page->getFormatted(). E.g. $value = $page->getFormatted('some_field_name'); Repeaters If the RuntimeOnly field is used inside a Repeater field then you can get the Repeater page it is on via $inputfield->hasPage. E.g. $repeater_page = $inputfield->hasPage; // Use $repeater_page as needed echo "The name of the repeater page is $repeater_page->name"; https://github.com/Toutouwai/FieldtypeRuntimeOnly https://modules.processwire.com/modules/inputfield-runtime-only/
    1 point
  12. Thanks szaesz, fixed. ? Pretty basic I guess. But I also assume that something in there is slowing down the process, extract from gulpfile: // CSS task function css() { var plugins = [ tailwindcss(), autoprefixer() ]; return gulp.src(srcPaths.styl) .pipe(plumber()) .pipe(sourcemaps.init()) .pipe(stylus()) .pipe(postcss(plugins)) .pipe(sourcemaps.write('.')) .pipe(gulp.dest(buildPaths.css)) .pipe(browsersync.stream()); } Knowing that it should be faster, I can iterate over it and try to eliminate the bottleeneck, thanks. Interesting, could you give an example of your setup? The other issue still remains. A typical .php of the project file looks like this: <?php $cssClass = ""; $textoutput = ""; $waveClass = $page->checkbox1 ? " wave" : ""; $colClass = $page->checkbox2 ? " flex-matrix" : " md:flex-1"; $containerClass = $page->checkbox2 ? " matrix" : ""; $containerHeadline = $page->text1 ? "<h2>{$page->text1}</h2>" : ""; $cardoutput = "<div class='boxes__cards flex flex-1 items-stretch flex-col lg:flex-row {$containerClass}'>"; $cardClass = "boxes__card"; foreach($page->cards as $card) { include('parts/card.php'); } $cardoutput .= "</div>"; $output = " <div class='element element--boxes{$waveClass}' id='{$sanitizer->pageName($page->text1)}'> <div class='container content pt-8 relative z-20'> {$containerHeadline} <div class='flex items-start'> {$cardoutput} </div> </div> </div>"; echo $output; Most of the tailwind classes don't get caught by purge, some do. I assume it is looking for sth like class="...". And my classes are dynamic depending on settings. I don't know how to solve this without adding a lot of overhead to the template files. Absolutely. I really see the benefits and also it makes a lot of fun trying things out and adjusting "on the fly". But with the above mentioned problems the benefits were reduced too much. I am also considering Tailwind for some vue projects, but the overhead for dynamic classes scares me off a little.
    1 point
  13. I understand how this can be tricky. One way to find out what's available is to go down the rabbit hole. In your case, you are dealing with the class InputfieldFile. So, using the search in the API docs here: https://processwire.com/api/ref/ to look for 'inputfieldFile' would bring you here (the API docs for the Class): https://processwire.com/api/ref/inputfield-file/ Going through those docs, there is no method or property directly dealing with templates or pages. However, this is a derived class, so the parent class could help. Looking at this ubiquitous note on this page: We might be able to get something in the parent Class, Inputfield: https://processwire.com/api/ref/inputfield/ So, we head over there and reading through, we find this under Other: ?
    1 point
  14. The modules directory issue is now fixed. @eydun, note that this is not a module support thread, so I've moved it to the General Support area of the forum. "Modules/Plugins" area is reserved for module-specific support threads, one per module.
    1 point
  15. Thanks to you both. Thanks Robin, I'll try that! I thought it should be easy but I am new to hooks and couldn't find a way to get from $event to the template.
    1 point
  16. Yes. The admin warns you about this when you define a "required if" condition for a field inside a Repeater: @ryan, it would be nice though if this limitation was mentioned in the relevant section of the inputfield dependency documention. More information: https://github.com/processwire/processwire-requests/issues/262
    1 point
  17. @MadeMyDay Thanks for the showcase. Note that the contact form in the English version is 404.
    1 point
  18. Hi @Mats thx, this has been on my wishlist for quite some time ? Have you thought about also integrating other services like https://www.pexels.com or https://pixabay.com ?
    1 point
×
×
  • Create New...