Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/09/2023 in all areas

  1. 140 commits, 55 resolved issues, dozens of new features, eight contributors, and five new pull requests make yet another great new version of ProcessWire. This week I’m happy to announce another new main/master branch version of ProcessWire, version 3.0.210. Like most main release versions, there is a lot here. This post covers some of the most notable additions and improvements— https://processwire.com/blog/posts/pw-3.0.210/
    4 points
  2. For me the SMTP thing is not really negotiable, sometimes companies use some mail setup that requires it. I've used both PHPMailer and the module, and sometimes the module even wins out. Thanks for the "post-install-cmd" tip, that might work well for my situation... being that moving the vendor folder outside of the webroot isn't mission critical. I'm in that situation where I can do whatever I want, but I do have to work with 101 different mail clients and shared hosts so I prefer to add my most used packages to a new project by default. Thanks everyone!
    2 points
  3. That's because it's not a regular array but a PageImages object. If you inspect $i in your first example, you'll see that it contains the image filename, not a numeric index. To get a plain array without the filenames as keys, use its inherited getValues() method. foreach ($page->images->getValues() as $i => $image):
    2 points
  4. The module can generate basic ICS calendar strings and files. Usage Example: $icsgen = wire()->modules->IcsGenerator; // set properties $icsgen->setArray(array( 'date' => new \DateTime('2033-12-24 12:00'), 'dateEnd' => new \DateTime('2033-12-24 13:00'), 'summary' => 'Event title', 'description' => 'Event description', )); // get path to a temporary .ics file // (using wire()->files->tempDir) $icspath = $icsgen->getFile(); // send email with ics file $mail = wireMail(); $mail->attachment($icspath, 'calendar.ics'); $mail->to($user->email); $mail->subject('ICS Demo'); $mail->body('This is a ICS demo.'); $numSent = $mail->send(); For more infos see GitHub Readme or Modules Page. If you experience reproducable issues please open a GitHub issue.
    1 point
  5. Hello @bernhard, as posted in the other thread, I tried adding the Latte Tracy Bar to RockFrontend. Just Added this to the RockFrontend.module.php: // Top of the Module add the LattePanel Class use Latte\Bridges\Tracy\LattePanel; // Add inside the "protected function renderFileLatte($file, $vars)" // After "$latte = new Engine();" add this to initialize the LattePanel if($this->modules->isInstalled("TracyDebugger")) LattePanel::initialize($latte); After that you have the LattePanel in Tracy ? I have not been able to detect any problems so far.
    1 point
  6. Hey @zoeck thx! I've added it to the latest version ? Only thing to mention is that this: Will result in only showing "header.latte" in the bar: In order to make it work you need to render default.latte instead of default.php: Nice! The problem here is though that we are losing nice RockFrontend features like "renderIf(...)" and there is no early exit feature in latte at the moment ?
    1 point
  7. Nice. I’m all for one-liners (at least for something like formatting…), but I find the whole IntlDateFormatter business a bit verbose. I like to keep pre-configured instances of the things around, for example on $config, and just call something like $config->dateFormatter->format($page->cooldate) Not sure if $config is a good place for this, and I have no experience doing this on multilanguage sites, but I imagine you’d be able to prepare the instances according to the user’s language and never have to worry about it again.
    1 point
  8. Evening @kongondo, Awesome work on all the bug fixes. Thank you for all of your continued efforts!
    1 point
  9. I agree, you have to use the IntDateFormatter class, like @Jan Romero mentioned. Have a look at this thread, I made a few examples how to use the IntDateFormatter as one-liner, etc.
    1 point
  10. Or Check this Post from bernhard: (Important: only works with the new master version 3.0.210 ?)
    1 point
  11. Check in your template > Advanced tab > List of fields to display in the admin Page List
    1 point
  12. @Ralf alright I'm on it. The new approach is a WireArray events property, that can hold data for one or more events. // get the module $icsgen = wire()->modules->IcsGenerator; // add an event $icsgen->events->add([ 'summary' => 'Event Title 1', 'description' => 'Event body 1', 'dtstart' =>'2033-12-24 12:00', 'dtend' => '2033-12-24 14:00', ]); This is a breaking change, rest of the API stays the same. Here is a working prototype so you can already test it if you like. I aim for a new version that also supports most ICS event properties like last-modified etc. Edit: should be mostly done, just have to add some docs. Maybe someone can test it in Outlook.
    1 point
  13. Hello all, I wanted to share a proof of concept approach on how we can have an infinite scroll pattern without writing Javascript. We can achieve this with htmx. What you will get An overview page with a list of posts (PW pages). On initial page load 5 posts will be shown. When scrolling down and reaching the last post, another 5 posts will be loaded via AJAX in the background and appended after the last post until no more pages are found. Prerequisites You are using the delayed output strategy, with a _main.php appended. Just like using the default site profile when installing ProcessWire You are using markup regions, in my _main.php I have a div#content that will be used for the output of the posts Inside site/config.php $config->useMarkupRegions = true; Inside site/templates/_main.php <!-- main content --> <div id='content'> </div> For script loading I am using a custom $config->bodyScripts FilenameArray Inside site/config.php $config->bodyScripts = new FilenameArray(); Inside site/templates/_main.php before the closing </body> tag <?php foreach ($config->bodyScripts as $file) : ?> <script src="<?= $file ?>"></script> <?php endforeach ?> </body> PW page structure for this tutorial In the page tree I have a parent page "Posts" with template "posts". All child pages of that page have template "post" In the template "posts" settings in the "URLs" tab, check "Allow Page Numbers" and save. Needed for pagination. When viewing the page "Posts" all logic happens inside site/templates/posts.php site/templates/posts.php <?php namespace ProcessWire; // posts.php template file // add htmx js from site/templates/scripts $config->bodyScripts->add($config->urls->templates . 'scripts/htmx.min.js'); $limit = 5; $posts = $pages->find("template=post, limit={$limit}"); $lastPost = $posts->last(); $nextPageUrl = $page->url . $input->pageNumStr((int) $input->pageNum() + 1); $hxAttributes = array(); $hxAttributes[] = 'hx-get="' . $nextPageUrl . '"'; $hxAttributes[] = 'hx-trigger="revealed"'; $hxAttributes[] = 'hx-swap="afterend"'; ?> <?php if (!$config->ajax) : ?> <section pw-append="content" class="posts" hx-headers='{"X-Requested-With": "XMLHttpRequest"}'> <?php endif ?> <?php foreach ($posts as $post) : ?> <article class="post" <?php if ($post == $lastPost) echo implode(' ', $hxAttributes) ?>> <header> <h3><?= $post->title ?></h3> </header> </article> <?php endforeach ?> <?php if ($config->ajax) return $this->halt() ?> <?php if (!$config->ajax) : ?> </section> <?php endif ?> And that is all there is to it. Not a single line of Javascript, thanks to htmx. I followed the infinite scroll pattern from the official htmx examples. Now let's break the code down into easily digestible chunks // add htmx js from site/templates/scripts $config->bodyScripts->add($config->urls->templates . 'scripts/htmx.min.js'); This adds site/templates/scripts/htmx.min.js to our custom $config->bodyScripts FilenameArray so it will be loaded in _main.php. You can get the script here from unpkg.com. $limit = 5; $posts = $pages->find("template=post, limit={$limit}"); Sets our pagination limit to 5 and loads the correct set of posts. $lastPost = $posts->last(); Saves the last post of each set. We use this later to determine whether the htmx attributes should be rendered. $nextPageUrl = $page->url . $input->pageNumStr((int) $input->pageNum() + 1); We are building the link to the next "page" with the next set of posts. Will result in something like "/posts/page2", "/posts/page3" etc. $hxAttributes = array(); $hxAttributes[] = 'hx-get="' . $nextPageUrl . '"'; $hxAttributes[] = 'hx-trigger="revealed"'; $hxAttributes[] = 'hx-swap="afterend"'; Define our htmx attributes as an array. They will be added to every last post's HTML. Note the hx-get attribute which will be the URL for the AJAX call in the background. That request is triggered whenever the last post becomes visible inside the viewport while scrolling down. hx-swap afterend tells htmx to append the next batch of posts after the last post. <?php if (!$config->ajax) : ?> <section pw-append="content" class="posts" hx-headers='{"X-Requested-With": "XMLHttpRequest"}'> <?php endif ?> // and <?php if (!$config->ajax) : ?> </section> <?php endif ?> Renders the wrapping section tag only on initial page load which is a none AJAX request. Note the hx-headers='{"X-Requested-With": "XMLHttpRequest"}'. This adds an additional header to all AJAX requests with htmx. We need this header so ProcessWire understands that it is an AJAX request. Otherwise $config->ajax would always return false. See https://htmx.org/attributes/hx-headers/ for more info <?php foreach ($posts as $post) : ?> <article class="post" <?php if ($post == $lastPost) echo implode(' ', $hxAttributes) ?>> <header> <h3><?= $post->title ?></h3> </header> </article> <?php endforeach ?> Render each posts's HTML. If it is the last post, also render our htmx attributes. For brevity in this example I only output the post title. <?php if ($config->ajax) return $this->halt() ?> For AJAX requests stop execution of the template file and everything that follows. This prevents appending of _main.php for ajax calls. So we only get the desired HTML for the list of posts and no head, footer etc. Summary Compared to other approaches, htmx lets us control all our AJAX logic with a few html attributes. Really neat and concise. Easypeasy. I like that and will surely use an approach like this in future when infinite scroll is needed. What I like in particular is how easy this is implemented with ProcessWire's powerful pagination capabilities. If you have the same page structure, the code in site/templates/posts.php is working out of the box as is. I have this running on a standard PW multilang site profile with additions/amendments mentioned above under "Prerequisites". Here's a visual of the result:
    1 point
  14. Yes it can, but not via the field settings in the GUI. You can put this hook code in site/templates/admin.php above the require($config->paths->core . "admin.php"); line: // sets field checkbox to checked on new pages with template basic-page $wire->addHookAfter('Pages::saveReady', function (HookEvent $event) { /** @var Page $page */ $page = $event->arguments(0); if ($page->isNew() && $page->template->name == 'basic-page') { $page->checkbox = 1; } }); You just need to adjust template and field name. Everytime a new page with that template is created the checkbox will be checked by default. If you have TracyDebugger installed, you can do this with a one-liner in the Tracy console in the backend: $pages->find('template=basic-page, include=all')->each(function($p) { $p->setAndSave('checkbox', 1); });
    1 point
  15. You can use the new getPageListLabel() method of custom page classes to mimic a table-like list: <?php namespace ProcessWire; // placed in /site/classes/BasicPagePage.php class BasicPagePage extends Page { public function getPageListLabel() { return "<span style='display:inline-block;width:200px;outline:1px solid black;'>{$this->id}</span><span style='display:inline-block;width:300px;outline:1px solid black;'>{$this->path}</span>"; } } Brilliant new feature ?
    1 point
  16. So i tried the other way around and formatted a date using the IntlDateFormatter. This thread helped me find my way: https://stackoverflow.com/questions/71874030/local-language-without-strftime-deprecated-but-with-date So imagine we want to output "today" like this (formatted for german) Mittwoch 8 Juni 2022 This was the old way to to it: echo strftime('%A %e %B %Y', strtotime('now')); Since this will be deprecated in PHP 8.1 and removed in PHP 9 now we have to make use of this instead: $fmt = new IntlDateFormatter('de_DE', IntlDateFormatter::FULL, IntlDateFormatter::FULL ); $fmt->setPattern('EEEE d LLLL yyyy'); echo $fmt->format(strtotime("now")); The only thing that freaked my out about this was the weird formatting pattern. At first sight it makes no sense (to me), but the ICU documentation offers a big list of available options for formatting the date in any way you could imagine: https://unicode-org.github.io/icu/userguide/format_parse/datetime/ If you are looking for a "one liner solution" then this seems to be the right way (https://stackoverflow.com/questions/12038558/php-timestamp-into-datetime) echo IntlDateFormatter::formatObject( new DateTime('@' . strtotime("now")), "EEEE d LLLL yyyy", 'de_DE' ); EDIT: Beware that timezone settings get ignored when you work with timestamps. This might get you into some trouble. My solution was to format the timestamp into a date string: echo IntlDateFormatter::formatObject( new DateTime(date("d.m.Y", $timestamp)), "EEEE d LLLL yyyy", 'de_DE' );
    1 point
  17. @Gadgetto Have you seen this? https://github.com/processwire/processwire/blob/dev/wire/core/FieldsTableTools.php#L108
    1 point
  18. Hi guys, I’m writing on a brief editor’s manual what reminds me of a topic I repeatedly stumble upon: What are the exact differences between unpublished, hidden and locked pages? Just to make it clear: There is no problem with checking or setting the status and using the result for whatever. The only thing I don’t really understand is the editor’s view: What is happening with the states beside their usage in my templates? Surprisingly, the otherwise excellent PW docs don’t reveal too much about.
    1 point
  19. Hi, I agree it is a bit hidden, but it is here -> https://processwire.com/api/ref/page/#pwapi-methods-constants.
    1 point
×
×
  • Create New...