Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/19/2024 in all areas

  1. Search Corrections Suggests alternative words for a given input word. This can be useful in a website search feature where the given search term produces no results, but an alternative spelling or stem of the term may produce results. The module has two methods intended for public use: findSimilarWords(): this method suggests corrected spellings or similar alternatives for the given word based on words that exist in the website. stem(): this method returns the stem of the given word, which may give a full or partial match for a word within the website. The module doesn't dictate any particular way of using it in a website search feature, but one possible approach is as follows. If a search produces no matching pages you can take the search term (or if multiple terms, split and then loop over each term) and use the module methods to find alternative words and/or the stem word. Then automatically perform a new search using the alternative word(s), and show a notice to the user, e.g. Your search for "begining" produced no matches. Including results for "beginning" and "begin". findSimilarWords() This method creates a list of unique words (the "word list") that exist on the pages and fields that you define, and compares those words to a target word that you give it. The method returns an array of words that are sufficiently similar to the target word. For multi-language sites, the $user language determines which language populates the word list. Similarity The method ranks similar words by calculating the Levenshtein distance from the target word. Where several results have the same Levenshtein distance from the target word these are ordered so that results which have more letters in common with the target word at the start of the result word are higher in the order. Method arguments $target (string) The input word. $selector (string) A selector string to find the pages that the word list will be derived from. $fields (array) An array of field names that the word list will be derived from. $options (array) Optional: an array of options as described below. minWordLength (int) Words below this length will not be included in the word list. Default: 4 lengthRange (int) Words that are longer or shorter than the target word by more than this number will not be included in the word list. Default: 2 expire (int) The word list is cached for this number of seconds, to improve performance. Default: 3600 maxChangePercent (int) When the Levenshtein distance between a word and the target word is calculated, the distance is then converted into a percentage of changed letters relative to the target word. Words that have a higher percentage change than this value are not included in the results. Default: 50 insertionCost (int) This is an optional argument for the PHP levenshtein() function. See the docs for details. Default: 1 replacementCost (int) This is an optional argument for the PHP levenshtein() function. See the docs for details. Default: 1 deletionCost (int) This is an optional argument for the PHP levenshtein() function. See the docs for details. Default: 1 Example of use // The input word that may need correcting $target = 'dispraxia'; // Get the Search Corrections module $sc = $modules->get('SearchCorrections'); // Define a selector string to find the pages that the word list will be derived from $selector = "template=basic-page"; // Define an array of field names that the word list will be derived from $flds = ['title', 'body']; // Optional: override any of the default options $options = ['maxChangePercent' => 55]; // Get an array of similar words that exist in the pages/fields you defined // The return value is in the format $word => $levenshtein_distance $results = $sc->findSimilarWords($target, $selector, $flds, $options); Example result: stem() This method uses php-stemmer to return the stem of the given word. As an example, "fish" is the stem of "fishing", "fished", and "fisher". The returned stem may be the original given word in some cases. The stem is not necessarily a complete word, e.g. the stem of "argued" is "argu". If using the stem in a search you will probably want to use a selector operator that can match partial words. Method arguments $word (string) The input word. $language (string) Optional: the language name in English. The valid options are shown below. Default: english catalan danish dutch english finnish french german italian norwegian portuguese romanian russian spanish swedish Alternatively, you can use the ISO 639 language code for any of the above languages. Example of use // The input word $word = 'fishing'; // Get the Search Corrections module $sc = $modules->get('SearchCorrections'); // Get the stem of the word $stem = $sc->stem($word); https://github.com/Toutouwai/SearchCorrections https://processwire.com/modules/search-corrections/
    3 points
  2. AFAIK ProcessWire’s pagefileSecure feature only works on the page level. So when your page is viewable by guests, its files will be viewable as well. However, when pagefileSecure is active, all files should be routed through the hookable method ProcessPageView::___sendFile(). It’s a short little method you could hook to add your own logic. For example: $this->addHookBefore('ProcessPageView::sendFile(template=MY_SPECIAL_TEMPLATE)', function(HookEvent $event) { /** @var Page $page */ $page = $event->arguments(0); $filename = $event->arguments(1); if ($this->wire->user->isGuest()) throw new Wire404Exception('File not found', Wire404Exception::codeFile); });
    2 points
  3. Hey @Ivan Gretsky and @gebeer, Thanks for chiming in all sorted now - more below! True. Main issue for me is time 😁. I have the tenacity and the curiosity; just not the time to be fixing and fixing. It was a very pleasant experience. I tried it (installed it) but it just wasn't Omakub 😀. Apart from its awesome aesthetics, Omakub just feels snappier. So, I went back to Omakub + Ubuntu. This time, I brought a friend; Timeshift! I did a fresh install of Ubuntu, then added Omakub. After that I went crazy with Timeshift, creating snap shots after every little tinkering. So far so good - system is up to date and chugging away smoothly. Thanks again!
    2 points
  4. @SIERRA I use Google Cloud services for some things but I'm not really an expert on it. I can provide some information that I am familiar with but you'll need to do research to determine if it fits your needs. I built a module that interfaces with a Google service but it doesn't provide any special insights. I'll start off with the easy answers first. Yes. Fluency translates the content that you enter into ProcessWire into other languages using the third party service, then enters that translated content into ProcessWire which is then stored in your website's database. This is stored the same way as if you had manually entered the content in other languages yourself. Even if you translated content for your website and then uninstalled Fluency altogether your translated content is stored in ProcessWire and is yours to keep. Third party translation services almost always, as far as I've seen, charge by character count. This is because words and phrases may be different lengths in different languages. It's not really possible to guess ahead of time what your character count will be according to word count, the best way to determine that is to translate some content then check your Google Cloud account to see how many characters you have used and then come up with an estimate based on that information. See my note below on using Google's tools to estimate this. Yes. ProcessWire's language support adds tabs to each multi-language field. If you manually add content to the fields under each tab and don't use Fluency to perform translation then you will have not used any translation service credits. That said, consider the following: Here you can see that Fluency is set up with the "Translate to all languages" option configured. This means that if you have entered content in any language and click "Translate to all languages", Fluency will translate that content into all of the other languages and then replace anything that has been already been entered under other language tabs. This is intentional behavior. If you use this option and have already added content that you are satisfied with in another language, then clicking "Translate to all languages" may be unnecessary because it will translate your content and overwrite it anyway. I'm not able to tell you want to do and I don't want to be responsible for any charges that came about due to bad information on my part. Google provides plenty of information about how they charge for their services and I would just be doing the same research that you would need to do to fit your use case. Google has a pricing calculator that you can use to estimate costs for usage of any Google Cloud services, including translation. Here's the link to check it out. No. Their billing is based on services usage per month so you will only pay for what you use. There isn't really a service that exists, as far as I know of, that would charge a flat fee for "a website" because that could mean a very large website or a very small website. I'll make a couple of recommendations that may help you out in this situation. If this is for a client, then the costs of using third party services are what they are. You don't have control over pricing or how much they ultimately intend to use the service because this is content that they will provide. The estimated content range of 400,000 to 500,000 words is very wide and not accurate. That range is 20% and won't be accurate, especially considering that the charges are in characters and not words which each have different character counts . To put this into context, a quick search found that the average length of a novel is 40,000 to 70,000 words long. That means the difference between the two word counts in your case is anywhere from 1-2 entire books you'd find at a book store- that isn't trivial! The best idea is to work on getting accurate pricing is to try and get a much more accurate estimate on length of content. Book publishers would not accept a 100,000 give-or-take estimate from an author in how long a novel is because there are real costs involved, and the same would best be true in this case. Here's a few things that you may be able to do: If you have all of the content ahead of time, then get an accurate character count and pad it a little to get a price you can work with. If you have some of the content, but not all, take estimate the percentage that content is relative to the entire amount of content, get the character count, and multiply it. If you estimate that you have 10% of the content right now, get the character count and multiply that by 10, then add a little to be safe, and estimate your costs. If the website will list products, or blog posts, or something that repeats, estimate the amount of content for one and then multiply that by an estimate of the number of whatever will be repeated on the site. It's much easier to estimate the content for one item of many and then estimate the number of how many there will be. If you already have a few examples, get the character count for each and calculate the average before multiplying. Hope that helps. Just trying to offer some advice that may be useful.
    1 point
  5. Hi everybody, I have inherited the website of our dance association. We also use Process Wire with Recurme. I encountered a fatal error when updating from PHP7.4 to PHP8.3. I could fix it by fixing this function. I added the check "is numeric". Maybe it can be helpful for somebody else. public function ___formatDate($date = '', $format = 'U'){ // default to time() if($date === '' || $date === null){ $date = time(); } // date is integer set_error_handler(function() { /* ignoring e_warning on date fail */ }); if(is_numeric($date)){ $date = $date; } else if(strtotime($date)){ $date = strtotime($date); } else{ restore_error_handler(); return false; } return date($format, $date); } Best Regards Florian
    1 point
  6. Thanks, i sort of imagined that elasticsearch would be the solution. My case is a bit different I've got both misspelled words but also a mix of languages. A word can be very similar in another language but not directly misspelled. Interesting suggestions, nevertheless, thanks!
    1 point
  7. @joe_g, you might be interested in this recently released module:
    1 point
  8. Clickbait title aside, I recently found a cool new feature in PHP 8.1 and wanted to share it with you, in case you didn't know this either. Starting with PHP 8.1 you can write $this->method(...) (yes, that's the actual syntax, not a placeholder) to reference a method. I find this super convenient, especially for defining hooks. Plus the IDE can refactor this much better than the traditional [$this, 'method'] callback. <?php class MyModule { public function init() { $this->addHookAfter('ProcessPageView::finished', $this->doSomething(...)); } private function doSomething(HookEvent $event) { // TODO: something } }
    1 point
  9. Hi Ivan, I really appreciate your input and I'm very happy to see your interest in RM growing. Though I have some concerns about your suggestion. Not saying that are bad suggestions, I just try to be realistic. First of all: I'm really, really happy with RM and how it works right now. There has been a lot of refactoring from RM1 to RM2 and that has brought a lot of improvements to the module. The API is in my opinion quite easy and stable to use and the concepts have proven to be working. Second: It's a free module. I think it's one of the best and most powerful modules out there for PW and it can bring a HUGE value to your everyday work, especially if you work in a team or want or need more professional workflows with zero-downtime deployments on multiple environments etc.; I decided to release it for free, because I think this should be part of the core. It should be something that every developer can use to create great modules. To use it as a foundation for, eg quickly and easily create a blog module that creates all the necessary fields and templates that you get a one-click blog setup for ProcessWire. That's simply not possible to do with site profiles and it's simply a pain to do with the regular API. Unfortunately that did not happen. Quite the contrary. People complained about it being too complicated (and didn't even use the module once). And no one ever used RM to create something useful for the community as far as I know. I'm not complaining - it is like it is, but that's the context for the question you are asking. That said, back to topic: I've been talking with @gebeer about refactoring quite some time ago: --bernhard-- In the long term, however, I thought it might make sense to split the API. Similar to how the wire core is split into its own classes. $rockmigration->fields->create('foofield'); $rockmigration->templates->addField('foofield', 'bartemplate', afterfield: 'title'); $rockmigration->migrate([ ... ]); That would really be a completely different API... That means a mega breaking change. I don't know if it's worth it...... --gebeer-- In the long run it's not wrong because it brings more structure into the API. But I think the API is well usable as it is. But I'm still not sure if it would be better. I really like the simple API that is accessible via $rm: Also splitting the API brings in other problems. Many methods do something with two things, eg "addFieldToTemplate" - would that be $rm->fields->addToTemplate("myfield", "mytemplate") or would that be $rm->templates->addField("mytemplate", "myfield") ? I don't understand ? If you have specific ideas I'd be more than happy to hear them and think about how we can improve the module and/or the code quality.
    1 point
×
×
  • Create New...