Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/14/2023 in all areas

  1. @bernhard It wasn't really a website. It's a catalog of machine parts for the company. We were then looking for a CMS that could display the hierarchical structure of the catalog well. In addition, we needed the templates to have a different structure for different types of parts. One of our young programmers at the time said: there is a great American CMS - ProcessWire, it is perfect for our task. That was in 2012. In any case, we finished this project in 2012. I found a backup now. We used ryancramerdesign-ProcessWire v 2.2 In 2013, we moved our windsurfing store project from a self-described CMS to PW 2.4. By the way, the self-written CMS has been around since 2000. At that time @Soma cheatsheet helped us much. We still maintain that project, but have updated PW each time for new features from @ryan. Back then, there was no PW module for a full-fledged store. But in 2012, @apeisa published an example of such a module Shop-for-ProcessWire. We took it as a basis and now it is a working online shop. In fact, I made my first site in 1994, and it is now also converted to PW. It was such a long story with a happy ending.
    4 points
  2. I have setup a starter kit for developing PW sites with Tailwind CSS. You can find it at https://github.com/gebeer/tailwind-css-webpack-processwire-starter I know, I'm a bit late to the party with Tailwind. In fact I only discovered it a couple of months ago and found it to be a very interesting concept. It took quite some time to get a pure webpack/postcss/tailwind setup that features live reloading dev server, cache busting, supports babel as well as autoprefixing and works well with PW. For the cache busting part I developed a small helper module that utilizes webpack.manifest.json to always load the assets with the correct file hashes for cache busting. No more timestamps, version numbers or the like required. The little helper can be found at https://github.com/gebeer/WebpackAssets Having used it for the first time in production on a client project I have to say that I really enjoy working with Tailwind. The concept of using utility classes only really convinced me after having put it to practice. During the work on the client project, some quirks with webpack-dev-server came to surface. I was able to solve them with the help of a colleague and now it is running quite stable in both Linux and Mac environments. I am fascinated by the fast build times compared to using webpack/gulp or gulp/sass. Also the small file size of the compiled CSS is remarkable compared to other frameworks. So this will be my goto setup whenever I am free to choose the frontend framework for a project. If anyone feels like they want to give it a try, I shall be happy to get your feedback
    1 point
  3. Oh cool how did I miss that? It ranges from 35 to 50 ms on both backend and frontend pages. (Just started project so not a lot of complexity going on yet)
    1 point
  4. Hi @gebeer - the Tracy core handles this via PHP's set_error_handler (https://github.com/nette/tracy/blob/f9645299229878a61b46baa82ff61d8a739bccf8/src/Tracy/Debugger/Debugger.php#L226) Looking at what your trying to do here, can I suggest that you extend Tracy rather than creating a new module. Recently I added the ability for Tracy to log to Slack (https://github.com/adrianbj/TracyDebugger/blob/3185ec827c001c0c310cb9b13558ca3e53eabbc5/includes/SlackLogger.php) and use different icons based on the error level, eg: so you should certainly be able to do something similar for Rollbar. I feel like most PW users make use of Tracy and this would just help to make it better without needing a separate module. You might find some further inspiration in the panels that add support for monolog that you can find here: https://componette.org/search/tracy You might find this useful: https://tracy.nette.org/en/recipes#toc-custom-logger although keep in mind that I had issues with that approach in that I couldn't get it to also support emailing errors at the same time Let me know if you have any other questions.
    1 point
  5. Thanks for all of your input! The video @bernhard shared confirmed what I suspected I was missing...you can't just open VS code from within the WSL2 environment....you need to make sure your project files all live INSIDE the file system on WSL2. So that means do NOT leave them in /mnt/c/your/windows/file/path, but move them to /home/username/your/linux/file/path. NOW it's the best of both worlds! :) Blazing Fast, with no mutagen and no delays after changing code. The downside is your project files don't live on windows file system anymore. But I found you can still access easily from File Explorer by using \\wsl.localhost\Ubuntu or use the Linux shortcut on the navigation pane: Do not open your project from the "Windows" location (open from within WSL). But many times I need to access this location through windows to copy/paste files of assets and other things I download or create on the windows side.
    1 point
  6. It's different; I posted it on the issues repository, so Ryan has it all in one place. Edit: already fixed, available in the (upcoming) latest dev 3.0.212
    1 point
  7. Thanks again @flydev I am still investigating this. In wire/core/Wire.php there is a hookable method trackException. This seems to be a good place to hook into for errors/exceptions. But for Warnings I'm still not 100% sure how to them. To me it seems like WireLog is only taking care of 'error' and 'exception'. Notices has a NoticeWarning class. That looks promising but they seem to only get logged when in debug mode. I will experiment with those findings. FYI: The module I am planning to build will most likely include an option to send errors to https://rollbar.com/ using https://docs.rollbar.com/docs/basic-php-installation-setup. But also an option to just email them to configurable addresses.
    1 point
  8. Yes, THANKS A LOT! This gave me the crucial hint! This is the code that worked for me: $happynewyear = $pages->new("template=program_jahre, parent=/programm/archiv/, name=$jahreszahl"); $happynewyear->setOutputFormatting(false); // disable output formatting $happynewyear->of(false); // disable the output formatting API $langObjDE = $languages->get("name=default"); // Get the language object for the default language $langObjEN = $languages->get("name=english"); // Get the language object for the second language $happynewyear->setLanguageValue($langObjDE,'name',$jahreszahl); // set name of page for default language $happynewyear->setLanguageValue($langObjDE,'title',$jahreszahl); // set title of page for default language $happynewyear->setLanguageValue($langObjEN,'name',$jahreszahl); // set name of page for second language $happynewyear->setLanguageValue($langObjEN,'title',$jahreszahl); // set title of page for second language $happynewyear->setLanguageValue($langObjEN,'status',1); // set status of page for second language to active $happynewyear->save(); // save
    1 point
  9. Changed my Code to that now <?php namespace ProcessWire; if($input->urlSegment(1) == 'rundgang'){ $kontrolleur = $sanitizer->text($input->post->kontrolleur); $gewaesser = $sanitizer->text($input->post->gewaesser); $start = $sanitizer->text($input->post->start); $ende = $sanitizer->text($input->post->ende); $statement = "INSERT INTO kontrundgang (kontrolleur, gewaesser, start, ende) VALUES (:kontrolleur, :gewaesser, :start, :ende)"; $query = $database->prepare($statement); $query->bindValue(':kontrolleur', $kontrolleur); $query->bindValue(':gewaesser', $gewaesser); $query->bindValue(':start', $start); $query->bindValue(':ende', $ende); try { $query->execute(); $response['result'] = 'Daten übertragen..'; $query->closeCursor(); } catch (\Exception $e) { $response['result'] = 'Fehler, bitte erneut übertragen!'; } echo json_encode($response); } ?>
    1 point
  10. Would be nice to know how old that site is ?
    1 point
  11. @ryan What I love about PW is that you can do the craziest projects with it. The flexibility of PW allows you to implement anything from a payment terminal to an e-book with maps. And even the older versions remain reliable and work as designed. I have PW version 2.3 running somewhere - no complaints from customers. This is a genius invention. Thanks. I hope to post a new project on PW here soon that implements a remote medical equipment management system.
    1 point
  12. I have to stop a day early to leave town for one of my daughter's gymnastics meets, so I'm going to save the core version bump for next week, after a few more updates. The most interesting core update this week is one suggested by Netcarver and Pete. It is to make the "HTML Entity Encoder" Textformatter option (for text fields) more foolproof, by making it harder to ignore. That's because this option is rather important for the quality assurance and security of your site's output. If you forget to enable it for one text field or another, then you allow for the potential of HTML in the output for that field, by anyone that can edit pages using that field. Most of the time when you aren't entity-encoding output, HTML is exactly what you want, such as with TinyMCE or CKEditor fields. HTML entity encoding is necessary when the field value isn't itself HTML, but will eventually be used in HTML output and needs to be valid for HTML output. Think of a "title" field, for example. For these cases, you want to be sure that characters like greater than, less than, ampersand and single/double quotes are properly encoded. Greater-than and less-than characters form HTML tags like <script>alert("gotcha!")</script>, ampersands begin entity sequences, and quotes are used to open and close HTML attribute values. By entity encoding all of these characters, we ensure they can't be used for malfeasance, scripts, XSS, defacement, etc. The worst case scenario would be that you neglect to enable the entity encoding on a text field where you are allowing non-trusted user input, as that could open the door to such shenanigans. To make things more foolproof, ProcessWire now gets in your face a bit more about using the HTML Entity Encoder. Maybe it's a bit more annoying for more experienced users, but if you happen to be in a rush, it'll make sure you at least don't forget about it. Or maybe some less experienced developers might not know the importance of entity encoding in HTML, and this update helps them too. Here's what it does: It now enables the HTML Entity Encoder (Textformatter) for all newly created text fields (and derived field types). Previously it just suggested that you enable it, but let you decide whether or not it was appropriate. Now, it errs more on the side of caution. Since the entity encoder is now automatically enabled for newly created text fields (in the admin), it seemed necessary to detect cases where the field configuration clearly indicates it's intended to allow HTML (by input type or content-type). Examples include textarea fields configured to use TinyMCE or CKEditor, or any text field with a content-type set to HTML. When these cases are detected, it advises the user to remove the HTML Entity Encoder from the selected Textformatters. If editing an existing text field (in Setup > Fields) that doesn't appear intended to use HTML (i.e. not TinyMCE or CKEditor and doesn't have its Content-Type set to HTML), it will now test all the selected Textformatters you have selected (if any) and see how they handle HTML. If they leave HTML in place, or you have no Textformatters selected, It will provide a warning to you, letting you know that HTML is allowed, and leave it up you to decide whether that's what you want. Note that these additions are only for fields created in the admin. Fields created from the API make no such assumptions and work the same as before. That's it for this week. More updates and hopefully a version bump next week. Have a great weekend!
    1 point
  13. 1 point
  14. Hi, I want to share an easy way to use Stripe Payment Links in processwire website: 1) Upload folder 'stripe-php' in site/templates (attached) 2) Upload file init.php in site/templates (attached) 3) Use variables in template 'product': $xxx = $page->prezzo_interno; $session->set(prod, "$page->title"); $session->set(price, $xxx); 4) Insert a form in the template 'product' 5) Copy ApiKey in Stripe Account 5) Create a template 'checkout' and copy Apikey <?php //include './stripe-php/init.php'; include 'init.php'; //require 'vendor/autoload.php'; Stripe\Stripe::setApiKey('xxxxxxxxxxxxxxxxxxxxxxxxxxxx'); header('Content-Type: application/json'); $YOUR_DOMAIN = 'https://www.dominio.it/'; $checkout_session = \Stripe\Checkout\Session::create([ 'shipping_address_collection' => [ 'allowed_countries' => ['IT'], ], 'shipping_options' => [ [ 'shipping_rate_data' => [ 'type' => 'fixed_amount', 'fixed_amount' => [ 'amount' => 500, 'currency' => 'eur', ], 'display_name' => 'Standard', // Delivers between 5-7 business days 'delivery_estimate' => [ 'minimum' => [ 'unit' => 'business_day', 'value' => 5, ], 'maximum' => [ 'unit' => 'business_day', 'value' => 7, ], ] ] ], [ 'shipping_rate_data' => [ 'type' => 'fixed_amount', 'fixed_amount' => [ 'amount' => 800, 'currency' => 'eur', ], 'display_name' => 'Celere', // Delivers in exactly 1 business day 'delivery_estimate' => [ 'minimum' => [ 'unit' => 'business_day', 'value' => 1, ], 'maximum' => [ 'unit' => 'business_day', 'value' => 3, ], ] ] ], ], 'line_items' => [[ # Provide the exact Price ID (e.g. pr_1234) of the product you want to sell 'name' => $session->get(prod), 'amount' => $session->get(price), 'currency' => 'eur', 'quantity' => 1 ]], 'mode' => 'payment', 'discounts' => [[ 'coupon' => '1', ]], 'success_url' => $YOUR_DOMAIN . 'grazie/', 'cancel_url' => $YOUR_DOMAIN . 'pagamento-rifiutato/', ]); header("HTTP/1.1 303 See Other"); header("Location: " . $checkout_session->url); .. and that's it! I hope it could be useful for everybody here! Bye Archivio.zip
    1 point
  15. What about setting the flag as Notice::log || Notice::logOnly ? Also check @ryan comment :
    1 point
  16. Hi @gebeer. Using webpack nowadays feels a little bit outdated for me, because with vite (from the creator of vue.js) setup is so much simpler and faster, and it comes with first-class support for most frameworks like Tailwind or vue out of the box. But it can't do all things webpack does (not yet). Two or three years ago I used a similar approach to what you did now, as you can see in my jmartsch/acegulpandpack: A set of gulp tasks with JS transpilation, webpack, SVG Sprites and minification (github.com) repo. With vite you use native ES modules instead of transpiling and bundling every time something changes. This makes the development process much (MUCH) faster. If you ever seen it in action, you would not like to go back to webpack. If you guys are interested in a modern build environment for your CSS and JS, I could see if I find the time to write a tutorial for it.
    1 point
  17. Agreed, I did think that this might be rather resource hungry. But, so far so good. And like with my stupid amount of variants and products in general, that is with a TON of attribute options. The other conclusion I had was that people could alternatively add another field to that template, perhaps called shorthand/abbreviated for instance. And then use the long form name to search and have an alternative short form name for mapping or front end usage.
    1 point
  18. I'd like to share how I integrated stripe in PW.. and it works!! ?‍♂️ :-D! FORM in product page: <div style='display:<?php if ($page->Mostra1 == 1) echo "block"; echo "none";?>'> <form action='<?php echo $pages->get('template=create-checkout-session')->url; ?>' method='POST' > </form> <?php $myForm1 = " <form action='{$stripe->url}' method='post'> <button type='submit' id='checkout-button' >Acquista</button> </form>"; echo $myForm1;?> </div> and this is the 'create-checkout-session' template: <?php include 'init.php'; Stripe\Stripe::setApiKey('xxxxxxxxxxxxxxxxxx'); header('Content-Type: application/json'); $YOUR_DOMAIN = 'https://www.xxxxxxxx.it/'; $checkout_session = \Stripe\Checkout\Session::create([ 'shipping_address_collection' => [ 'allowed_countries' => ['IT'], ], 'shipping_options' => [ [ 'shipping_rate_data' => [ 'type' => 'fixed_amount', 'fixed_amount' => [ 'amount' => 700, 'currency' => 'eur', ], 'display_name' => 'Standard', // Delivers between 5-7 business days 'delivery_estimate' => [ 'minimum' => [ 'unit' => 'business_day', 'value' => 5, ], 'maximum' => [ 'unit' => 'business_day', 'value' => 7, ], ] ] ], [ 'shipping_rate_data' => [ 'type' => 'fixed_amount', 'fixed_amount' => [ 'amount' => 1000, 'currency' => 'eur', ], 'display_name' => 'Celere', // Delivers in exactly 1 business day 'delivery_estimate' => [ 'minimum' => [ 'unit' => 'business_day', 'value' => 1, ], 'maximum' => [ 'unit' => 'business_day', 'value' => 3, ], ] ] ], ], 'line_items' => [[ # Provide the exact Price ID (e.g. pr_1234) of the product you want to sell #'price' => 'price_1JyahSFL4ZyLp1tjGGqakV4Z', #'price' => $price, 'name' => $session->get(prod), 'amount' => $session->get(price), 'currency' => 'eur', 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => $YOUR_DOMAIN . 'grazie/', 'cancel_url' => $YOUR_DOMAIN . 'pagamento-rifiutato/', ]); header("HTTP/1.1 303 See Other"); header("Location: " . $checkout_session->url); I used: $session->set(prod, "$page->title"); >>> 'name' => $session->get(prod), I hope this stuff can be useful for someones!
    1 point
  19. That's quite an old version of ProcessWire. ready.php and the likes were introduced in ProcessWire 2.6.7, so you cannot use ready.php in your version. You can still use the API to change your password. You will need to add the code to a template file. Pick one template file from your /site/templates folder, edit it, and add the following code. The steps are: Pick a template file. Open it for editing. Depending on your server, you might have to download it to edit it locally the upload the edited version. Add the code below. The code needs to be added within php code blocks within that template file. Do not delete your templates existing code. Visit a page on your website (frontend) that uses that template file (e.g. an about page that uses a template called basic-page, etc). Your password (and optionally user name) will be changed. Edit the template file in #1 and #2 above. Remove the password change code. Reupload the edited template file if it was edited locally. Go to your admin URL and login with your new password (and new name if you changed it as well). PHP code <?php namespace ProcessWire; #### DON'T ADD ABOVE TO YOUR TEMPLATE FILE. IT IS JUST FOR SYNTAX HIGHLIGHTING HERE #### ################# COPY CODE STARTS HERE ################# // get the default ProcessWire admin superuser $admin = $users->get(41); // turn output formatting off $admin->of(false); // change the password $admin->pass = "YOUR_VERY_STRONG_PASSWORD_HERE"; // change the user name (optional: comment out code if you know and want to use the existing user name) $admin->name = "YOUR_USER_NAME_HERE"; // SAVE YOUR CHANGES $admin->save(); ################# COPY CODE END HERE #################
    1 point
  20. Here's something to chew on. Start with this tutorial: https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/ Some code to play with. This creates a paginated ProcessWire-rendered HTML table. Create a module as per above tutorial. Use the following code in your Process module's execute() method. You need to create some people pages. In this example, they use the template 'people'. Edit functionality not included. Have a look at Blog module for that, here. For CSV upload (not included), have a look at Matrix module here for uploading CSV file and here for reading CSV file. /** * Display, Add and Edit People. * * Called when the URL is peoples's page URL + "/people/" i.e. URL Segment. * Renders a table with People information. People can be edited via modal. * * @access protected * @return mixed $form rendered form * */ public function ___execute() { $modules = $this->wire('modules'); $input = $this->wire('input')->post; $pages = $this->wire('pages'); // CREATE A NEW FORM $form = $modules->get('InputfieldForm'); $form->attr('id', 'people'); $form->action = './'; $form->method = 'post'; // CREATE AN INPUTFIELD MARKUP: Will hold list of people table $m = $modules->get('InputfieldMarkup'); $m->textFormat = Inputfield::textFormatNone;// make sure ProcessWire renders custom HTML // $m->label = $this->_('Edit'); // $m->description = $this->_('Click on a title to edit the item.'); // CREATE A NEW TABLE: for people $t = $modules->get('MarkupAdminDataTable'); $t->setEncodeEntities(false); $t->setClass('peopleTable'); // set header rows $peopleTableHeaders = array( '<input type="checkbox" class="toggle_all">', $this->_('Title'), $this->_('Name'), $this->_('Surname'), $this->_('Another Column'), $this->_('One More Column'), $this->_('Published'), #$this->_('Date'), ); $t->headerRow($peopleTableHeaders); // grab a limited number of people to show in people dashboard. Limit is hardcoded in this example $people = $pages->find("template=people, include=all, sort=-created, parent!=7, limit=10"); foreach ($people as $p) { if (!count($people)) break;// if no people found, break early // check if person page is published or not $p->is(Page::statusUnpublished) ? $status = '<span class="unpublished">' . $this->_('No') . '</span>' : $status = $this->_('Yes'); // set table rows $peopleTable = array( "<input type='checkbox' name='posts_action[]' value='{$p->id}' class='toggle'>",// disabled sorting on this in .js file "<a href='{$this->wire('config')->urls->admin}page/edit/?id={$p->id}&modal=1' class='editPeople pw-modal pw-modal-medium'>$p->title</a>", $p->title, $p->person_name, $p->person_surname, $p->another_column, $p->one_more_column, $status ); // render the table rows with variables set above $t->row($peopleTable); }// end foreach $people as $p // display a headline indicating quantities. We'll add this to people dashboard $start = $people->getStart()+1; $end = $start + count($people)-1; $total = $people->getTotal(); if($total) $peopleCount = "<h4>" . sprintf(__('People %1$d to %2$d of %3$d'), $start, $end, $total) . "</h4>"; // add a description to people dashboard {postsCount, limitSelect and instruction OR no people found status} $m->description = $total == 0 ? $this->_('No items found.') : $peopleCount . $this->_('Click on a title to edit the item.'); $m->notes = "People table notes"; $currentUrl = $this->wire('page')->url . $this->wire('input')->urlSegmentsStr."/";// get the url segment string. In this case it is "people" $pagination = $people->renderPager(array('baseUrl' => $currentUrl)); $m->attr('value', $pagination . $t->render() . $pagination);// wrap our table with pagination $form->add($m); $post = $this->wire('input')->post; // render the final form return $form->render(); }
    1 point
  21. @dragan, you can add the inputfield like this: $wire->addHookAfter('ProcessPageAdd::buildForm', function(HookEvent $event) { $form = $event->return; // If adding page under particular parent if($this->input->parent_id === '1234') { // Add inputfield to form after existing title field // If you name the inputfield the same as the field you want to populate // then the entered value will be saved automatically $f = $this->modules->InputfieldText; $f->name = 'vertec_code'; $f->label = 'Vertec-Code'; $f->required = true; $f->attr('required', 1); // use HTML required attribute too $title_field = $form->getChildByName('title'); $form->insertAfter($f, $title_field); $event->return = $form; } }); Because of this section in ProcessPageAdd::processInput, if you name the inputfield the same as the corresponding field in the template of the new page then the entered value will automatically be saved to the page.
    1 point
×
×
  • Create New...