Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 03/03/2025 in Posts

  1. Hello! I use .env files on every ProcessWire project to manage environment-specific configurations and settings. I've built a ProcessWire specific utility that makes using .env files a breeze. This post isn't intended to debate .env vs. config.php, use what you're comfortable with and prefer. That said, here are a few benefits to using .env files that may make it worth considering: Native support on web servers, including Apache, they are not served via http request by default True environment based secrets and settings management A standard file widely used and accepted as the method for managing secrets and sensitive values Able to store any value whether sensitive or not and access them globally Building a dedicated solution came from a discussion here on the forums where I threw together a rough implementation that needed little polish for real world use. It makes use of phpdotenv. This utility delivers the following: Easy use of and access to .env variables Caching the parsed .env for performance. This is a significant part of this utility and addresses a known need Automatic .env change recognition and re-caching Utilities to make working with environment variables feel ProcessWire native and a few extra nifty things What it isn't: A module. It's not possible to make a module for this need because the information kept in a .env file needs to be available before ProcessWire boots. Adding this to a new or existing project is very easy. It's designed to implement quickly and use immediately in your projects. Full documentation is provided in the Github repository. Here are a few examples of using this tool: <?php namespace ProcessWire; use Env\Env; if(!defined("PROCESSWIRE")) die(); $env = Env::load(__DIR__ . '/../'); // Make env available throughout the application $config->env = $env; $config->dbName = $env->get('DB_NAME'); $config->dbUser = $env->get('DB_USER'); $config->dbPass = $env->get('DB_PASS'); // Env::get() takes a second argument that is the fallback value if for any reason DEBUG doesn't exist $config->debug = $env->get('DEBUG', false); // Conditional values. By default, if the condition is falsey, Env::if() returns null $config->adminEmail = $env->if('APP_ENV', 'production', 'you@youremail.com'); // A fourth argument will be returned if condition is false, truthy/falsey output can be env var names or specific values $config->adminEmail = $env->if('APP_ENV', 'production', 'ADMIN_EMAIL', 'you@youremail.com'); // Conversely, you can also check if a condition is not met. $config->adminEmail = $env->ifNot('APP_ENV', 'development', 'ADMIN_EMAIL'); // Use one env value to set multiple config properties $config->advanced = $env->if('APP_ENV', 'production', false, 'ENABLE_ADVANCED'); // Never in production, change locally in env as needed $config->adminEmail = $env->ifNot('APP_ENV', 'development', 'ADMIN_EMAIL'); // Never send an email in dev, always on staging/production These helper methods make is very straightforward to implement a dynamic config file. This can be useful for using secure .env values while retaining the ability to commit and upload some types of changes to your config.php file without needing to touch .env values on the server. You can also use Env::pushToConfig(). As long as you use the "screaming snake case" naming convention for your environment variable names, type and value recognition are handled automatically. <?php $env->pushToConfig($config, [ 'usePageClasses' => true, 'templateCompile' => 'TEMPLATE_COMPILE', 'debug' => ['DEBUG', false], // Fallback to false 'advanced' => $env->if('APP_ENV', 'production', false, 'ENABLE_ADVANCED'), 'adminEmail' => $env->ifNot('APP_ENV', 'development', 'ADMIN_EMAIL'), 'httpHosts' => [ 'something.com', 'staging.something.com', 'something.ddev.site' ], ]); Using Env in your application files and templates can be very useful. In the above example we assigned the Env object to $config->env. This lets you access your .env variables globally and use some helpful methods. <?php if ($config->env->eq('APP_ENV', 'development')): ?> <script src="/some/development/stuff.js"></script> <?php endif ?> <?php if (!$config->env->exists('GOOGLE_API_KEY')) { $wire->error('A Google API key could not be loaded from the environment file.'); } try { // Do something that could fail } catch (Exception $e) { $message = $config->env->if('APP_ENV', 'production', 'Oh no. Friendly message here', $e->getMessage()); } This utility also automatically casts 'true' and 'false' values in .env files to booleans, and casts numbers to integers. It also includes several configuration options. I have been using this tool in production and have been happy with it. Maybe you might find it helpful in your projects as well. If you like it, throw a star on the repo. If you run into any bugs, file an issue on Github. I may publish it as a composer package at some point. Env utility for ProcessWIre on Github.
    3 points
  2. @elabx Those are really just a matter of being thorough with security. Another answer to your question about where to put the env folder is anywhere you want really. As long as you update your composer.json file so the namespace resolves to the location that folder you can keep it anywhere.
    1 point
  3. My bad, hadn't noticed the .htaccess files, great idea!
    1 point
  4. I have been using .env but only with phpdotenv, this looks like a step forward, thanks!
    1 point
  5. Hello, we noticed that these "extraClasses" are not included in the minified version of the used leaflet.awesome-markers https://github.com/lennardv2/Leaflet.awesome-markers/blob/2.0/develop/dist/leaflet.awesome-markers.min.js but in the unminified version https://github.com/lennardv2/Leaflet.awesome-markers/blob/2.0/develop/dist/leaflet.awesome-markers.js so we solved this by adding the unminified version to the project https://github.com/hefan/FieldtypeLeafletMapMarker/commit/9aeefed37b8065d71fc3a23ed80d9ee41eab974b and just link this file in "MarkupLeafletMap.module" file https://github.com/hefan/FieldtypeLeafletMapMarker/commit/0f5f563cdf2df725a32e1a3bbeb30a8790f4bd13
    1 point
  6. Thanks for the tutorial! I didn't integrate the "search as you type" ajax and instead just hijacked the submit button to perform the search using the same method as you explained, and it works great!
    1 point
  7. Big thanks to everyone that shared your favorite ProcessWire features last week, it was very helpful for the new ‘features’ section of the website. Speaking of the website, I’ve been continuing to work on that this week, and was primarily focused on the modules directory. I’ve got plenty more to do there, but making good progress. The website is going to be the focus of the next few weeks, with some core updates along the way. This week the core updates were a few issue fixes on the dev branch, with more on the way next week. Thanks for reading and have a great weekend!
    1 point
  8. Speaking of the website, it currently states that you're downloading 3.0.244 but it shows as 3.0.246 once installed.
    1 point
  9. Greetings Everyone, ************************************************* ************************************************* EDIT NOTE: This post started as a work-in-progress discussion as I was working out the elements of a successful form. After contributions from participants in this discussion, the code below has been tested and works well. You can use the code as shown below in your ProcessWire templates! Feel free to follow up with additional quesations/comments! ************************************************* ************************************************* I have successfully built front-end forms with ProcessWire to add pages via the API. It works great -- until I had to include image uploads along with the "regular" form fields. Then it temporarily got a bit complicated. In this discussion, I show how to handle front-end submissions in ProcessWire with the goal of allowing us to create pages from custom forms. I then go a step further and show how to use the same form to upload files (images and other files). I'm hoping this discussion can illustrate the whole process. I know a lot of people are interested in using ProcessWire to do front-end submissions, and my goal for this discussion is to benefit others as well as myself! First, here's my original contact form (no file uploads): <form action="/customer-service/contact/contact-success/" method="post"> <p><label for="contactname">Name:</label></p> <p><input type="text" name="contactname"></p> <p><label for="email">E-Mail:</label></p> <p><input type="email" name="email"></p> <p><label for="comments">Comments:</label></p> <p><textarea name="comments" cols="25" rows="6"></textarea></p> <button type="submit">Submit</button></form> And here's the "contact-success" page that picks up the form entry to create ProcessWire pages: <?php // First, confirm that a submission has been made if ($input->post->contactname) { // Save in the ProcessWire page tree; map submission to the template fields $np = new Page(); // create new page object $np->template = $templates->get("contact_submission"); $np->parent = $pages->get("/customer-service/contact-us/contact-submission-listing/"); // Send all form submissions through ProcessWire sanitization $title = $sanitizer->text($input->post->contactname); $name = $sanitizer->text($input->post->contactname); $contactname = $sanitizer->text($input->post->contactname); $email = $sanitizer->email($input->post->email); $comments = $sanitizer->textarea($input->post->comments); // Match up the sanitized inputs we just got with the template fields $np->of(false); $np->title = $contactname; $np->name = $contactname; $np->contactname = $contactname; $np->email = $email; $np->comments = $comments; // Save/create the page $np->save(); } ?> This works great! After submitting the form, we go to the "Success" page, and new submissions show up in the ProcessWire page tree right away. Excellent! Now I need to add a photo field. I altered the above form so it looks like this: <form action="/customer-service/contact/contact-success/" method="post" enctype="multipart/form-data"> <p><label for="contactname">Name:</label></p> <p><input type="text" name="contactname"></p> <p><label for="email">E-Mail:</label></p> <p><input type="email" name="email"></p> <p><label for="comments">Comments:</label></p> <p><textarea name="comments" cols="25" rows="6"></textarea></p> <p>Click the "Select Files" button below to upload your photo.</p> <input type="file" name="contact_photo" /> <button type="submit">Submit</button> </form> And here's the updated "contact-success" page: <?php // First, confirm that a submission has been made if($input->post->contactname) { // Set a temporary upload location where the submitted files are stored during form processing $upload_path = $config->paths->assets . "files/contact_files/"; // New wire upload $contact_photo = new WireUpload('contact_photo'); // References the name of the field in the HTML form that uploads the photo $contact_photo->setMaxFiles(5); $contact_photo->setOverwrite(false); $contact_photo->setDestinationPath($upload_path); $contact_photo->setValidExtensions(array('jpg', 'jpeg', 'png', 'gif')); // execute upload and check for errors $files = $contact_photo->execute(); // Run a count($files) test to make sure there are actually files; if so, proceed; if not, generate getErrors() if(!count($files)) { $contact_photo->error("Sorry, but you need to add a photo!"); return false; } // Do an initial save in the ProcessWire page tree; set the necessary information (template, parent, title, and name) $np = new Page(); // create new page object $np->template = $templates->get("contact_submission"); // set the template that applies to pages created from form submissions $np->parent = $pages->get("/customer-service/contact-us/contact-submission-listing/"); // set the parent for the page being created here // Send all the form's $_POST submissions through ProcessWire's sanitization and/or map to a variable with the same name as the template fields we'll be populating $np->title = $sanitizer->text($input->post->contactname); $np->name = $np->title; $np->contactname = $sanitizer->text($input->post->contactname); $np->email = $sanitizer->email($input->post->email); $np->comments = $sanitizer->textarea($input->post->comments); $np->save(); // Run photo upload foreach($files as $filename) { $pathname = $upload_path . $filename; $np->contact_photo->add($pathname); $np->message("Added file: $filename"); unlink($pathname); } // Save page again $np->save(); ?> <p>Thank you for your contact information.</p> <?php return true; } else { ?> <p> Sorry, your photo upload was not successful...</P> <?php } ?> Replace the field references with your own field names, make sure to change the various paths to match yours, and change the various messages to be what you need for your project. Read the entire discussion to see how we worked through getting to the solution shown above. Thanks, Matthew
    1 point
×
×
  • Create New...