• Content Count

  • Joined

  • Last visited

  • Days Won


eelkenet last won the day on December 5 2018

eelkenet had the most liked content!

Community Reputation

60 Excellent

About eelkenet

  • Rank
    Full Member

Profile Information

  • Gender
    Not Telling
  • Location

Recent Profile Visitors

1,965 profile views
  1. Ah, I did not know that. Makes sense as a limit for the full posts. For titles though.. not sure. Besides, Invision Community (the forum software) supports it on their own support forum just fine:
  2. While I know there are a couple of modules, topics and posts regarding SEO, it is impossible to search for these: for instance yields no results. It seems that the minimum input length is currently set at 4 characters, though this is not mentioned. So my request, if technically feasible: can the minimum search length please be reduced to 3 character long strings? If possible 2-letter combinations could be valuable as well, though that could be a bit too much of a strain on the database I guess.
  3. eelkenet

    Anything in your logs?
  4. eelkenet

    Congratulations on the launch, Ryan! I do have issues with the iMac/screenshots images though, as others have said before me. Not because it is an iMac, but because of the impossible size of the content. My first reaction as a visitor is to squint my eyes and to move my head close to the monitor to see the actual PW screenshots inside it. And to be honest I think that is a problem, because: The very first impression, the first thing people look at, on any website will always be graphics/images, not text. You only get one shot at a first impression The first impression should be very clear and very convincing The iMac frame and code in the background take about 75% of the available real estate, making the actual screenshots tiny! A simple sliding carousel or slideshow would suffice, possibly showing steps like: The pagetree Editing a page Cropping an image Creating fields Creating template
  5. eelkenet

    Great work Ryan, thank you! I fully agree with this. Our main use of Processwire is as a headless CMS / CMF for Single Page Applications. As a possible future user I would be very interested in learning about how PW can be used in this way. I would look for that on the 'Output' page ( A simple JSON API example, without the use of any external modules, would suffice here I think.
  6. I had a quite some trouble getting this to work with the content from a ProFields Table, as this does not work the same as with a Repeater or PageTable. But I am happy to say that treating those fields as a 'file' works, by setting this in the options array. Ie: <?php $finder = new RockFinder("template=template_name,limit=10", ["title", "some_field_name"]); $field = $finder->addField("my_table_field", ["column_name", "other_column"], ["type" => "file"]); $field->seperator = ", ";
  7. eelkenet

    Hmm, that is weird, in that case it is probably being reset somewhere. Have you tried doing a full search of your project's code for places where it might be overridden? Maybe some module or template is accidentally setting it, instead of checking for the value.
  8. eelkenet

    You should not overwrite this file. Instead, edit the config in site/config.php.
  9. eelkenet

    I ran into this issue too. I edited the Mollie module to fit my own needs, a bit too many changes to create a merge request, but it deals with this issue. <?php namespace ProcessWire; // Here you can find more information about the Mollie php api require_once __DIR__ . "/vendor/autoload.php"; class PaymentMollie extends PaymentModule { public static function getModuleInfo() { return [ 'title' => 'PaymentMollie', 'version' => '0.0.2', 'summary' => 'Mollie Payment method', 'singular' => false, 'autoload' => false, 'requires' => 'ProcessWire>=3.0.98, PaymentModule', ]; } public function init() { ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); } public function getTitle() { return $this->_("Mollie: iDeal, Bancontact"); } public function getFailureReason() { return "Error"; } public function processPayment() { $payment_id = wire()->input->post->id; $order_id = wire()->input->urlSegment2; $mollie = new \Mollie\Api\MollieApiClient(); $mollie->setApiKey($this->test_api_key); if ($this->live_check == "1") { $mollie->setApiKey($this->api_key); } $payment = $mollie->payments->get($payment_id); $order_id = $payment->metadata->order_id; wire()->log->save("mollie", "Processing payment for... $order_id"); if ($payment->isPaid() == true) { wire()->log->save("mollie", "Order $order_id was paid using mollie!"); $order = wire()->pages->get($order_id); $order->of(false); $order->pad_paid = time(); $order->addNote($this->_("Order paid using Mollie") . ": " . $payment->id); $order->removeStatus(Page::statusUnpublished); $order->save(); return true; } elseif ($payment->isOpen() == FALSE) { return false; } return false; } public function getMollieMethods() { $mollie = new \Mollie\Api\MollieApiClient(); $mollie->setApiKey($this->test_api_key); if ($this->live_check == "1") { $mollie->setApiKey($this->api_key); } $methods = $mollie->methods->all(); $return = [ ]; foreach ($methods as $method) { $return[] = [ "title" => htmlspecialchars($method->description), "icon" => htmlspecialchars($method->image->size1x), "icon2x" => htmlspecialchars($method->image->size2x), ]; } return $return; } public function render() { $output = ""; $mollie = new \Mollie\Api\MollieApiClient(); $mollie->setApiKey($this->test_api_key); if ($this->live_check == "1") { $mollie->setApiKey($this->api_key); } $paymentInfo = [ "amount" => [ "value" => number_format(($this->getTotalAmount() /100), 2, '.', ''), "currency" => 'EUR', ], "description" => "Bestelling van: " . $this->customer->givenName . " " . $this->customer->familyName, "redirectUrl" => $this->httphost . "checkout/?id=" . $this->id, "webhookUrl" => $this->httphost. "checkout/processmollie/" . $this->id . "/", // Specify here wat you want "metadata" => [ "order_id" => $this->id, /* "customer_name" => $this->customer->givenName, "customer_familyName" => $this->customer->familyName, "customer_address" => $this->customer->streetAddress, "customer_locality" => $this->customer->locality, "customer_postalCode" => $this->customer->postalCode, "customer_country" => $this->customer->country, "customer_email" => $this->customer->email */ ], ]; // $output .= "<pre>" . print_r($paymentInfo, true) . "</pre>"; $payment = $mollie->payments->create($paymentInfo); wire()->log->save("mollie", "Creating the payment... $order_id"); // Type here your custom HTML // use $payment->getPaymentUrl() as url for your payment link foreach ($methods as $method) { $output .= '<div style="line-height:40px; vertical-align:top">'; $output .= '<img src="' . htmlspecialchars($method->image->size1x) . '" srcset="' . htmlspecialchars($method->image->size2x) . ' 2x"> '; $output .= htmlspecialchars($method->description) . ' (' . htmlspecialchars($method->id) . ')'; $output .= '</div>'; } $output .= "</div>"; $output .= "<div><form action='{$payment->getCheckoutUrl()}'> <button type='submit'>". __('Pay') ."</button></form></div>"; return $output; } public static function getModuleConfigInputfields(array $data) { $inputfields = new InputfieldWrapper(); // Test API $live_api_field = wire('modules')->get('InputfieldText'); $live_api_field->name = 'test_api_key'; $live_api_field->label = __("Test API Key"); $live_api_field->notes = __(""); if (isset($data['test_api_key'])) { $live_api_field->value = $data['test_api_key']; } $inputfields->add($live_api_field); // Live API $test_api_field = wire('modules')->get('InputfieldText'); $test_api_field->name = 'api_key'; $test_api_field->label = __("Live API Key"); $test_api_field->notes = __(""); if (isset($data['api_key'])) { $test_api_field->value = $data['api_key']; } $inputfields->add($test_api_field); // Select live or test API $check_api_field = wire('modules')->get('InputfieldCheckbox'); $check_api_field->name = 'live_check'; $check_api_field->checked = $data['live_check']; $check_api_field->label = __("Use Live API Key"); $check_api_field->notes = __("If not selected, the test-api will be used. Keep in mind that you also have to activate the Live api on your Mollie dashboard"); if (isset($data['live_check'])) { $check_api_field->value = $data['live_check']; } $inputfields->add($check_api_field); // HTTP Host url $httphost_field = wire('modules')->get('InputfieldURL'); $httphost_field->name = 'httphost'; $httphost_field->label = __("HTTP Host"); $httphost_field->notes = __(""); if (isset($data['httphost'])) { $httphost_field->value = $data['httphost']; } $inputfields->add($httphost_field); return $inputfields; } }
  10. eelkenet

    I ran into an issue that is related to the way the RestAPI circumvents the pagetree structure (running the checkIfApiRequest hook before rendering any page). This method made it impossible to use ProCache for API requests that could (and should) return a cached result, such as for static site content. I thought about creating a custom caching system on top of RestApi, but ProCache is just too well designed to ignore here. I wrote a post about this on the ProCache VIP-forum, but as this forum is not accessible to all people I'd like to share my (admittedly hacky) solution for this. Basically I add another (cacheable) endpoint in the pagetree, which pipes the request to the RestApi endpoint: Create a new template and corresponding page (I called both 'api'). Set the content-type of this template to application/json, and disable any prepending/appending of files. Add the following code to the template: <?php //site/templates/api.php $protocol = $config->https ? "https://" : "http://"; $endpoint = $modules->get("RestApi")->endpoint; $hostname = $config->httpHost; $segments = implode("/", $input->urlSegments); $url = $protocol.$hostname."/".$endpoint.$segments; return file_get_contents($url); I'm sure there would be a better, cleaner way of doing this. A current downside is that there now are 2 seemingly identical endpoints for my site. One is cached, and the other is 'live'. Any ideas?
  11. eelkenet

    Great, that works! Thank you for the fix.
  12. eelkenet

    I installed the module (v0.1.3) on an existing site, running PW in the current Master release, v3.0.98 on Php 7.2. After enabling the module for a regular Fieldset (Open) I kept running into this error: Method InputfieldFieldsetOpen::wrapClass does not exist or is not callable in this context This is because Inputfield::wrapClass() has not been added to the Master yet, it is only available on the ProcessWire dev release (currently 3.0.119). The fix for this issue is to replace lines 107-109 with: // Add classes to inputfield $inputfield->wrapClass .= ' MinimalFieldset'; if(!$field->no_spacing) $inputfield->wrapClass .= ' MinimalFieldsetSpaced';
  13. eelkenet

    While it is not an 'out of the box' solution, it is perfectly possible to for instance to use the RestAPI module to parse any bit of content, such as (items from a) repeater matrix. Just like when you would write your regular template logic, it does require some custom programming on your end though: you will have to go through the matrix' items and decide how they should be presented through your API. Which is exactly the flexibility which makes PW our go-to solution for pretty much any modern (headless) webapp or old-school site!
  14. eelkenet

    Tip: If you install TracyDebugger, you automatically also get Adminer, with which it is very easy to import/export your full database from and to your local/staging server.
  15. eelkenet

    Hi @thomasaull, I have been using this module during the last week, to rebuild my API logic from the ground up. It's really nice work, thank you for releasing it! One thing I've noticed though, is that the exceptions handler (Router::handleException) is a bit overactive, and shuts everything down on non-critical exceptions. For instance, when running a PNG file through the PW ImageResizer ($img->size() etc), PW throws an exception, because the exif_read_data function is not available for PNG's. PW deals with this by using the error control operator (@method): the code still runs fine, while silently throwing an exception message. However, using the RestAPI module, this renders (and logs) an error message and stops any further output. It is of course easy to just comment out Router.php line 25, where you set the handler. But perhaps this could work in another way? Maybe making it a configurable option?