Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by teppo

  1. Don't worry, it's not a stupid question πŸ™‚ You can definitely build a custom search feature and get great results with that, but things tend to get a little more complicated if your site contains a larger amount of fields, and particularly if you're using Repeater, RepeaterMatrix, PageTable, or other types of fields with repeatable content β€” or perhaps page reference fields gluing content from different pages together. In other words content that isn't technically (directly) part of the page, but needs to be tied with the page in the context of site search. Although in many cases you could no doubt include all those fields in your search queries, this can result in pretty complex queries, and such queries also tend to become inefficient. Generally speaking the more fields you join in the query, the more complex the resulting SQL query will get, and the more time and resources it'll take to process. Not a great thing for scalability. First version of SearchEngine was really just an easy way to reuse bits and pieces of code that were developed over time to mash field values together so that they could be searched more efficiently. Soon after along came the markup generating parts (which now make up a notable portion of the module), a set of features for automatically filtering and sanitizing queries and processing the index, JSON output option (mostly for AJAX requests), indexing support for field types requiring specific handling (core ones as well as third party), etc. From the initial post in this thread: These days in my projects I install SearchEngine, set it up, and trigger the render function. The module takes care of everything else and "just works". In a nutshell SE bundles most of the stuff a typical site search will need into one package, and tries to do it efficiently and following best practices πŸ™‚ Hope this answered your question!
  2. In the end I couldn't reproduce this issue: when a page is indexed, output formatting should be disabled, and thus this sort of problem shouldn't happen. Likely there's some scenario I've missed, so in 0.24.0 I switched that get() to getUnformatted(). I hope that resolves the problem β€” but if not, I may need a bit more information on how to reproduce it πŸ™‚
  3. Quoting myself here, but just wanted to add that they do indeed have a solution for this πŸ™‚ ... so if you're using purge as defined in the Tailwind config file you need to make sure that NODE_ENV is not production when you're doing your dev build.
  4. I had to take a closer look, and it's actually mostly related to our PHP task, which runs PHP_CodeSniffer (which can be very time-consuming). You can use this with any files, though β€” check out https://www.npmjs.com/package/gulp-cached. It's really easy to add, basically just require the package and add a single line to your gulp task. The basic idea is that gulp-cached keeps track of files, and makes sure that files are only passed downstream if they've changed since last run. What this means in practice is that when using watch, the initial build may still be slow (none of the files being watched are cached) while subsequent ones are going to be much, much more performant, as all files that didn't change will be skipped over. Other differences I can see with our setups: You seem to be running sourcemaps on every build. If this is really the dev/watch process, then I don't really see a reason to do that, and it's definitely going to slow things down. We're using gulp-if to check for env and only setting sourcemaps up if it's a production build (basically gulp build vs. gulp watch). I'm not seeing anything related to purge here. If you're using the purge setting in Tailwind config, this is a relatively new thing and I really can't say anything about that β€” for me it seems easier to just run purge as a part of the gulp task: // Tailwind extractor for purgeCSS const tailwindExtractor = (content) => { return content.match(/[A-z0-9-:\/]+/g) || [] } ... .pipe(gulpif(argv.prod, purgecss({ content: [ config.paths.base + '**/*.php', config.paths.base + '**/*.js', config.paths.site + 'modules/InputfieldCKEditor/*.js', ], extractors: [ { extractor: tailwindExtractor, extensions: ['php', 'html', 'js'] } ] }))) ... Actually it shouldn't β€” just having something like px-3 in a file with nothing else should be enough. Again this is based on the code I've posted above, so if the native feature is using some sort of "advanced" matching algorithm, it could be a major problem for a lot of code. Weird. Note also that unless Tailwind has a mechanism for disabling purge on dev builds, you're going to be doing a lot of work that you probably don't need there. That could be another bottleneck. I'd probably just stick to a manual purge declaration in gulpfile. There's good documentation for that here, in case you need more details: https://tailwindcss.com/docs/controlling-file-size/.
  5. 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 πŸ™‚
  6. teppo

    Request Error

    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.
  7. 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 πŸ˜„
  8. AJAX request detection is based on the X-Requested-With header. You need to set its value to XMLHttpRequest: // via default settings: axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; // or via config object when making the request: axios.post('/post/', { pageID: this.pageID, text_heading: this.text_heading }, { headers: { 'X-Requested-With': 'XMLHttpRequest' } }) Written in browser and untested, but that's the general idea anyway πŸ™‚
  9. Hey @adrian! I'm pretty sure that those issues were already fixed. Could you check that you've got 2.1.0 installed?
  10. No worries, I get what you're saying πŸ™‚ The way SearchEngine is built makes it (in my opinion) really simple to use when you basically just want a search feature and are happy with some visual modifications to the form and list of results etc. But once your needs get more complex, there's a bit of a learning curve there. I've tried to keep the complexity to bare minimum, but it can still be a bit overwhelming at the beginning, especially if you're not particularly familiar with the way ProcessWire itself works. You can definitely do the kind of query you mentioned above with SearchEngine. At least for now the index field is just a regular FieldtypeTextarea (or FieldtypeTextareaLanguage for multi-lingual sites), which means that you can perform queries against it just like with your own custom fields. +1 to this right there. Selectors are one of the biggest arguments for ProcessWire: not only do they make complex queries a breeze, but by sticking with them you can easily avoid some of the gotchas you'd have to worry about working with raw SQL (injection attacks, etc.) Behind the scenes almost every field you see in the admin is what one might call a "custom field", and each of those has a database table of its own. ProcessWire makes extensive use of JOIN queries, which do indeed make things more complex if you're trying to write raw SQL, but again: this is something you should almost never do anyway πŸ™‚
  11. [18-Jun-2020 03:42:32 America/New_York] PHP Fatal error: require(): Failed opening required '/home/niklcicr/public_html/wire/config.php' (include_path='.:/opt/alt/php56/usr/share/pear:/opt/alt/php56/usr/share/php') in /home/niklcicr/public_html/wire/core/ProcessWire.php on line 1199 I don't have an answer to you, sadly, but looking at the post you linked to, this seems like a different issue. In that other case the problem was that the host only had 32MB of memory available, which wasn't enough to actually run (or even install) the system. In this case it seems that PHP is unable to include the config file. I would start by making sure that it actually exists in the path mentioned above. If it does, it could be a permission issue: depending on the setup PHP may be running as some user that doesn't have access to this file. Could also be something entirely different, so what I'd really suggest doing would be contacting support on the host in case they've got an idea what's going on. Note: this is a little off-topic, but your host is running PHP 5.6.40. That's a very old version that hasn't received official security updates since January 2019, so I'd suggest updating to PHP 7, and preferably at least PHP 7.3. And if that's not possible on this host, it might be best to look for a new one... πŸ™‚
  12. Hey @Erik Richter, FormBuilder questions would be best posted to the FormBuilder VIP support area, which you get access when you purchase a license. If you have bought a license and still don't have access, be sure to contact Ryan to get it sorted out πŸ™‚ To me it looks like the code you've posted and the error you're seeing are not directly related: the notice suggests that you're using $first_name, while in the code you're clearly referring to $values['first_name']. I'm not really familiar with how the autoresponder logic works, so perhaps there's an explanation for this, but in the meantime I'd make sure that this really is the code you're running. Since the modules section of the forum is only intended for module-specific support threads β€” one per module β€” I'm moving this topic into General Support. Perhaps someone can help you there.
  13. Hey @cosmicsafari! FormBuilder questions should really be posted to the VIP support area, which you should have access to if you've got a FormBuilder license. If you have bought the license yet still don't have access, you should contact Ryan so you can get it sorted out πŸ™‚ I don't think I've ever used $forms->embed() in this way, but according to the docs you can pass in an array that overrides GET variables, while with render you can pass in an array of pre-populated values. These are different things, obviously, though it probably should work if you had configured your form so that values can be pre-populated using GET variables.
  14. Hey there! Just wanted to drop a quick comment πŸ™‚ SearchEngine provides two built-in methods for search form rendering: Highly customizable "basic form". You can probably get the best idea of this by taking a look at these lines in SearchEngine.module.php. I'd actually be surprised if there's something you can't customize. Less customizable (unless you really enjoy hooking into form rendering) "native ProcessWire form". I know that some folks prefer these (I don't), so I thought it would be a nice addition. ... and, of course, you don't have to use either one. Bring your own markup. SearchEngine doesn't really care about the form β€” there's no CSRF or anything involved, it's just a search feature πŸ™‚ As for the results list, there's the "easy way" where you let SearchEngine handle everything for you. Again, this is quite customizable via config settings and hooks, if you've got something specific in mind. JSON is also an option, but this is mostly intended for cases where you want to utilize SearchEngine as a part of an API, or perhaps create a fully customized JS search form feature. The biggest things lacking form SearchEngine (in comparison to tools like Meilisearch, or more heavy-weight indexers such as Solr, Elasticsearch, RediSearch, etc.) are the ability to normalize queries, perform complex lookups from the index (SE is basically just using ProcessWire's selectors and that's it), smart weighting of results based on relevance (this is on my to-do list), and perhaps really snappy real-time results (you can perform asynchronous queries, but they go through your site, which means that they have some overhead; tools like Meilisearch can do this much more efficiently). Anyway, just wanted to let you know that there are different options there. I don't actually know your case well and can't say if SearchEngine is the correct solution, but if it's UI level customization you're after, that shouldn't be an issue. And if it is, please let me know what's missing and I'll be happy to take a closer look; perhaps it's something that others might find useful as well πŸ˜›
  15. Note that legislation may differ from country to country. For an example here in Finland one apparently still has to document the cookies, even though "necessary" ones don't require opt-in (or opt-out). IANAL etc. but that seems to be the common consensus anyway πŸ™‚ Here's a rough translation of the descriptions we've been using: wires ProcessWire session identifier. First-party session cookie, expires when the browser is closed. wires_challenge ProcessWire session cookie used to verify the validity of a session. First-party session cookie, expires when the browser is closed.
  16. Right β€” looks like I skimmed too quickly over this part. Was also pretty sure that I had tested this before, but you're right that it doesn't seem to work at the moment. Thanks, I'll take a closer look soon!
  17. Actually it sounds like your search_index field could be single-value textarea, instead of textarea (multi-language). If so, you'll have to change the type of the field manually. Could you check if this is the case? Either way I should probably add some extra checks to make sure that this doesn't happen.
  18. teppo

    ProcessWire on the web

    Hey @jonatan! Good points regarding Kirby. Just wanted to drop a couple of comments πŸ™‚ Since you asked: Personally I find ProcessWire's current admin more appealing than the one in Kirby. I get that this is opinionated, of course, but from my point of view Kirby's GUI is the one that looks dated. For starters everything is tiny and stuffed, the icons and typography are rather mundane (in the lack of a better word), colour theme feels unimaginative (basically just black, gray, and then β€” gasp β€” a bit more black) and contrasts are pretty bad. I may be primarily a developer, but I'm saying this also as a designer and author: Kirby's GUI does not feel appealing to me, and it's definitely not something that would, in any way, inspire me. In a way it's nice and simple, yet at the same time it's "the wrong type of simple". Kind of like someone skipped most of the design phase and instead converted an initial wireframe into a final product πŸ™‚ (Again: this is highly opinionated. I get that different things appeal to different people β€” there's no universal truth when it comes to something like design. I'm also not trying to dismiss Kirby; I'm sure they have their strong points, but my humble opinion is that the GUI is not one of those.) I won't claim to know what the future has in store for this part of the ProcessWire core, but it's worth noting that a lot of what the core currently does depends on an actual database. Ryan has also stated on various occasions that features like full-text index are a must. I'm not very familiar with Kirby myself, so perhaps they've devised equally flexible and performant ways to perform complex queries, but I'd imagine that being much trickier to implement when you're missing all the nice database features β€” and without the ability to perform even complex queries, ProcessWire wouldn't really be ProcessWire. ... and, that being said, my understanding is that the flat file thing is one of the biggest β€” if not the biggest β€” selling point of Kirby. I bet it's a great tool for a lot of use cases, but one could say that it's really competing in a somewhat different category compared to ProcessWire πŸ™‚
  19. To be clear I wouldn't say that it was a failure by any means β€” more like we didn't see major benefits going with Editor.js vs. Repeater Matrix + CKEditor. "Results were inconclusive" πŸ™‚ Like you said, Editor.js probably isn't going to replace Repeater Matrix if what you really need is a block builder; at least it doesn't seem like a good idea at the moment. While it could definitely help with some tasks that CKeditor currently isn't very good at β€” such as embedding images β€” at the same time the "every element is a block" approach can also feel a little intimidating and perhaps even unintuitive for those more familiar with "traditional" content editors (CKeditor, Word, etc.) Should probably also mention that I did my proof of concept back in March, when the Editor.js project seemed a little... unresponsive. There were big missing parts (including i18n support) and issues that were not getting much attention. Now that I've checked, it appears that the project is going strong again. Hope this makes sense. All in all I'm very curious to see where you're going with this module! πŸ™‚
  20. Intrigued! As it happens, I have InputfieldEditorJS + FieldtypeEditorJS proof-of-concept sitting on one of my own sites as well. Mostly functional, though your module looks way more polished. I never got to implement media uploads, for one. It was intended as a test to see if our team would prefer that over Repeater Matrix, and since it wasn't a massive success, I never fully completed it. Very much looking forward to seeing your module in action πŸ™‚
  21. Likely irrelevant, but... // wire('pages') $existing = wire('pages')->get("template=supplier, unique_id={$record['Unique ID']}", ['cache' => false]); ... // $pages $pages->uncacheAll(); I don't see anything obviously "wrong" with your script, which is why I'm wondering if it could be possible that this uncache call isn't doing what it should?
  22. Literally heard about hCaptcha for the first time earlier today when someone recommended it as a ReCaptcha replacement. Great to have this available as an option! πŸ™‚
  23. teppo

    Fatal Error

    Hey @Dean, A few more questions β€” it's still pretty hard to say what's going on there, except that for some reason "something" is trying to set current user as something other than User object. Is this the only page on your site (/register/) that generates this error? If so, what's happening on that page? Any modules involved? πŸ™‚ Have you updated ProcessWire or your modules recently?
  24. @Mamun Paul, this is a double post (https://processwire.com/talk/topic/9711-map-marker-map/?do=findComment&comment=202283) and also not related to module development, so I'm closing this thread. One topic per issue, please.
  25. Hey @montero4, First of all, just wanted to say that I really need to figure out some way to handle these conflicts with Hanna Code β€” it's becoming a common issue. I'll see what I can do about that soon πŸ™‚ Technically there's nothing wrong in your code. It will work just fine on the front-end, where it's really intended to run. The problem is that in order to get useful index out of field content, SearchEngine actually gets it via $page->getFormatted(), which means that TextFormatters (such as Hanna Code) will also run in the admin side. In this case you're using $pages->get() to get another Page, and since the default in the admin is that output formatting is off, this means that this new Page will have output formatting disabled β€” and that's why $page->image actually returns an instance of Pageimages (instead of a single Pageimage). ... anyway, just wanted to explain what's going on in here πŸ™‚ Right now the easy fix would be checking for the type in the Hanna Code snippet. (Again, I'd like to automatically handle this in SearchEngine, but I can't say for sure when I'll get to that.) $page=$pages->get($id); //gets the page $image = $page->image instanceof Pageimages ? $page->image->eq(0) : $page->image; $image = $image->width(1240, ["suffix" => "srcset"]); //create image that is 1200px wide Alternatively you could make sure that output formatting state is on β€” it's mostly a matter of taste, really: $page=$pages->get($id); //gets the page $of = $page->of() // store initial output formatting state for later use $page->of(true); // make sure that output formatting is on $image = $page->image->width(1240, ["suffix" => "srcset"]); //create image that is 1200px wide $page->of($of); // restore initial output formatting state
  • Create New...