Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 08/15/2021 in all areas

  1. Hello @ all I want to share a new module with you, which makes the creation and validation of forms easy. Take a look at the following example of a simple contact form: // A very simple example of a contactform for demonstration purposes $form = new Form('contactform'); $gender = new Select('gender'); $gender->setLabel('Gender'); $gender->addOption('Mister', '0'); $gender->addOption('Miss', '1'); $form->add($gender); $surname = new InputText('surname'); $surname->setLabel('Surname'); $surname->setRule('required'); $form->add($surname); $name = new InputText('name'); $name->setLabel('Name'); $name->setRule('required'); $form->add($name); $email = new InputText('email'); $email->setLabel('E-Mail'); $email->setRule('required'); $form->add($email); $subject = new InputText('subject'); $subject->setLabel('Subject'); $subject->setRule('required'); $form->add($subject); $message = new Textarea('message'); $message->setLabel('Message'); $message->setRule('required'); $form->add($message); $privacy = new InputCheckbox('privacy'); $privacy->setLabel('I accept the privacy policy'); $privacy->setRule('required')->setCustomMessage('You have to accept our privacy policy'); $form->add($privacy); $button = new Button('submit'); $button->setAttribute('value', 'Send'); $form->add($button); if($form->isValid()){ print_r($form->getValues()); // do what you want } // render the form echo $form->render(); This piece of code creates a simple contact form and validates it according to the validation rules set. Inside the isValid() method you can run your code (fe sending an email) Highlights: 30+ validation types Support for UiKit 3 and Bootstrap 5 CSS framework SPAM protection Highly customizable Hookable methods for further customization Multi-language You can download and find really extensive information on how to use at https://github.com/juergenweb/FrontendForms. Please report errors or suggestions directly in GitHub. Best regards and happy testing ? If you have downloaded the module in the past I recommend you to uninstall the module completely and install the newest version 2.1.14. There are a lot of changes in the new version, so please test carefully.
    4 points
  2. Have you tried the actual path rather than docroot?
    2 points
  3. It worked! I don't know how I missed that. I was pretty sure I checked the path that was generated with docroot, but I guess I won't forget it next time. I am leaving it for a few hours now to test with my actual script and hopefully it's all good. Thanks for the quick tips, guys!
    1 point
  4. Im not sure, are you speaking about form and formsubmission? Than have a look at pw $session. It has a method exactly for that (xrss validation). You find it in the API docs. Im on mobile sorry.
    1 point
  5. Sure... If you haven't read deeply into htmx, the main premise is that the server is the single source of truth regarding both data and markup, i.e. whole application state. If we need to update either data or markup, the server handles that. We just need to tell it what action to take. Validation has to pass, of course, before the server will oblige ?. Below is a quick example that demonstrates updating the markup using htmx based on user actions. Only 'remove' locations is demonstrated in this example. I wasn't sure whether your app shows the user both their removed and added locations and whether they can reset the session to have all locations reloaded afresh. It doesn't matter much as it wouldn't change much of the logic in the example. Secondly, note that this example makes use of alpine.js and tailwind css just for the pizzaz. These are not required by htmx. To let ProcessWire recognise htmx requests, please refer to this thread. Depending on the approach you take from there, you might not even need a JavaScript file! In the example below, we do have a JavaScript file just because we want to use alpine.js (for notifications) and we need htmx to talk to alpine.js. We also need the JavaScript file to tell htmx to add XMLHttpRequest to its request headers so that ProcessWire's $config->ajax will understand the request. First, let's see a demo then we'll see how easy our work is using htmx. Just for this demo, I have included htmx (and alpine.js and tailwind css via their respective CDNs [in production, you want to purge your tailwind css ?]) in my _main.php. Inside the template I am using for this demo, I have the following code. Here, I have removed the tailwind classes used in the demo so we can focus on htmx. Note that you don't need a dedicated template file for this to work. It will work with any template. As long as htmx is loaded in the page view and your template (in this case, the current page's template) is listening to ajax requests. In the template file, the main htmx magic happens here: <?php namespace ProcessWire; $out = "<a hx-post='./' hx-target='#locations' hx-vals='{\"location_add_id\": \"{$page->id}\"}' hx-include='._post_token' hx-indicator='#locations_spinner_indicator'>Add</a>" . "<a hx-post='./' hx-target='#locations' hx-vals='{\"location_remove_id\": \"{$page->id}\"}' hx-include='._post_token' hx-indicator='#locations_spinner_indicator'>Remove</a>"; echo $out; Let's go through the htmx attributes: hx-post This tells htmx where to send its ajax request. In this case, we are sending it to the same page we are viewing (./) and are using POST. We could have used hx-get if we wanted to (GET). hx-target This tells htmx which markup to replace/swap. The default is to replace the markup of the element from which htmx was called. However, hx-target can be used to specify the element to replace. In this example, we are replacing the whole listing so we target its wrapper element which has the id locations. hx-vals This is optional but we need it in our example. We want to tell the server which location (ID) has been added/removed. If we had a form element, we could have used it for this instead. Since we don't have one, we are telling htmx to process the (JSON) value of hx-vals and send that together with its request. Note: the escape slashes are so we can have raw, valid JSON in the attribute as required by htmx. hx-include This is also optional but important in our case. It tells htmx to include input elements found via the selector in this attribute in its ajax request. In our example, we are telling htmx to include the CSRF token we set on the server together with its request. hx-indicator Also optional. Tells htmx to show/hide this element to show the user that something happened. In this case we use a spinner. We could have used a progress indicator as well, .e.g., if we were uploading a file. That's it really! No event listeners, no handlers! We can add (and I did add one), event listeners on htmx events in order to do something after the event. In this example, htmx fires a custom event which alpine.js is listening to in order to show notifications after the DOM has settled. The notification type (success, error, etc) and the message are all coming back from the server but not as JSON. The markup to update the page is also coming back from the server. htmx receives it and plugs it into the DOM per the hx-target (also see hx-swap) attribute value. In this example, we are updating the whole listing. If we wanted, we could update just the location that was removed, e.g. add it back but with some removed 'indicator', e.g. greyed-out. In this example we use anchor tags as htmx triggers. For htmx, it doesn't matter; button, div, p, li, whatever valid HTML element would work. You already have a backend logic that's working for you but I show an excerpt of mine here, for completeness. Inside my-template-file.php (the template file for the template for the current page, in this example), I have the following code: <?php namespace ProcessWire; if ($config->ajax) { // check CSRF if (!$session->CSRF->hasValidToken()) { // form submission is NOT valid throw new WireException('CSRF check failed!'); } // ................ more code // e.g. check removed locations in the session, etc // get previously removed locations (keeping things in sync) $removedLocations = $session->get('removedLocations'); // REMOVING LOCATION if ((int) $input->post->location_remove_id) { $mode = 'remove'; $notice = "Removed"; $id = (int) $input->post->location_remove_id; } else if ((int) $input->post->location_add_id) { // ADDING LOCATION $mode = 'add'; $notice = 'Added'; $id = (int) $input->post->location_add_id; } // ................ more code // e.g. check if we really have a page by that id, SET $noticeType, $options and update session 'removedLocations' etc // build final content //----------- // @note: buildLocationsCards() is a function that does what it says on the tin. We use it in both the ajax response here and also below, in non-ajax content, when the page loads // the $options array contains a key 'skip_pages_ids' with an array of IDs of locations (pages) that have been removed in this session. We skip these in buildLocationCards(). $out = buildLocationCards($page, $options); // @note - here we always return one input only // we use the values in this input in JS to pass event details to alpine.js to show the correct notification and the notification message. $out .= "<input type='hidden' id='location_notice' name='location_notice' data-notice-type='{$noticeType}' value='{$notice}'>"; echo $out; $this->halt(); } // NON-AJAX CONTENT BELOW.... That's all there is to it ?. I am happy to share the full code if anyone wants to play with this further.
    1 point
  6. As netcarver pointed out above, the amount of users is not going to be a problem. One site I've worked on recently has ~25 thousand users, most without admin access (just to a members area and a discussions forum), and that setup works just fine. One thing you need to take care of is that you don't grant said users' role/roles any admin-related permissions. Additionally if your site has front-end features that these users are not allowed to access, you'll want to make sure that you don't rely on $user->isLoggedin() alone, but rather always check that the user has expected role or permission. If you mean rolling your own system for handling all aspects of user management — authentication, authorisation, etc. — then I would recommend against it. ProcessWire has a solid system for handling such needs built-in, whereas any custom-built authentication solution would be a major security hot spot. In case ProcessWire's built-in system won't cut it for some reason (which I highly doubt), next best option would likely be using something like Laravel (or another application framework with proven track record) for this part.
    1 point
  7. @Manaus Take a look at Lakeland Trails from @Pete at Nifty Solutions. Almost 52 thousand users. Might be worth pinging him to ask more about the actual pros/cons of doing it that way.
    1 point
  8. Thanks for your hard work in getting lots of stuff resolved Ryan! Any chance you could prioritize this one: https://github.com/processwire/processwire-issues/issues/1116 It seems very critical to me for any site that uses URL segments and the link abstraction feature in CkEditor fields. Thanks!
    1 point
  9. Yes, I just subscribed for the complete webdev pack the discount is a very good deal. I see you guys back full stack ?
    1 point
×
×
  • Create New...