Jump to content


Popular Content

Showing content with the highest reputation since 06/14/2020 in Posts

  1. 20 points
    This week I'm not bumping the version number just yet because I've got lots of work in progress. The biggest thing so far is something I hinted at last week. Basically, I like what the addition of the MySQL query expansion operators have brought (per posts last week and week before), but they also reveal what's lacking: something as simple as a search for "books" still can't directly match the word "book". But that's the most basic example. It's not a limitation of ProcessWire, but just the type of database indexes in general. I think it'd be amazing if ProcessWire had the ability of being really smart about this stuff, able to interpolate not just plurals vs. singulars but related words. In a perfect world, this is what query expansion would do (in addition to what it already does). But the reality is that it involves all kinds of complicated logic, rules and dictionaries; well beyond the scope of even a database. And it can be vastly different depending on the language. So this isn't something we can just add to the core and have it work. On the other hand, I figured maybe we should just put in a hookable method that just pretends the ability was there. Then people could hook it and make it respond with variations of words, according to their needs. The searches that use query expansion could then call this method and use whatever it returns... for when someday the ability is there. So I went ahead and added that hook — WireTextTools::wordAlternates(). And our database-searching class (DatabaseQuerySelectFulltext) now calls upon it, just in case an implementation is available. Well, after getting that hook added and having our class call it, naturally I wanted to test it out. So I got to work on it and came up with this module: WireWordTools. The WireWordTools module provides an API for English word inflection and lemmatisation. And it hooks that new method mentioned above, so that you can install it and immediately have it bring your searches to the next level. While it only helps for English-language searches, maybe we'll be able to add more languages to it, or maybe it'll lead to other modules that do the same thing for other languages. The expanded/alternate words are only used for searches that use the new query expansion operators, which are the ones that have a "+" in them: ~+=, ~|+=, *+=, **+=. They all can return similar results, but are weighted differently. Unlike most operators, where the logic is direct and you can expect them to always behave the same way, these query expansion operators are more subjective, and ones I think we should intend to keep tweaking and improving over time to continually improve the quality of the results they return. Basically, they are geared towards building site search engines, so I think it makes sense for us to pursue anything that makes them better at that, rather than aiming to always have them return the same thing. I am currently testing out the ~|+= operator ("contains any words expand") on our main site search engine here, along with the WireWordTools module. Finally, searching for "books" does match "book" too, and a lot more. More to be done here, but it's a good start hopefully.
  2. 20 points
    In ProcessWire 3.0.160 we’ve got some major upgrades and additions to our text-matching selectors and operators. This brings a whole new level of power to $pages->find() and similar API calls, especially when it comes to search engine type queries. This blog post also includes a demo search engine that lets you test everything out live— https://processwire.com/blog/posts/pw-3.0.160/
  3. 17 points
    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!
  4. 16 points
    Relative to ProcessWire 3.0.161, version 3.0.162 contains 24 commits that continue upgrades/improvements to selector operators, fix various minor issues, add new API convenience methods, improve documentation, optimize and refactor various portions of code and DB queries, and much more. For full details, see the dev branch commit log as well as last week’s post. Next week I hope to finally finish up a new version of ProCache and continue with some additional core to-do items. By early August my hope is that we’ll have the next master branch version ready. Also added this week is a new dedicated documentation page on this site that covers all of ProcessWire’s selector operators, including all the newly added ones here: selector operators. Thanks for reading and have a great weekend!
  5. 15 points
    Hello @ all Today I want to share an inputfield/fieldtype to store 2 or 3 dimensions of an object. This fieldtype was inspired by the amazing fieldtype "Fieldtype Dimensions" from SOMA (https://modules.processwire.com/modules/fieldtype-dimension/). This fieldtype was introduced in 2013 - so its time for a relaunch. This new fieldtype offers more possibilities than the old one from SOMA. This inputfield/fieldtype let you enter max. 3 dimensions (width/height/depth) of an object (fe a product), but you can select if you want to display inputs for 2 or 3 dimensions. 2 dimension can be used fe for wallpapers or photos, 3 dimensions fe for furnitures or other objects. There are several configuration options for this fieldtype in the backend. set type (2 or 3 dimensional) set width attribute for the inputfield in px (default is 100px) set size unit as suffix after each inputfield (default is cm) set max number of digits that can be entered in each field (default is 10) set max number of decimals (default is 2) show/hide a hint to the user how much digits/decimals are allowed If the number of decimals or digits will be changed, the database schema for each dimension column will also change after saving the field in the backend. For example: If the schema for each dimension field in the DB is f.e. decimal(10,2) and you will set the number of digits in the configuration to 12 and the number of decimals to 1, then the schema in the DB will also change to decimal(12,1) after saving the inputfield. You can download this inputfield at https://github.com/juergenweb/FieldtypeObjectDimensions There you will find more detailed information and explanation too. If you find any bugs or you have an idea to improve it (also code improvements) please report it on Github. Have a nice day!
  6. 14 points
    Hello fellow ProcessWire people! I published an article explaining how I migrated three years worth of running data from Garmin to ProcessWire: https://francescoschwarz.com/articles/running-on-my-own/ Have a great day! Cheers.
  7. 10 points
    Hello @ all! I want to share a simple fieldtype and inputfield to store address data with you. I have created this inputfield for learning purposes and it has no fancy functionality. It is simply for storing address data such as street, number, postalcode and so on in one table. As an addition you can store latitude and longitude too, so you can use them in maps. Here is a screenshot of what it looks like: You can select which fields are mandatory and you can choose if the inputs for longitude and latitude should be displayed. These settings can be configured in the field configuration. If you find this inputfield useful you can download it at https://github.com/juergenweb/FieldtypeSimpleAddress There you will find a detailed explanation. If you have an idea of an usefull feature that can be added or you have detected a bug, please report it in my github account.
  8. 9 points
    Using SSL should be quite straight forward, assuming that everything is configured correctly on the server side. The enforcing happens on the server the moment you issue an ALTER USER your-processwire-user@your-mysql-server REQUIRE SSL The moment you do that, you'll get a database error when you access your site. To enable PHP to talk over an encrypted MySQL connection, you now need to point it to the MySQL server's CA certificate. Copy that to a location where the web server can read it and add an entry in site/config.php (adapt the path to match your ca cert location): $config->dbOptions = array( \PDO::MYSQL_ATTR_SSL_CA => 'C:/temp/mysql-ca.pem' ); There may be scenarios where the name you use to access the server doesn't match the name in the certificate and you get the error "SQLSTATE[HY000] [2002]". The same error occurs when you use a self-signed certificate in the server (that's the case when you leave things to default after installing MySQL on most distributions). In that case, you need at least one of the following PHP versions: PHP 7.2, 7.3, 7.4 or 8 all versions PHP 7.1 >= 7.1.4 PHP 7.0 >= 7.0.18 The reason is that earlier versions of the MySQL PDO module didn't have the flag to disable certificate verification. You need to expand your entry in site/config.php: $config->dbOptions = array( \PDO::MYSQL_ATTR_SSL_CA => 'C:/temp/mysql-ca.pem', \PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => false ); Most (hopefully all) PW modules should be using the PDO interface by now, but you may stumble upon one that still makes use of the old mysqli wrapper. Those won't work with an SSL connection.
  9. 9 points
    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: 😉
  10. 9 points
    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 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/
  11. 7 points
    We have created a module to create BlurHash strings for images while uploading in ProcessWire. This blurry images will be saved in the database because they are very small (20-30 characters) and can be used for Data-URL's as placeholders for image-lazy loading. https://github.com/blue-tomato/ImageBlurhash E.g. where we use this in production: https://www.blue-tomato.com/en-INT/blue-world/ https://www.blue-tomato.com/en-INT/blue-world/products/girls-are-awesome/ https://www.blue-tomato.com/en-INT/buyers-guides/skateboard/skateboard-decks/ https://www.blue-tomato.com/en-INT/team/anna-gasser/
  12. 7 points
    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 😄
  13. 7 points
    Screencast updated - import of an entire article ☝🏼️ Still dealing with media files.
  14. 6 points
    Heya folks! Just wanted to say that I finally got a chance to properly test this module, and... wow. Amazing work! It looks like you had a bunch of additional stuff planned, but the features that already are there are very useful, and apart from a few minor glitches the module seemed to work like a charm. While the built-in template editing tools we have in the core are not at all bad, at least for me the workflow with Designme is still a huge improvement 🙂 At this point I'm mostly curious about what else you might've had in store when you said that the module was "far from being good enough for release". @elabx, care to provide some insight on this? I mean... it feels to me like you could've removed some of the "less "critical" features (widgets, perhaps even the code editor, etc.) and just released the module as-is. I might be missing something important, of course, but that's my impression anyway. Either way I'm blown away by just how awesome this module is! 🙂
  15. 6 points
    I didn't want to create a topic for this, so I decided to use my existing thread , as mentioned, I am creating some Youtube tutorials around Processwire, I feel a video is much more easier to help people getting started with Processwire. So I did a first video introduction, However I quickly realized my dilemma with self expression skills when talking, so I am working on that but here is the first video and I hope to drop a Video per week or more depending on how fast I can get things out but I am also open to covering other complex topics too around Processwire. Thanks and I hope this helps out a lot of people. NOTE: LOL Working on how I sound too 😁, bear with me Love from Nigeria
  16. 6 points
    Check the "Advanced" tab in the Template settings. There you'll find an option to make the createdUser modifiable:
  17. 6 points
    I was going through the Hanna Code "Readme" in Bitpoet's editorial blog based off kongondo's Blog module and this particular line caught my attention: $f = $modules->InputfieldCheckboxes; $f->name = 'vegetables'; // Set name to match attribute $f->id = 'vegetables'; // Set id to match attribute $f->label = 'Vegetables'; $f->description = 'Please select some vegetables.'; $f->notes = "If you don't eat your vegetables you can't have any pudding.";//<<<<<<<<<<<< $f->addOptions(['Carrot', 'Cabbage', 'Celery'], false); $form->add($f); Very funny... 😁
  18. 6 points
    Check this out: https://processwire.com/blog/posts/pw-3.0.137/#on-demand-mirroring-of-remote-web-server-files-to-your-dev-environment
  19. 6 points
    Today, I am glad to announce that the module support the native image field 👍🏼
  20. 6 points
    There is an alternative method in ProcessWire to determine if $page is editable by current user: https://processwire.com/api/ref/page-permissions/editable/ It returns true or false if the user is allowed to edit the page.
  21. 6 points
    @encho you pointed to something I hadn't thought of before reading your comment. I then tried all the afternoon to work on that - I have to brainstorm more about that, but I think we could have something which works. In this sample, you can see a heading and a paragraph written in a CKEditor field. You can then change the fieldtype to EditorJS and get you saved data. As you can see - and as you stipulated as well in your last comment - the strong tag isn't taken into account. Anyway, I am quite confident to get a parser working here. I still take into account that I am not aware of how/which DOM are inserted on every CKEditor for a given user. I was thinking to alert the user if his content couldn't be parsed entirely, or something like that, and so, a manual intervention will be needed in this case. And this is how look the paragraph with inner DOM elements, should be "easy" to insert them :
  22. 6 points
    Hi @michelangelo, The fastest way to achieve the effect of Instagram feed, is to use Processwire Pagination with Ajax Infinity Scroll, for example https://infiniteajaxscroll.com There is no silver bullet to take thousands of results form any kind of database. You should take it part by part and Processwire Selectors with Limits are good solution or prerender them as static data and keep them cached, as guys above said. BTW, 1,000 divs on one page is realy bad idea in terms of browser capacability. Just open Instagram, scroll hounded posts and take a look how many resources it will takes from your console. Good luck Alexander
  23. 5 points
    So I basically meant like I felt it needs a bit more of a well thought structure to make it more maintainable for the future (and I think it had some missing parts? can't remember). I have had to give maintenance to other projects *cough* Recurme *cough* and although that one was particularly complex, I learned my lesson that I definitely don't want to release MVP's that turn into a pain to maintain later just for the sake of getting it out there, I might be just wrong of course. (joshua always insisted I was too conservative in this aspect haha) I agree some of the features could be taken off, like the editor and widgets. I also remember some bits were missing to make it fully functional at the point we envisioned, I think a bit of stuff with repeaters/repeater matrix, don't remember now honestly but it indeed works for the most part! We really feel it shows a lot of the power ProcessWire "hides"!
  24. 5 points
    This is one of the most common solutions, but as in everything with PW, it's your call how you do it! What you could do with your approach is place that php script outside of the sites directory which is protected by apache from being accessed directly for security reasons. So on your ajax request, the url is just /archive-list-render.php?q=etc Now, on you archive-list-render.php, load the PW API: <?php //This is the index.php in the web root directory, sibling to site, wire, etc. include("./index.php"); $q = $sanitizer->text($input->get('q')) $foundPages = $pages->find("somfield=$q"); //imaginary doSomethingWithPages method.. $response = doSomethingWithPages($foundPages); echo $response; Another approach for simple cases is using the same page where the ajax requests originates from, and detect if it's an ajax call otherwise render the site. This can get tricky depending on appending or prepending files into the template. (Very well exemplified on Ryan's post bellow) <?php if($config->ajax){ //ajax processing/render stuff } else{ //normal render stuff } Ryan's post:
  25. 5 points
    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 🙂
  26. 5 points
    😀 Yet another runtime field. I can also provide one: slim and full PW-API provided. In addition, you can change everything in another field (Database) via hook into ProcessInput. https://github.com/kixe/FieldtypeMarkup
  27. 5 points
    Progress update: Have managed to throw in a few hours on v2. The frontend is being rebuilt in Svelte, because I simply don't use jQuery/Datatables anymore. By not using any of these, I'm free to code this thing the way I want, without having to use a bunch of dependencies that are simply frustrating to build things with. Datatables in particular is hell to work with. (As an aside, I primarily work with Vue, but Svelte is a little more suited here. No runtime, much smaller bundle.) Anyways, here's a preview of the redesigned jumplinks list. Newly built styles, consistent in both the default and UIKit themes (should be fine in custom themes too) and scoped to the Svelte container. Have carried over the behaviours, however instead of fetching all jumplinks, they're now fetched as a paginated collection. I'm sure there are a few sites out there with many jumplinks, and fetching them all is just too much. As mentioned in a previous preview post (such a long time ago!), you'll be able to turn off the colour helpers if you don't like/need them.
  28. 5 points
    Hi @joer80 In the top of the post.php file, you can write your logic to check which user is allowed to post or not xhr request. Example : <?php namespace ProcessWire; // if the page is viewed wihtout ajax, return if(!$config->ajax) return; // if the user is a superuser, return if($user->isSuperuser()) return; // only editor can post request to this page if(!$user->hasRole('editor')) return; // other checks if needed, CORS check, Custom header check, etc // rest of code - access granted // ... then, for example in your component , but anyway you already know how to do it : // example editPage() { this.$store.dispatch('setEditPage', this.$route.path).then(() => { axios .post(config.apiEditPageURL) .then(response => { this.data = response.data }) .catch(error => { this.errored = error }) .finally(() => { this.$store.dispatch('loading', false) }) }) },
  29. 5 points
    For a brief moment I was contemplating parsing HTML with regex but then StackOverflow taught me this: https://stackoverflow.com/a/1732454/1036672 My sides are now hurting 😂
  30. 5 points
    A ProcessWire find will perform an SQL query. The important thing (in terms of performance and tools like RockFinder) is what happens next. SQL queries are normally very fast. However, if you then load the results into Page objects, you might get a performance hit depending on the number of results you fetched. RockFinder does not load Page objects, hence remains very fast and performant. It is very much suited to handling large datasets.
  31. 5 points
    In the blog post last week we looked at some of the two-factor authentication system upgrades, like the new “remember this computer” feature. This week I finished off the remaining parts, as well as released new versions of both the TfaTotp and TfaEmail modules. Auto-enable TFA support We now have auto-enable support (forced 2FA), which lets you setup two-factor authentication for users, without their input (if they haven’t enabled it already). This is a good way to add a lot of security for very little work. Currently, the module that supports this is the TfaEmail module. That’s because it’s a safe bet to assume the user has access to their email, even if they haven’t specifically setup 2FA. So email is a very good way to nudge people into 2FA, and people are already used to this, as many online services now do it. Considering that the computer can now be remembered, I think it’s unlikely you’ll get any complaints from users. Setting up auto-enable is really simple. Grab the latest version of the TfaEmail module and install it. Then go to your ProcessLogin module settings (Modules > Configure > ProcessLogin) and you’ll see an option there to select Email in the “Force two-factor authentication - Type” field. If you want to limit this to specific roles, then you can also do that here. If you don’t select any roles, then it applies to all roles. Once setup, any user logging into your admin will be asked to enter an authentication code sent to their email, and they’ll need that code to complete the login. Chances are they’ll also click that “remember this computer” checkbox so that they can skip the code on future logins. TfaEmail version 2 The new version of the TfaEmail module also lets you now configure what WireMail module you want it to use for sending authentication emails. If using multiple mail sending services, you’ll want your most reliable and fastest email sending service to handle these kinds of transactional emails. TfaTotp version 4 Once users understand the benefits of 2FA, chances are they’ll want to upgrade to TOTP, where they can use a dedicated authenticator app. The ProcessWire TfaTotp module got several upgrades this week. The biggest was the addition of a locally hosted QR code generator (QRCode for PHP by Kazuhiko Arase). No longer does it have to rely upon an external service to generate QR codes (previous versions used Google Charts for QR code generation). In addition, the TOTP TwoFactorAuth library has been updated to the latest version. Moving those modules to the core Speaking of those two modules (TfaEmail and TfaTotp), thanks for your input last week about their inclusion in the core. It sounds like most think it’s a good idea, so I think we’ll go that route. But I need a little more time to do that, so going to hold that update and the 3.0.160 version bump for next week. Coming next week: Useful new selector operators Next week I’ve also got a couple of special new text-matching operators being added to our selectors system that I think you are going to really like. They are operators that are especially useful to those building text search engines, and ones that I’ve found so useful this week that I wish we’d had them since the beginning. I’m excited to add those into 3.0.160 and tell you more about them next week. By the way, while 3.0.160 isn't officially the version on the dev branch yet, if you download the current dev branch version (3.0.159), all of the TFA updates mentioned above are present and ready to use.
  32. 4 points
    I know that headless cms has been a hot topic for a while. I've experimented with several frontend frameworks (Angular, React, Vue, etc) and I just don't get it. Maybe for huge corporations with multiple dev teams and big budgets, OK. For 95+% of use cases however, I find headless cms/js frontend to be a major pain with no discernible benefits. From a frontend web UX, they're often slower than a well built PW site with caching (eg ProCache). For native apps, something like api calls to/from PW/Dart via json would do the job. Am I missing something other than a desire for JS devs to earn extra $$$?
  33. 4 points
    Good article and postgresql looks interesting with its search capabilities, thanks. Though none of these really solve what I was after here. I experimented quite as bit with stemming and different stemming libraries. Though they all did roughly the same thing. When it came to searching, stemming just wasn’t that useful. WireWordTools originally had a stemming library and methods, and the appropriate fulltext queries included the word stems with wildcards. In the end, it just wasn’t helpful most of the time. And in the few cases where it was worthwhile, it was redundant, though far less thorough, than what we already had with inflection and lemmatisation. So while stemming can have its uses, it’s not even half way there, if trying to build a smart search. Cool nevertheless that they have it built-in apparently. As far as accent support, ranking and fuzzy search, these are all things that MySQL does as well, though maybe there are differences in how they do them. For instance, MySQL supports “sounds like” and also supports pluggable parsers for fulltext searches. Fuzzy search also isn't what I'm after here, but certainly interested in exploring in the future. For me the most useful thing by far is boolean mode searches, particularly in InnoDB, which has a full-text engine modeled on Sphinx. Boolean mode searches are really very powerful, enabling you to specify what’s required, what’s excluded, matching of words or phrases, partial matching of words with wildcards, specifying noise words, isolating distance between words, adjusting ranking up or down on a per-word basis, grouped expressions and nested subexpressions. All while being incredibly fast. I’m pretty thrilled with what MySQL supports here and what it brings to ProcessWire. Postgresql looks very nice too, but for our needs, I don’t feel we are lacking anything relative to it. I think anyone that would say that as a general thing is not very familiar with what MySQL fulltext supports, or maybe is thinking of fulltext support where it was back a long time ago. For ProcessWire and the scale that most use it at, MySQL fulltext is really a sweet spot, enabling PW to deliver enormous power and capability when it comes to search features.
  34. 4 points
    Another approach to try: // Store page changes in custom property on $wire $wire->addHookAfter('Page(template=contact|sample)::changed', function(HookEvent $event) { $page = $event->object; $what = $event->arguments(0); $old = $event->arguments(1); $new = $event->arguments(2); $page_changes = $event->wire('page_changes') ?: []; $page_changes[$page->id][$what] = [ 'old' => $old, 'new' => $new, ]; $event->wire('page_changes', $page_changes); }); // Send email if there are page changes after the request is finished $wire->addHookAfter('ProcessWire::finished', function(HookEvent $event) { $page_changes = $event->wire('page_changes'); if($page_changes) { // Send the email using the values in $page_changes ... } });
  35. 4 points
    If you're dealing with multiple timezones I'd strongly suggest not involving the db in it. There are two types of datetimes: absolute time (times you want to compare with each other even across timezones) and wall time (11 o'clock stays 11 o'clock for your user). Because timezone defintions can potentially change for future datetimes it's not always as easy to keep both properties as one might think. If only the first one is important to you you should keep everything in UTC. If only the last one is important you could use a datetime in the timezone of the user, but it's rarely the case you don't compare timestamps or it doesn't become a requirement (e.g. for ordering). For past datetimes it's enough to store a utc timestamp and the timezone of the user to get to both the absolute time and the wall time as timezone defintions rarely change in retrospect. For future datetimes you'd need to make sure to save enough information so you can detect changes in the timezone definition when they happen. Then you or your user can decide if absolute time or wall time was meant to be consistent.
  36. 4 points
    @bernhard I didn't come up with the dictionary words in the JSON files, they are converted from an existing one (here) and apparently the original source is wordnet.princeton.edu. So I'm not sure if those particular words are intended or mistakes. New to me, but "wa" and "wo" are actual English words. Though as far as I can tell they aren't related to "was" or "will". I can't imagine those two instances will ever be helpful for our intended use case so maybe it makes sense to remove them. My plan was to keep looking for more existing dictionaries and continue to merge them into the one in WireWordTools so that it becomes more comprehensive over time.
  37. 4 points
    Thanks for your contributions to the community 😄 Good luck in all that you do - we'll see you around pwFoo 🙂
  38. 4 points
  39. 4 points
    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 🙂
  40. 4 points
    /** @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);
  41. 4 points
    I know you asked for a configuration but, maybe hook here? <?php $wire->addHookAfter('ProcessPageAdd::getAllowedTemplates', function($e){ $templates = $e->return; $specialTemplate = wire('template')->get('specialOne'); $parent = $pages->get(wire('input')->get->parent_id); if($parent->template != "sub"){ unset($specialTemplate->id, $templates); $e->return = $templates; } });
  42. 4 points
    There have actually been quite a lot of issues. Ryan has fixed several of them, but there are still some outstanding issues and I expect more will continue to surface and AFAIK Ryan still hasn't upgraded his dev environment so he's not seeing them and not being able to replicate so there has been some guesswork and back and forward with me on them. That said, I do have several sites running on MySQL 8 / MariaDB 10 so I am reporting new things as they come up. Not ideal, but hopefully they'll all be sorted sooner than later. However if I were you, I wouldn't upgrade yet.
  43. 4 points
    Just check the user role 😉 https://processwire.com/docs/user-access/roles/ or change the permissions to your post page in the Admin Panel (or both!) https://processwire.com/docs/user-access/permissions/
  44. 4 points
    Thanks for the reply teppo! You're right, i definitely should use php 7.3, I also tried that. I just developed the site on php 5.x and wanted to keep the settings as similar as possible. I'm talking to the namecheap support right now, if I can solve the issue with them I will post it here for future reference.
  45. 4 points
    This suggests that the query string does not receive the search string but an object of type WireInputData instead. WireInputData is the class behind the WireInput properties $input->get, $input->post, and so on. $q = $sanitizer->selectorValue($input->get); $input->whitelist('q', $q); Here you put the $input->get object of type WireInputData into a sanitizer method. The method only accepts strings and arrays. Since you gave it neither, it makes a string out of it. I guess this turns the WireInputData object into the string "WireInputData". Not sure what the right fix is. What is “q” supposed to be? It looks more like the query string you want is something like “?larghezze=123&lunghezze=456”. So you should put each of those into a separate whitelist item, eg. $input->whitelist('larghezze', $input->get->selectorValue('larghezze')). ProcessWire’s pagination will automatically put everything from $input->whitelist in the url query string. if($input->whitelist->lunghezze) echo $sanitizer->entities($input->whitelist->lunghezze); if($input->get->lunghezze) echo ($input->get->lunghezze); //delete this! Here you output lunghezze twice, only the first line doesn’t work, because you never put anything into $input->whitelist->lunghezze. Also, the whitelist is stored on the server and you’re expected to only fill it with things you already sanitized, so there is no need to sanitize it again at that point. In the second line you output untrusted unsanitized input straight from the GET request! You should delete that line and the others like it. They’re unnecessary anyway, because you already output the whitelisted stuff above 🙂 Change it to this: echo $input->whitelist->lunghezze; That should be all you need. Then, in search_alimentare.php, add the line I highlighted: if ($input->get->lunghezze) { $lunghezza = $sanitizer->selectorValue($input->get->lunghezze); $input->whitelist->lunghezze = $lunghezza; //add this line for each get variable $tolleranza = ($percentuale / 100) * $lunghezza; $val_up = $lunghezza + $tolleranza; $val_down = $lunghezza - $tolleranza; $selector .= "variante_prodotto.lunghezza>=$val_down, "; $selector .= "variante_prodotto.lunghezza<=$val_up, "; } Sorry I’m being so incoherent 👀
  46. 4 points
    BETA: SplashAndGrab https://github.com/madebymats/InputfieldSplashAndGrab This module attaches a search input to selected image fields that lets you search and download images from Unsplash. (Unsplash is a stock photo service where you can download images for free and use as you wish. No strings attached.) You can search by string, colors, orientation/crop and order by relevance or time published I find Unsplash useful both for placeholder images when building sites but also as a time saver for editors if they don’t have any images at hand, just search, download and publish. Thanks to @apeisa for building the FlickrInputField Module and @Robin S for AddImageUrls, took a lot ideas and code from those modules.
  47. 4 points
    There's no need at all to understand the PW architecture or database structure and relations - or even to think about these things. Stick to using PW selectors (https://processwire.com/docs/selectors/) and all the hard work is done for you. Selectors are one of the really great features of PW! (Note that if you later decide to use RockFinder for the extra speed, it also understands the PW database structure so that you don't have to.)
  48. 4 points
    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 😛
  49. 4 points
    RockFinder can massively reduce search times. I've used it to reduce complex searches from several seconds to fractions of a second. However, if your searches aren't too complex, even on a fairly large number of pages the difference could be between part of a second using PW selectors and a very small part of a second using RockFinder. This isn't really going to solve your problem. So I'd suggest sorting out the rendering first, as suggested by others, with RockFinder as a possible later refinement.
  50. 3 points
    @Kola - glad you figured it all out 🙂 The key thing here is that it's not really the ASMSelect inputfield, but rather the Page Reference fieldtype that's behind it - because you have that set to store multiple values you need to use the add() method. Same would go for checkboxes etc.
  • Create New...