Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/16/2023 in all areas

  1. A search/filter via Vue or alpine js with browser history would surely help here. And/or showing the recipes in a modal could also help for quickly navigating between recipes. I'd opt for PR to that same recipe. There's no need to keep around old outdated versions if improved ones exist. I think we can discard recipes for 2.x. But versioning for 3.x would be good because for some API methods we need a min version
    3 points
  2. Very nice! ?? (https://processwire.recipes/code-of-conduct/)
    3 points
  3. I think maybe both variants should be in the same recipe. I am talking about the recipe creating a page via api. The published method is still viable, but there is also pages->new with a much simpler one argument syntax. So neither is right or wrong, better or badder, but a matter of choice.
    2 points
  4. It's pretty straight forward. Instead of defining textual options, you create a page for every selectable option. Preferably, you group them under their own parent, and you'll usually want to assign them their own template, both to make queries easier and so you can add more fields to the template later. In your case, you can start with a (backend-)template "region", no need to add a PHP template file since the region pages are only for filling the dropdown. You'll also want a template "regions" for the regions' parent page. This one will be the overview page you're trying to build and therefore need a PHP template. In the first step, just create both templates with the minimum fields PW suggests (i.e. just a "title" field which will be the label in your dropdown). Then create the pages. Home - Regions - - Region 1 - - Region 2 - - ... In your hotel template, add a page reference field for the region, and on the "Input" tab in the field's configuration, go to "Selectable pages". Under "Templates", select "region". Edit your hotels and assign a region to each. Now you can easily iterate over all available regions in your regions.php template file, output the region's details and a list with the hotels for that region. A little PHP snippet as a starting point: <?php namespace ProcessWire; foreach($page->children() as $region) { echo "<h3>{$region->title}<h3>"; echo "<ul>"; $hotels = $pages->find("parent=/hotels/, region=$region"); foreach($hotels as $hotel) { echo "<li><a href='{$hotel->url}'>{$hotel->title}</a></li>"; } echo "</ul>"; }
    2 points
  5. I have just released version 2 of RockMigrations: GitHub: https://github.com/baumrock/RockMigrations Modules Directory: https://processwire.com/modules/rock-migrations/ Please star the module on GitHub if you like it ? Are you unsure if RockMigrations is the right tool for you? @Jonathan Lahijani in a very nice PM ? Read the full post here Read the full post here Read the full post here QuickStart The example code uses bd() calls for dumping data. You need TracyDebugger installed! Put this in your site/migrate.php /** @var RockMigrations $rm */ $rm = $modules->get("RockMigrations"); bd('Create field + template via RM'); $rm->createField('demo', 'text', [ 'label' => 'My demo field', 'tags' => 'RMDemo', ]); $rm->createTemplate('demo', [ 'fields' => [ 'title', 'demo', ], 'tags' => 'RMDemo', ]); Reload your site and you will see the new field and template in the backend and you'll see the message in the tracy debug bar.
    1 point
  6. I oftentimes create a checkbox field called 'test' and assign it to certain templates. I check the box if the page is a test page. These pages may exist on the live site and I don't want to hide or unpublish them, but at the same time, I don't want them to appear in the XML Sitemap. (not part of this tutorial, but I also noindex,nofollow those pages using a meta tag in the head so search engines don't index them) In that case, you can remove them from the WireSitemapXML like this in /site/ready.php: $wire->addHookAfter('WireSitemapXML::allowPage', function(HookEvent $event) { $page = $event->arguments('page'); if($page->hasField('test') && $page->test) $event->return = false; });
    1 point
  7. I've been working with ProcessWire for a while now, and I've noticed that using Composer to manage dependencies and autoload external libraries isn't as prevalent in ProcessWire development as in other areas of PHP programming. I started out by using the default setup recommend in this blogpost. However, one major problem I have with this approach is that all external dependencies live in the webroot (the directory the server points to), which is unfavourable from a security standpoint and, in my opinion, just feels a bit messy. In this tutorial, I want to go through a quick setup of Composer and ProcessWire that keeps the dependencies, all custom-written code and other source material outside of the webroot, and makes full usage of the Composer autoloader. This setup is pretty basic, so this tutorial is probably more useful to beginners (this is why I'll also include some general information on Composer), but hopefully everyone can take something away from this for their personal workflow. Site structure after setup This is what the directory structure can look like after the setup: . ├── composer.json ├── composer.lock ├── node_modules │ └── ... ├── public │ ├── index.php │ ├── site │ ├── wire │ └── ... ├── packacke-lock.json ├── package.json ├── sass │ ├── main.scss │ ├── _variables.scss │ └── ... ├── src │ ├── ContentBag.php │ └── ... └── vendor ├── autoload.php ├── composer ├── league ├── symfony └── ... As mentioned, the main point of this setup is to keep all external libraries, all other custom source code and resources out of the webroot. That includes Composer's vendor folder, your node_modules and JavaScript source folder if you are compiling JavaScript with webpack or something similar and including external scripts via NPM, or your CSS preprocessor files if you are using SASS or LESS. In this setup, the public directory acts as the webroot (the directory that is used as the entry point by the server, DocumentRoot in the Apache configuration). So all other files and directories in the mysite folder aren't accessible over the web, even if something goes wrong. One caveat of this setup is that it's not possible to install ProcessWire modules through Composer using the PW Module Installer (see Blogpost above), but that's just a minor inconvenience in my experience. Installation You'll need to have composer installed on your system for this. Installation guides can be found on getcomposer.org. First, open up your shell and navigate to the mysite folder. $ cd /path/to/mysite/ Now, we'll initialize a new Composer project: $ composer init The CLI will ask some questions about your projects. Some hints if you are unsure how to answer the prompts: Package names are in the format <vendor>/<project>, where vendor is your developer handle. I use my Github account, so I'll put moritzlost/mysite (all lowercase). Project type is project if you are creating a website. Author should be in the format Name <email>. Minimum Stability: I prefer stable, this way you only get stable versions of dependencies. License will be proprietary unless you plan on sharing your code under a FOSS license. Answer no to the interactive dependencies prompts. This creates the composer.json file, which will be used to keep track of your dependencies. For now, you only need to run the composer install command to initialize the vendor directory and the autoloader: $ composer install Now it's time to download and install ProcessWire into the public directory: $ git clone https://github.com/processwire/processwire public If you don't use git, you can also download ProcessWire manually. I like to clean up the directory after that: $ cd public $ rm -r .git .gitattributes .gitignore CONTRIBUTING.md LICENSE.TXT README.md Now, setup your development server to point to the /path/to/mysite/public/ directory (mind the public/ at the end!) and install ProcessWire normally. Including & using the autoloader With ProcessWire installed, we need to include the composer autoloader. If you check ProcessWire's index.php file, you'll see that it tries to include the autoloader if present. However, this assumes the vendor folder is inside the webroot, so it won't work in our case. One good place to include the autoloader is using a site hook file. We need the autoloader as early as possible, so we'll use init.php: EDIT: As @horst pointed out, it's much better to put this code inside the config.php file instead, as the autoloader will be included much earlier: // public/site/config.php <?php namespace Processwire; require '../../vendor/autoload.php'; The following also doesn't apply when including the autoloader in the config-file. This has one caveat: Since this file is executed by ProcessWire after all modules had their init methods called, the autoloader will not be available in those. I haven't come across a case where I needed it this early so far; however, if you really need to include the autoloader earlier than that, you could just edit the lines in the index.php file linked above to include the correct autoloader path. In this case, make sure not to overwrite this when you update the core! Now we can finally include external libraries and use them in our code without hassle! I'll give you an example. For one project, I needed to parse URLs and check some properties of the path, host et c. I could use parse_url, however that has a couple of downsides (specifically, it doesn't throw exceptions, but just fails silently). Since I didn't want to write a huge error-prone regex myself, I looked for a package that would help me out. I decided to use this URI parser, since it's included in the PHP League directory, which generally stands for high quality. First, install the dependency (from the project root, the folder your composer.json file lives in): $ composer require league/uri-parser This will download the package into your vendor directory and refresh the autoloader. Now you can just use the package in your own code, and composer will autoload the required class files: // public/site/templates/basic-page.php <?php namespace Processwire; use \League\Uri\Parser; // ... if ($url = $page->get('url')) { $parser = new Parser(); $parsed_url = $parser->parse($url); // do stuff with $parsed_url ... } Wiring up custom classes and code Another topic that I find really useful but often gets overlooked in Composer tutorials is the ability to wire up your own namespace to a folder. So if you want to write some object-oriented code outside of your template files, this gives you an easy way to autoload those using Composer as well. If you look at the tree above, you'll see there's a src/ directory inside the project root, and a ContentBag.php file inside. I want to connect classes in this directory with a custom namespace to be able to have them autoloaded when I use them in my templates. To do this, you need to edit your composer.json file: { "name": "moritzlost/mysite", "type": "project", "license": "proprietary", "authors": [ { "name": "Moritz L'Hoest", "email": "info@herebedragons.world" } ], "minimum-stability": "stable", "require": {}, "autoload": { "psr-4": { "MoritzLost\\MySite\\": "src/" } } } Most of this stuff was added during initialization, for now take note of the autoload information. The syntax is a bit tricky, since you have to escape the namespace seperator (backslash) with another backslash (see the documentation for more information). Also note the PSR-4 key, since that's the standard I use to namespace my classes. The line "MoritzLost\\MySite\\": "src/" tells Composer to look for classes under the namespace \MoritzLost\MySite\ in the src/ directory in my project root. After adding the autoload information, you have to tell composer to refresh the autoloader information: $ composer dump-autoload Now I'm ready to use my classes in my templates. So, if I have this file: // src/ContentBag.php <?php namespace MoritzLost\MySite; class ContentBag { // class stuff } I can now use the ContentBag class freely in my templates without having to include those files manually: // public/site/templates/home.php <?php namespace Processwire; use MoritzLost\MySite\ContentBag; $contentbag = new ContentBag(); // do stuff with contentbag ... Awesome! By the way, in PSR-4, sub-namespaces correspond to folders, so I can put the class MoritzLost\MySite\Stuff\SomeStuff in src/Stuff/SomeStuff.php and it will get autoloaded as well. If you have a lot of classes, you can group them this way. Conclusion With this setup, you are following secure practices and have much flexibility over what you want to include in your project. For example, you can just as well initialize a JavaScript project by typing npm init in the project root. You can also start tracking the source code of your project inside your src/ directory independently of the ProcessWire installation. All in all, you have good seperation of concerns between ProcessWire, external dependencies, your templates and your OOP-code, as well as another level of security should your Server or CGI-handler ever go AWOL. You can also build upon this approach. For example, it's good practice to keep credentials for your database outside the webroot. So you could modify the public/site/config.php file to include a config or .env file in your project root and read the database credentials from there. Anyway, that's the setup I came up with. I'm sure it's not perfect yet; also this tutorial is probably missing some information or isn't detailed enough in some areas depending on your level of experience. Feel free to ask for clarification, and to point out the things I got wrong. I like to learn as well ? Thanks for making it all the way to the bottom. Cheers!
    1 point
  8. Personally I would consider an alternative approach, having this auth form as a separate page that you pass the original page to. This way you could have it as a separate entity, but still have access to anything that the original page contains. In this scenario you could have the original page fetch and then render the authorization form page, and return rendered content from there, instead of content of its own. Though of course I may be missing plenty of nuance in your use case ? In case it makes more sense, it is also possible to set/override the controller for a page (by calling $page->setController('TemplateName')) just like it is possible to set/override layout or view. Technically this might mean that while rendering a page you detect this situation and then re-render the same page with different controller. Feels a little odd, and I'm not entirely certain that it'll work, but I can't see why it wouldn't either.
    1 point
  9. We're using a similar approach: install ProcessWire via Composer and then use post-install-cmd and post-update-cmd to copy the wire folder from vendor to web root. It would be preferable not to have to do the whole post-[install/update]-cmd step (or have entire wire directory in public directory for that matter) but to be honest this works quite well. Some files in wire need to be web accessible, so I'm not aware of any clean way around this. To be clear this is about installing and/or updating ProcessWire on a site that has already been set up. As for setting up a complete, new ProcessWire setup via Composer... I've no experience about that. Technically you could install ProcessWire via Composer and then copy everything from vendor/processwire/processwire/ to your web root, but for my use cases that has never really made sense ?
    1 point
  10. https://github.com/elabx/FieldtypeRecurringDates Well a few summers later, finally got like a sort of working version. For info please take a look at the repo's readme. It's still super alpha but going to deploy into a couple websites to replace Recurme so wish me luck. This module is only a Fieldtype and Inputfield, there are no "markup" modules as there used to be in Recurme. I'd appreciate any testing or any kind of comments.
    1 point
  11. I also sort of have this scenario and decided to use separate Time fields to indicate start and end time of each occurrence. I just have to assume that the occurrences have the same time.
    1 point
  12. @eydun Yeah, I don't think this has ever been tested or officially supported. It will definitely not work out of the box, as ProcessWire expects a specific folder structure and doesn't work if it's placed in the vendor folder. Not sure why this is even in the docs.
    1 point
  13. @ryan Are you using this in your tool chain? If so, could you update the repo with any additional tests you've added, like the subfield test you mentioned above? Thanks.
    1 point
  14. Allow me to answer myself. Very sneakily the hidden `Advanced SMTP` had the `Authentication Mechanism` set to `password`. Removing this solved the issue.
    1 point
  15. The reason why I am asking for the release of v008 is because as the initial select I want to display a list of images instead of the title. Is this possible with v007?
    1 point
  16. @wbmnfktr Here are some thoughts for improvement and a question: A search function is missing. Would be great if it could be integrated. There are search functions that work with html elements, like Search, sort, filters, flexibility to tables, list and more! - List.js (listjs.com) but this solution would only work if all recipes are on one page, as it is right now. Going forth and back to see different recipes is not good for the eyes, because of the steady switch of backgrounds. I think it is better if you remove the blue background on the homepage and maybe add some shadows to the recipe cards then. It would be nice, if you can quickly navigate from one recipe to others. There are several ways this could be done. A search function would be one option, or an iframe as a sidebar with all recipes. How can I improve a recipe because there are better (newer) methods to accomplish the same? Create a PR for that recipe? Or create a new recipe with the same title with the improved method? There should be a ProcessWire version field, so someone knows that one method only works with a specific version of PW.
    1 point
  17. Was version 008 ever released? I bought this module some days ago, and received version 007 (codename James Bond).
    1 point
  18. First of all, thanks for your work on this! You mean all four repos? I starred them all. Another question: maybe I'm blind a bit, but I cannot find any search function on the site. We can always use Google, like https://www.google.hu/search?q=hook+site%3Aprocesswire.recipes but Google might not be always up-to-date for a while, I guess.
    1 point
  19. So... you might have noticed that there was another/new release on processwire.recipes. A few things were added, removed, updated... and... so... on. Latest major updates are listed on the changelog page. (which is a new addition on its own) I added a CoC (Code of Conduct) page, legal details were updated, an upcoming section and a small UI update was there in between as well. AND... please ⭐ Star this repo on Github I'm happy to have your feedback!
    1 point
  20. Thank you so much. I really hope and wish we all can achieve some kind of an awesome hub for newcomers and even long-time users. This would be great. Just pushed another UI update. Still not perfect but at least that issue should be gone for now. Would appreciate your feedback on the latest update.
    1 point
  21. Thanks for the tip about composer scripts, that might come handy when setting up new processwire-installations. The docs mention: composer require processwire/processwire as a possible installation method: https://processwire.com/docs/start/install/new/#installation-with-composer-and-packagist But I guess that is not feasible...
    1 point
  22. In the past I had used the old version of RockMigrations for some simple tasks like adding fields and templates which turned out to be huge time saver. But only just recently I started to use the new version and to discover the possibilities of this tool in more depths. And what should I say, I am really amazed. Once I had grasped the core concepts and, with @bernhard's help, had learned how to use it in a more structured way and in different contexts, it turned out to to be an even bigger time saver. I hate repetitive tasks. Adding fields and templates and fields to templates and configuring labels / access rights etc for fields in the template context in PW is a pleasure when using the GUI. But it is still a repetitive task. With RockMigrations I can have definitions of these fields / templates and fields in template context in a single file and reuse that. In a matter of seconds I have my reusable base structure available to start off a new project. Adding new structure through the GUI in a staging environment and then having to replicate it on the live sytem through the GUI. Repetitive task again. Pushing a migration file to the live system and running the migration. Again in a matter of seconds. Writing migrations wherever I want is also a great feature. Be it inside site/migrate.php or inside a newly developed module, it doesn't matter. RockMigrations will find it and do its job. At the beginning I wasn't sure how to define different field types with all their different properties. RockMigrations comes with VSCode snippets that make things easy. Or you can create a field in the GUI and then just copy/paste the code for the migration from the GUI to your migration logic. So however you prefer to create your fields, RockMigrations has you covered. This post may sound like an advertisement. But I just wanted to express how happy I am after having made the decision to spend some time to learn how to work with this module. That time was definitely well spent. Big thanks to Bernhard for creating this and releasing it as a free module.
    1 point
  23. Hi @Maverick. Thanks for you custom. Currently, not out of the box. but should be very easy to achieve using your own JavaScript. It would go something like this Render your DynamicSelects form Next to it, in your template file, add your Go button or link Using JavaScript (e.g. jQuery) disable that button or link Once a 'last' selection is made, using JavaScript, change the value of your Go button/link to the URL of the last selection. For instance, if a link, we would change its href. On click, the user gets redirected to the selected 'URL'. Initially, I was thinking the developer could build in the 'URL' themselves, i.e. build it client-side using JavaScript, from the select option's label. For instance, if we have a city Berlin, we would build our ProcessWire URL off that. But that is not very friendly. I think it will be better if a I added a third $options argument to MarkupDynamicSelect's render() method. You can then specify what extra info for the results to return, e.g. url was passed in the options, it would result in: <select> <option value='1234' data-url='/continent/country/city-page-1/'>City 1</option> <option value='1235' data-url='/continent/country/city-page-2/'>City 2</option> <option value='1236' data-url='/continent/country/city-page-3/'>City 3</option> </select> You would then grab the selected option's data-parameter, e.g. in the case above, data-url, and do whatever you want with it. Is there any other value you think would be useful to return other than url? i.e. what other data-xxx would be useful? Thanks.
    1 point
  24. Here comes a small Christmas Present Go to setup > templates or setup > fields and find 2 important (or exportant) buttons below the list in the right corner to go here:
    1 point
  25. This module adds basic capability to restrict page rendering to selected number of IP addresses. Note: this is only meant to be used as an additional security measure in addition to typical username/password authentication or something similar, not on it's own! Currently individual IPs (127.0.0.1), IP ranges (127.0.0.1-127.0.0.255) and CIDR format (127.0.0.0/24) are supported. You can also decide whether restrictions should apply to a) admin area and b) authenticated users. By combining these two options you could create a site with public access restricted to selected IPs while still allowing users outside those addresses to have full access after authenticating. Better description can be found from README. And once again: all comments, bug reports, feature suggestions etc. are more than welcome! So far everything seems to work as planned, but I haven't had the chance to test this nearly as thoroughly as I'd like (that's also why this little cutie is flagged "Beta" in the modules directory..) https://github.com/t...erIPRestriction http://modules.proce...-iprestriction/ How to install Copy PageRenderIPRestriction folder to your /site/modules/, go to Admin > Modules, hit "Check for new modules" and install Page Render IP Restriction. That's it. How to use Default out-of-the-box settings don't introduce any restrictions. You can edit module settings (Admin > Modules > Page Render IP Restriction) to include those IPs you wish to allow access to your site for. Once you've filled in at least one IP address and saved module settings restriction will be immediately effective. Please note that if you fill in at least one IP address and check both "Restrict admin access" and "Restrict access for authenticated users" you will no longer be able to reach Admin without valid IP. Make sure that you've tested everything properly before turning those options on (and avoid turning them on at all unless you're 100% sure that you know what you're doing)
    1 point
×
×
  • Create New...