Jump to content

Leaderboard

Popular Content

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

  1. Using those aliases for DDEV, Git, RockShell makes the first 2.5 minutes kind of... blurry or a blackbox or something. Even though I know how to install ProcessWire with a custom site profile I had to watch it a few times to understand whats happening. While I use DDEV, I use way different aliases, i don't use RockShell, and so on. It felt a bit like installing Laravel or CraftCMS to me - so many different moving bits and I don't know or can't really follow as I don't have or use the tools and can't see what really happens. As mentioned elsewhere: I love the fact ProcessWire has still ZIP files and don't relies on composer to install something. It would have been nice to see a slide with the full DDEV command, a screen with the Github page and URL to see where I can get the profile as ZIP. After that I would have preferred to see a full clean install with unzipping a site profile, dragging it into the docroot, and go from there. If I were new to ProcessWire this would have freaked me out in terms of: that's a lot of hoops I have to jump through.
    2 points
  2. Meta are disabling the Instagram Basic Display API on December 4th, 2024. After this point, the InstagramBasicDisplayApi module will no longer function. Meta do provide an API that can be used to access Instagram media, Instagram API with Instagram Login. Using this API I've been able to refactor InstagramBasicDisplayApi as a new module called InstagramMediaDisplay: https://github.com/nbcommunication/InstagramMediaDisplay The main caveat with using this module (and API) is that personal and/or private accounts cannot be used. If you try to generate an access token for a personal account, IG will prompt you to upgrade to a business account. As far as I'm aware this is still a free account, and the main limitation is that you cannot use licensed music in the same way you can on a personal account. I have access to various IG accounts, some personal, some business, and I've never noticed a difference. This new module is built to supersede InstagramBasicDisplayApi and its implementation is practically identical. Upgrading should simply be a case of installing, configuring your new Meta app, authorising the same account(s), and updating the call to the previous module to call this one: <?php // $instagram = $modules->get('InstagramBasicDisplayApi'); $instagram = $modules->get('InstagramMediaDisplay'); Cheers, Chris
    1 point
  3. This module allows you to add Cloudflare's Turnstile CAPTCHA to your website, providing a user-friendly alternative to Google's reCAPTCHA. It is based on MarkupGoogleRecaptcha, allowing for easy switching between the two CAPTCHA systems. If MarkupGoogleRecaptcha is installed, some of its settings are used to configure Turnstile. https://github.com/nbcommunication/MarkupCloudflareTurnstile We've used reCAPTCHA for many years now but have found that it isn't as effective as it should be in reducing spam. It is also pretty annoying. We've recently switched a couple of our 'bigger' sites to use Turnstile (using this module) as the sites were on Cloudflare already. It is definitely a much friendlier captcha for users, still to determine whether it is better at preventing spam, but I expect it will be. Cheers, Chris
    1 point
  4. Here you go @FireWire thx for your suggestion! Please check out v1.1.1 Now that I tried the different sort settings I must say that sorting by name rather than by group feels better, so I made that the new default 🙂 See the selected icon and the one to the right - same name, different group (filled/outline)
    1 point
  5. This should change nothing for the API, field is not editable in admin pages but from the API you can edit it.
    1 point
  6. Thank you all for the help. In the end it was two things: field was not editable the second was a silly mistake of creating the tag pages as template = content-tags, instead of content-tag Can confirm up and working correctly now. The silliest things seem to be the biggest time sucker 🤣
    1 point
  7. So... I just used this module in ProcessWire 3.0.241 and it works just perfect. Yet the above statement seems to be not correct anymore. Opened up some pages and I find a truck load of new empty directories in /site/assets/files/ again. Is it because the image field of those pages has a fallback image defined or did the default behaviour in ProcessWire change in those regards in the last 12 years? Wouldn't consider this as a bug. Just curious.
    1 point
  8. Just added docs to https://www.baumrock.com/en/processwire/modules/rockcolorpicker/docs/ with lots of examples and added some minor improvements 🙂
    1 point
  9. If the question was never asked, I wouldn't have wondered. I do agree that if I discovered that a competing, comparable product was used instead of PW (such as WordPress) I'd be dismayed, but when the technical demands are different and a familiar tool seems like a better fit - no, I think that a lot of the decisions with ProcessWire is that simpler is often better and not to overcomplicate things: use the tool that you're familiar with that fits the solution best. If server costs were a concern and your home internet is stable enough, you could run a Raspberry Pi (5) as a webserver to run PW and MySQL inside of a Docker container and merge the backend with the frontend as flydev suggested. That seems like overkill simply to involve PW though? If there was a technical reason to use PW in the mix beyond what is currently offered, then that would be the time to do so!
    1 point
  10. These videos are so much work 🙈 I have tried a different software and a different technique. What do you think?
    1 point
  11. It depends on what you want to achieve but basically with lazycron you specify a time interval target and whenever someone loads a page the lazycron checks if the interval has passed and then triggers its function. This means that depending on where you put the hook, it may check more often or not: if you put the code in a template, then the lazycron is checked only when a guest is visiting a page with this template. However if you put the hook in init.php (or ready.php) then the lazycron will be checked for every pageview, even the admin ones.
    1 point
  12. 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/
    1 point
  13. Hello @Stefanowitsch I have updated the module and it should work now as expected. I have not the time to test all possible scenarios now, but I could not discover any problems on my local setup. For more information about the problem read the changelog.md. Please test it, if it works for you now. Best regards Jürgen
    1 point
  14. Since ProcessWire v3.0.152 we have been able to use custom Page classes: https://processwire.com/blog/posts/pw-3.0.152/#new-ability-to-specify-custom-page-classes Some PW users have said that they would like to have all their hooks relating to a particular Page class contained within their custom Page class file (in /site/classes/), to keep things tidy and organised. But custom Page classes do not have methods that fire on states like "init" or "ready", and it also wouldn't be ideal to attach hooks within a Page class because the class can be instantiated multiple times and therefore such hooks would be attached multiple times. I understand @bernhard has a feature that addresses this need built into his RockMigrations module, so check that out. And here's another approach, where hooks are attached in the places where you would normally attach them (e.g. in /site/ready.php or /site/init.php, or in the init() or ready() methods of some custom module) but the method that executes in the hook exists within your custom Page classes. Step 1 In /site/classes/DefaultPage.php, add the method shown below: class DefaultPage extends Page { // Call any Page methods with names that match the HookEvent object and method public function callHookMethods(HookEvent $event) { $objectName = $event->object->className; $methodName = $objectName . '_' . $event->method; if(!method_exists($this, $methodName)) return; $this->$methodName($event); } } This method looks for other Page method names that match the HookEvent object and method and if any exist it calls them. Hooks are attached using the format "Class::method" and this format wouldn't be valid for a method name, so an underscore is used instead of the two colons. E.g. "ProcessPageEdit::buildFormContent" would become "ProcessPageEdit_buildFormContent". Step 2 In any of your custom Page class files, add methods named to match the hookable methods you want to target. These custom Page classes should extend DefaultPage. In the example below I'm targeting hookable methods Pages::saveReady and ProcessPageEdit::buildFormContent in the BasicPagePage class. class BasicPagePage extends DefaultPage { public function Pages_saveReady(HookEvent $event) { // Show a message in the PW admin $this->wire()->message("About to save page named: $this->name"); } public function ProcessPageEdit_buildFormContent(HookEvent $event) { /** @var InputfieldWrapper $wrapper */ $wrapper = $event->return; // Add a custom markup field to Page Edit /** @var InputfieldMarkup $f */ $f = $this->wire()->modules->get('InputfieldMarkup'); $f->label = 'My custom markup'; $f->value = 'Hello!'; $wrapper->insertAfter($f, 'title'); } } Step 3 Attach hooks in the places where you normally would. You need to attach a hook for each hookable method you are targeting in your custom Page classes, but the hook code itself is minimal and where multiple Page classes target the same hookable method you only need it attach it once. In the example below I'm attaching hooks in /site/ready.php. $pages->addHookAfter('saveReady', function(HookEvent $event) { /** @var DefaultPage $page */ $page = $event->arguments(0); if($page instanceof DefaultPage) $page->callHookMethods($event); }); $wire->addHookAfter('ProcessPageEdit::buildFormContent', function(HookEvent $event) { /** @var ProcessPageEdit $ppe */ $ppe = $event->object; /** @var DefaultPage $page */ $page = $ppe->getPage(); if($page instanceof DefaultPage) $page->callHookMethods($event); }); Each hook only need to establish a $page object (often this is available as an argument to the hookable method) and if it's an instance of DefaultPage then it simply calls $page->callHookMethods($event), and any relevant hook-targeting methods for that particular Page class will fire. Here's the result of my two hook-targeting methods in BasicPagePage.php when I save a page of this class in Page Edit:
    1 point
  15. Hi @Robin S. Please also take a look at my request "automatically call the init method on custom page classes" https://github.com/processwire/processwire-requests/issues/456 and maybe leave a thumbs up. Your method requires changes to /site/ready.php or /site/init.php files. I think self-initiating custom page files are way better, so for example, a blogPage.php custom page class file would automatically create all fields and provide custom methods like `localDate`. This way, you can simply copy the file to a new project, and everything will be set up automatically without needing additional changes to other files.
    1 point
  16. Is my 100th post I wanted to do something special. I edited a video, hope you like it Just for fun Edited: Now with subtitles
    1 point
×
×
  • Create New...