Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 02/19/2024 in all areas

  1. On the dev branch this week we have a good collection of issue fixes and feature requests. The dev branch commit log has all the details. One feature added this week which I think could come in very handy is #520 (via @Jonathan Lahijani) which adds the ability to hide individual images in an images field. When an image is hidden, you can see and work with it in the admin, but it gets removed from the field value on the front-end of the site at runtime, effectively hiding it. I know I'll use this a lot, particularly on photo galleries where I may want to remove an image or two from appearing in the grid of photos, but don't necessarily want to delete them. Images can be hidden (or unhidden) from the Actions select of each image, where you'll see a "Hide" option (or an "Unhide" option if the image is already hidden). Hidden images are also dimmed out when viewing the images field in the admin. On the API side, you can hide or unhide images and files using $image->hidden(true) to hide, $image->hidden(false) to unhide, and $image->hidden() to get a true or false as to whether or not the image is hidden. Though this will only be useful on unformatted field values, since hidden images are automatically removed from formatted field values. The same can be used with regular file fields, but we don't currently have a UI/interface for hiding or unhiding items from regular (non-image) file fields. Likely we'll add one soon, but I figured it's likely to get more use with image fields than file fields, so figured we'd start there. More next week. Thanks for reading and have a great weekend!
    22 points
  2. I was browsing the requests repo and saw a request from @adrian that reminded me of a PW feature I had forgotten existed: from Page List you can open a page for editing in a modal window by long-clicking on the Edit button. This is quite handy for when you want to make a quick edit to a page. But as the request notes, it would speed things up if there was a "Save + Close" button in the modal. Until the request is actioned in the core I thought I'd try implementing it in some custom code, and it's also an opportunity to show an easy way you can add custom JS and CSS to the ProcessWire admin. The first step is to create the following files at /site/templates/admin-assets/admin-custom.js and /site/templates/admin-assets/admin-custom.css. The CSS is optional. admin-custom.js $(document).ready(function() { const $body = $('body'); const is_modal = $body.hasClass('modal') || $body.hasClass('pw-iframe'); if($body.hasClass('ProcessPageEdit') && is_modal) { const params = new URLSearchParams(window.location.search); const $save_button = $('#submit_save'); if(params.has('quick_edit') && $save_button.length) { $save_button.parent().append('<button type="submit" name="submit_save" value="Save" class="ui-button uk-hidden" id="save-and-close">Save + Close</button>'); } } if($body.hasClass('ProcessPageList') && !is_modal) { $(document).on('ajaxComplete', function() { $('.PageListActionEdit a:not([data-autoclose])').each(function() { $(this).attr('data-autoclose', '#save-and-close').attr('href', $(this).attr('href') + '&quick_edit=1'); }); }); } }); admin-custom.css /* Avoid Tracy debugbar appearing on top of modal */ .ui-widget-overlay.ui-front { z-index:40000; } .ui-dialog { z-index:40001; } /* Place modal buttons on the left rather than the right */ .ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float:none; } The second step is to add the following hook to /site/ready.php One good thing about using a hook to AdminTheme::getExtraMarkup to add custom CSS is that the file gets loaded after any CSS files that are loaded by modules or the PW core, so you can override any CSS rules without needing to add extra specificity. // Add custom JS and CSS to admin $wire->addHookAfter('AdminTheme::getExtraMarkup', function(HookEvent $event) { $parts = $event->return; $config = $event->wire()->config; // JS file should exist at /site/templates/admin-assets/admin-custom.js $js_url = $config->urls->templates . 'admin-assets/admin-custom.js'; $modified = filemtime(rtrim($config->paths->root, '/') . $js_url); $parts['head'] .= "<script type='text/javascript' src='$js_url?m=$modified'></script>"; // CSS file should exist at /site/templates/admin-assets/admin-custom.css $css_url = $config->urls->templates . 'admin-assets/admin-custom.css'; $modified = filemtime(rtrim($config->paths->root, '/') . $css_url); $parts['head'] .= "<link rel='stylesheet' href='$css_url?m=$modified'>"; $event->return = $parts; }); The end result:
    11 points
  3. This module won't suit everyone because... It requires what is currently the latest dev version of ProcessWire It requires your server environment have AVIF support Generating AVIF files is slow It offers fewer features than the core provides for WebP It is likely incompatible with the core WebP features so is an either/or prospect ...but it allows for the basic generation and serving of AVIF files until such time as the core provides AVIF features. Auto AVIF Automatically generates AVIF files when image variations are created. The AVIF image format usually provides better compression efficiency than JPG or WebP formats, in many cases producing image files that are significantly smaller in size while also having fewer visible compression artifacts. Requires ProcessWire v3.0.236 or newer. In order to generate AVIF files your environment must have a version of GD or Imagick that supports the AVIF format. If you are using ImageSizerEngineGD (the ProcessWire default) then this means you need PHP 8.1 or newer and an OS that has AVIF support. If you want to use Imagick to generate AVIF files then you must have the core ImageSizerEngineIMagick module installed. The module attempts to detect if your environment supports AVIF and warns you on the module config screen if it finds a problem. Delayed Image Variations Generating AVIF files can be very slow - much slower than creating an equivalent JPG or WebP file. If you want to use this module it's highly recommended that you also install the Delayed Image Variations module so that image variations are created one by one on request rather than all at once before a page renders. Otherwise it's likely that pages with more than a few images will timeout before the AVIF files can be generated. Configuration On the module configuration screen are settings for "Quality (1 – 100)" and "Speed (0 – 9)". These are parameters for the underlying GD and Imagick AVIF generation methods. There is also an option to create AVIF files for existing image variations instead of only new image variations. If you enable this option then all image variations on your site will be recreated the next time they are requested. As per the earlier note, the process of recreating the image variations and the AVIF files is likely to be slow. Usage Just install the module, choose the configuration settings you want, and make the additions to the .htaccess file in the site root described in the next section. How the AVIF files are served The module doesn't have all the features that the ProcessWire core provides for WebP files. It's much simpler and uses .htaccess to serve an AVIF file instead of the original variation file when the visitor's browser supports AVIF and an AVIF file named the same as the variation exists. This may not be compatible with the various approaches the core takes to serving WebP files so you'll want to choose to serve either AVIF files via this module or WebP files via the core but not both. Two additions to the .htaccess file in the site root are needed. 1. Immediately after the RewriteEngine On line: # AutoAvif RewriteCond %{HTTP_ACCEPT} image/avif RewriteCond %{QUERY_STRING} !original=1 RewriteCond %{DOCUMENT_ROOT}/$1.avif -f RewriteRule (.+)\.(jpe?g|png|gif)$ $1.avif [T=image/avif,E=REQUEST_image,L] 2. After the last line: # AutoAvif <IfModule mod_headers.c> Header append Vary Accept env=REQUEST_image </IfModule> <IfModule mod_mime.c> AddType image/avif .avif </IfModule> Opting out of AVIF generation for specific images If you want to prevent an AVIF file being generated and served for a particular image you can hook AutoAvif::allowAvif and set the event return to false. AutoAvif generates an AVIF file when an image variation is being created so the hookable method receives some arguments relating to the resizing of the requested variation. Example: $wire->addHookAfter('AutoAvif::allowAvif', function(HookEvent $event) { $pageimage = $event->arguments(0); // The Pageimage that is being resized $width = $event->arguments(1); // The requested width of the variation $height = $event->arguments(2); // The requested height of the variation $options = $event->arguments(3); // The array of ImageSizer options supplied // You can check things like $pageimage->field, $pageimage->page and $pageimage->ext here... // Don't create an AVIF file if the file extension is PNG if($pageimage->ext === 'png') $event->return = false; }); Deleting an AVIF file If you delete a variation via the "Variations > Delete Checked" option for an image in an Images field then any corresponding AVIF file is also deleted. And if you delete an image then any AVIF files for that image are also deleted. Deleting all AVIF files If needed you can execute this code snippet to delete all AVIF files sitewide. $iterator = new \DirectoryIterator($config->paths->files); foreach($iterator as $dir) { if($dir->isDot() || !$dir->isDir()) continue; $sub_iterator = new \DirectoryIterator($dir->getPathname()); foreach($sub_iterator as $file) { if($file->isDot() || !$file->isFile()) continue; if($file->getExtension() === 'avif') { unlink($file->getPathname()); echo 'Deleted: ' . $file->getFilename() . '<br>'; } } } Saving an original variation file Because requests to images are being rewritten to matching AVIF files where they exist, if you try to save example.500x500.jpg from your browser you will actually save example.500x500.avif. You can prevent the rewrite and load/save the original variation file by adding "original=1" to the query string in the image URL, e.g. example.500x500.jpg?original=1. https://github.com/Toutouwai/AutoAvif https://processwire.com/modules/auto-avif/
    10 points
  4. Hi all, I'm happy to share with you this website we launched two weeks ago for a Swiss movie in pre-production phase. The client wanted to have a blog to document the project and allow users to contribute posts through a form but also with a login to the admin which — once approved — gives them access to more options for their contribution’s content. Right at the beginning they came to us with scientific visualizations as references and thus I finally got to try D3.js. I’ve known about it for a very long time but never got a chance to try it out. It wasn’t easy but in the end I managed to get (what I think is) a pretty satisfying result. And here is a sample of the modules we used: - Fluency ⭐ - TracyDebugger - FormBuilder - RepeaterMatrix - AdminRestrictBranch - FieldtypeOembed - PageRenameOptions - MarkupComponents - Login Magic Link: this is a new one allowing to login with a link sent to the user’s email (inspired by this thread). It’s almost ready to share but I want to create a Process to have an overview of the generated links first Enjoy!
    10 points
  5. I received so much help from kind people on this forum; it’s now my turn to contribute. 😊 I recently had a need for a customer. They have a long list of articles, and they wanted to find any article corresponding to some criteria. They could use the Pages > find tool, which use pageLister, but then they would have to each time select some filters, which can be quite intimidating when you have many fields. So my idea was to create an admin page with the right filters already set. The customer only needs to use some of them. As I found out, this is much simpler than I first thought. So my tutorial is not rocket science, but my hope is that it helps newbies like me to achieve this... 😊 So first, you need to create a simple custom admin page. Bernhard already made a nice tutorial about this, and it’s quite straightforward (like everything in PW ❤️). Here is the code to create this custom admin page in our situation (thanks to Bernhard) : namespace ProcessWire; class ProcessArticlesList extends Process { // Infos about your module and some settings public static function getModuleinfo() { return [ 'title' => 'Articles Admin Page', 'summary' => 'No need to be afraid of building custom admin pages. ;-)', 'author' => 'Your name goes here', 'version' => 1, // you can set permissions here 'permission' => 'meeting-view', 'permissions' => [ 'meeting-view' => 'View Meetings page', ], // page that you want created to execute this module 'page' => [ // your page will be online at /processwire/articles/ 'name' => 'articles', // page title for this admin-page 'title' => 'Articles', ], ]; } public function ___execute() { // the logic goes here } } So, with this code, you get a new module that will produce a blank page. You have now to create a ProcessArticlesList folder inside that file in the site/modules folder and put your new file inside. Then, activate your module. The ___execute() method will run on page load. It’s supposed to return a string which will be your page content. Now things get quite... simple! 😄 The idea is to run an instance of ProcessPageLister, with custom parameters. You can find all these parameters in /wire/modules/Process/ProcessPageLister/ProcessPageLister.module (there are comments that really help you) and you can also have a look at the API doc about ProcessPageLister. Here is an example that covered my needs : public function ___execute() { // this is to avoid error detection in your IDE /** @var \ProcessPageLister $lister */ // get the module, so that you can use it the way you want. $lister = $this->modules->get("ProcessPageLister"); // from here, the comments in the source file were self explanatory, so I found how to cover my needs // filter all pages with the "meeting" template. This filter is by default, won’t show // in the filter list and cannot be changed. $lister->set('initSelector', "template=meeting"); // Then I set 3 filters, left blank, so that the user has just to fill them – or leave them blank $lister->set('defaultSelector', "title%=, themes.title%=, text%="); // Disallow bookmark creation. In my use case, there was no sense for that. $lister->set('allowBookmarks', false); // let the table be full width $lister->set('responsiveTable', false); // use the custom order defined by the user by moving the pages in the page tree $lister->set('defaultSort', 'sort'); // and just show the configured filter on the page. return $lister->execute(); } As you can see, there are 7 lines of specific code to achieve that. How elegant! 🥰 Hope that it is helpful to someone somehow. Cheers Thomas
    9 points
  6. Fantastic @Robin S - I hadn't been paying attention to AVIF browser support for a while, but it looks like we are finally good to go: https://caniuse.com/avif Just a minor thing but I just added AVIF support reporting in Tracy:
    7 points
  7. As of today, this is now a native feature on the dev branch: https://github.com/processwire/processwire-requests/issues/520#issuecomment-1961794624
    4 points
  8. I have no idea how Tailwind works but when I need something like this I usually set a CSS variable and add them with the style attribute where needed. Something like: <?php namespace ProcessWire; ?> <div style="--color: <?= $page->color ?>"><!-- My content --></div> When I need something more complex, say a CSS animation depending on some of the page parameters (e.g. children count) then I output in a <style> element within my template.
    4 points
  9. Very interesting concept, and works nicely! ... but I have to admit that I spent a few minutes trying to figure out how to actually view any content. Clicked the labels, nothing came up, clicked other labels, lines came up but still nothing else, etc. Would've given up if I hadn't known from the screenshots here that there is more to see. I get it now (you have to click those unlabeled sections at the outermost layer of the wheel; assumed at first that they were just a visual thing since there was nothing on them) but you might want to consider giving those sections some kind of label as well. Or add a help text or something. Just a suggestion 🙂 Anyway, always great to see projects that dare to be different.
    4 points
  10. With Geffen Playhouse for example, which was launched in 2019 right before custom fields for files/images was introduced, we needed custom fields for images. At the time, the best approach was to use the RepeaterImages module, which uses repeaters and all the functionality that comes with it. This includes the ability enable/disable a repeater item. In a recent update, I wanted to remove that dependency and switch to just a normal images field with custom fields, but the client still wanted enable/disable capability on images, hence my approach to it described in this post. I think about it just like repeaters. There are times when you want a piece of data to exist but not be visible. Without being able to disable an image, you would have to delete it (or do some other weird hack like perhaps add an image tag), which is less than ideal. With enable/disable capability, it brings it more in line with how multi-item fields, like repeaters, work.
    3 points
  11. $d = strtotime('next monday +7 days'); echo date('Y-m-d', $d); Seems to work for me.
    3 points
  12. A module for generating and serving AVIF files:
    3 points
  13. I should give you guys an early access to our websites in the Beer Garden lol Thank you though for the valuable feedbacks, it’s the kind of things you can have a hard time to see once you’re deep into projects with unconventional design: you get used to it and think it’s “understandable” enough. I went ahead and made the grey text darker and I’ve displayed the title in the center when you hover the outer strands. I also increased the contrast when hovering these. I hope this will do. Please don’t look at my code 🫥
    3 points
  14. Interesting concept. I'm with Bernhard when he suggested making the help text fixed in the middle. Half of the time the instructions are upside down (being in the bottom half of the screen) and moving - so hard to read unless you wait for it to make it back up. Could also do with some more contrast for those of us with slightly compromised sight. Thanks for sharing though.
    3 points
  15. Same experience as Teppo for me. Without his comment I would have not made it to show any content at all. For example when I click on "Full Spectrum" this happens: I really didn't get that I now have to click on one of the outer rings... Maybe you could show a message in these cases in the middle of the circle - something like "Click one of the outer rings to show content" ? Or Just show the first outer circle by default? Hats off for mastering D3.js 😅
    3 points
  16. Hi everyone. Padloper 009 is ready! The release has been delayed by issues with my site. It is currently offline as I work on upgrading it. I hit a number of issues which I am currently resolving. I am hoping this won't extend beyond two weeks. I request your patience please, thanks. Best.
    3 points
  17. Thx Robin! While the Save + Close button is there (as expected), the js part makes the edit links all open home page, eg. they all have the link /processwire/page/edit/?id=1&quick_edit=1 I fixed that with: const $links = $('.PageListActionEdit a:not([data-autoclose])'); $links.each(function() { $link = $(this); $link.attr('data-autoclose', '#save-and-close').attr('href', $link.attr('href') + '&quick_edit=1'); }); Just to mention that using uk-hidden class (as a "belt and suspender" approach) would only work in AdminThemeUIkit, leaving out newer (and older) admin themes.
    2 points
  18. Thank you for this @TomPich always good to see people giving back to the community, much appreciated!
    2 points
  19. Hi @ngrmm Thank you so much. Your information and reference link helped to me. it is worked perfectly.
    2 points
  20. @SIERRA i think repeater items are actually pages. They are somewhere down the site tree branch of the admin page. So you could change the select field in your Test2 Repeater into a page reference field first Then you would use a hook to make those pages be selectable. Maybe it's even possible through the page reference, look here:
    2 points
  21. Sure! In your js: window.addEventListener("load", () => { const headers = new Headers({"X-Requested-With": "XMLHttpRequest"}); // needed for $config->ajax to work const links = document.querySelectorAll("a.ajax"); const main = document.querySelector("main"); for(let i = 0; i < links.length; i++) { links[i].addEventListener("click", async (e) => { e.preventDefault(); loadPage(e.currentTarget.href); }); } async function loadPage(url, options) { const page = await fetch(url, { headers }); main.innerHTML = await page.text(); } }); And in your php: <?php namespace ProcessWire; ?> <?php if(!$config->ajax): ?> <main pw-id="main" pw-append> <?php endif; ?> <article><!-- Your content --></article> <?php if(!$config->ajax): ?> </main> <?php endif; ?> <?php if($config->ajax) exit; When opening the page directly it will go the usual route, outputting your content within <main> but if requested with ajax then it will only send the content and exit() so no other file is appended (_main.php in my case).
    2 points
  22. That is an interesting idea to handle fetching data. Would you mind showing us a short code example? I am planning to do the same in a project. Besides from that the the page you built is very avant-garde! It's kind of cool to see that designers go unusual and experimental ways in webdesign. It reminds me of the early days of the internet. Bedsides from that I have to admit - I also had my struggles understanding how navigating this website actually works 🙂
    2 points
  23. I guess best would be to either have a help popup, which I’m not fond of, or display the help text differently. I’ll stick with this for now as I think I’ve made enough changes but maybe I’ll come back to this later on. Thank you again for all the feedbacks. My bad on this one, thanks for pointing it out.
    2 points
  24. https://github.com/baumrock/AdminStyleRock is the way to go. You can override all uikit variables, for example this: @global-font-size: 30px;
    2 points
  25. There is actually a help text: the one on the rotating circle inside (desktop) / outside (mobile) but it’s dismissed after the first click wherever. I’m going to change it so it remains as long as you didn’t click on a “post” strand. Also, were you on mobile when seeing the website? It’s a tougher UI there for sure without hover... If not, did you notice the title of the post appearing in the bottom bar when hovering a strand? Maybe I could add at least a title="Open ”Title of the post”" so you have another hint when hovering. In any case, thank you for you comment @teppo! Edit: changes applied 🙂
    2 points
  26. The issue is fixed now in a commit on the dev branch: https://github.com/processwire/processwire/commit/3e90cb74faa46b63ff9b5920d1c4e5b971aac591
    2 points
  27. View at: https://okeowoaderemi.com I switched to Processwire 10 years ago and it's being my goto framework for maintaining my website and also developing for clients. Development I used the moduleTemplateEngineFactory and TemplateEngineTwig, Twig has always been my favourite templating engine, because of how easy it is, to use reusable code and have an easy way to inject content into the layout, it's almost like MasterPages in .NET (For the Oldies)
    2 points
  28. Maybe there is something for this already in the API, or elsewhere, but I couldn't find it, so here is my suggestion. The problem is that you can't simply copy the repeater using the API in the usual way: $page2->repeater = $page1->repeater; appears to work for page 2 but messes up page1 where the repeaters get duplicated. Instead you have to copy over each of the field values within each repeater item. So I wrote this. It seems to work, at least in my context. I placed it in init.php. (However, it would be better if the core handled this more intuitively 😁) /** * Copies a repeater field to another page * Operates on the RepeaterPageArray object e.g. $page->repeater->copyTo($page2) * * @param HookEvent $event * */ wire()->addHook('RepeaterPageArray::copyTo', function ($event) { $repeater = $event->object; $repeaterField = $repeater->getForField(); $page = $event->arguments(0); if(!$page->hasField($repeaterField)) { $event->error("Field $repeaterField does not exist on page"); return; } $page->of(false); foreach ($repeater as $item) { $newItem = $page->$repeaterField->getNew(); foreach($item->getFields() as $f) { $newItem->$f = $item->$f; } $newItem->save(); $page->$repeaterField->add($newItem); } $page->save(); });
    2 points
  29. @Tintifax I recently had the same requirement: { "color_map": [ "595885", "Purple", "6a905e", "Green" ], "custom_colors": false }
    2 points
  30. I'm experiencing this in production, not with Laravel. It appears to happen when the path has an empty segment, e.g. https://gregorlove.com//xmlrpc.php?rsd This isn't a valid URL on my site, I know it's just someone scanning for vulnerabilities, but I saw this error in the Tracy logs: Warning: Undefined array key "path" in /site/assets/cache/FileCompiler/site/modules/TracyDebugger/TracyDebugger.module.php on line 2865 Deprecated: explode(): Passing null to parameter #2 ($string) of type string is deprecated in /site/assets/cache/FileCompiler/site/modules/TracyDebugger/TracyDebugger.module.php on line 2865 ProcessWire: 3.0.210 PHP: 8.1.27 TracyDebugger: 4.25.17 Update: The issue appears to be that `REQUEST_URI` in this instance is `//xmlrpc.php?rsd`. Running parse_url() on that does not return a path segment because it parses `xmlrpc.php` as the host and `?rsd` as the query. The following explode() line expects that path. I think there needs to be some more sanitization before using the result of that parse_url().
    1 point
  31. A useful feature indeed! Thanks Ryan and Jonathan!
    1 point
  32. Hi @SIERRA, I guess you have to find a solution for this via hooks. May be you can use https://processwire.com/api/ref/inputfield/get-errors/ or other error methos. Take your time and have a look at the API docs And please avoid duplicate questions, thanks!
    1 point
  33. The TailwindCSS JIT compiler scans the source code rather than the html output, so it's looking for full class names in your PHP code. Hence you could do something like this: <?php namespace Processwire; $bg = $page->bgSetting === "success" ? "bg-green-500" : "bg-red-500"; ?> <div class="mt-4 max-w-md <?= $bg ?>"> Lorem ipsum dolor sit amet consectetur adipisicing </div> Or you could simply fake safelisting the expected values, e.g. in a comment if you just have a few you want to make available in a template: <?php namespace Processwire; $bg = $page->bgSetting === "success" ? "green-500" : "red-500"; /** safelist values: bg-red-500 bg-green-500 bg-blue-500 */ ?> <div class="mt-4 max-w-md bg-<?= $bg ?>"> Lorem ipsum dolor sit amet consectetur adipisicing </div> As long as the full string of the class name is in the code, it will get compiled by TW (use spaces between if you're using this method though, as if you were adding classes directly). (Of course there's also Tailwind's safelist setting in the tailwind.config file: https://tailwindcss.com/docs/content-configuration#safelisting-classes) Ian.
    1 point
  34. Not sure I entirely understand the question, but it sounds like you need Hanna code.
    1 point
  35. @monollonom nice work! Do you use PWs $config->ajax in the templates or is the content switching done completely with custom js?
    1 point
  36. Just to add another solution to the original question, this is how I hide not editable pages in admin tree: $this->addHookAfter('Page::listable', isPageListable(...)); function isPageListable(HookEvent $event): void { if ($event->page->path == "/") $event->return = true; else $event->return = wire()->user->hasPermission("page-edit", $event->page); }
    1 point
  37. Hey Robin! Thanks for this. I haven't had time to test this, but looking the code I see uk-hidden class on button. Would button even show? (and I know it's there for a reason)
    1 point
  38. This week continued the addition of new feature requests and PRs, and the version number has been bumped to 3.0.236. In fact, the addition of feature requests is the theme of version 3.0.236. My favorite addition for this week is probably feature request #474 which adds support for opening and collapsing family groups of repeater items together as one. To enable, see the field "Details" tab setting in "Repeater depths/indents" > "Open/close items as a family?". The same commit also made it possible to disable the automatic scrolling to new repeater items when you click the "Add" button, should that suit your need. Both of these updates also apply to Repeater Matrix as well, but don't require a Repeater Matrix upgrade. More updates can be found in the dev branch commit log, and ProcessWire Weekly has great coverage of what's new with version 3.0.236 in issues #507, #508 and #509. Thanks for reading and have a great weekend!
    1 point
  39. Hi everyone! Is it possible to limit the available colors using 'forecolor' in the TinyMCE toolbar? thank you in advance for your help. Greetings!
    1 point
  40. @Stefanowitsch in the 'Input' tab of the field settings, there is a 'Custom settings JSON' area. You can put it in the 'JSON text' field, or if you need to reuse it, create a file on your server add the above to the file and point to it using the 'JSON file' option.
    1 point
  41. Hi @bernhard, I discovered some more information which might help with troubleshooting. I came across this post which seemed to be related: https://processwire.com/talk/topic/29225-solved-show-this-field-only-if-doesnt-seem-to-work/. As mentioned in that post, if I use Alfred on the front end, or choose "Edit in new window" from the admin side, the changed information does indeed get saved. Only when editing the blocks in the admin in 'repeater mode' does the 'showIf' information not get saved. I hope that points you in the right direction (and for now I have a workaround!) Thx, Ian.
    1 point
  42. Hello, Since this is a core issue, I recommend opening an issue for this at processwire-issues.
    1 point
  43. Hi, I personally dont remember how the whole thing works, I suggest you to try @Juergen form if you can’t afford the paid v2 maintained by Ryan.
    1 point
  44. Hey All, I thought I'd jump on here and share my first 3 ProcessWire sites! LatticeWork (https://www.latticeworkinc.com/) - This one is live but still being actively developed in preparation for targeting an international audience (so current translations need auditing and it's not yet GDPR-compliant). The multilingual capabilities offered by ProcessWire, in contrast to WordPress, were the catalyst for starting my PW journey. The added performance that will be necessary as we deprecate some international sites and push everyone here was another decision driver for choosing PW. Obviously many thanks to @ryan and other core contributors for such an incredibly refined core product that regularly surprises me with features and functionality that I didn't know I was missing. Additional thanks go to @FireWire for the Fluency add-on, @Mike Rockett for Jumplinks, @Wanze for SEO Maestro, @teppo for Search Engine, and again Ryan for Pro Fields. These were invaluable. The Mart Group (https://www.martgroup.com/) - This site was my second to build with ProcessWire, though it was completed first due to its smaller size. In addition to all the prior thanks, I really appreciated RockFrontend by @bernhard while working on this one. Lori H. Cole (https://www.editsbylori.com/) - I probably wouldn't mention this single-page site I built as a favor, except to point out that PW is so lean and easy to work with I was able to give the client the ability to edit their own site without much server overhead or added development time. I did the front-end development work on these, which as a designer/animator hasn't historically been an area I'm comfortable in. ProcessWire has been such a delight to use that it has re-kindled my interest in working more with code. So, in time I hope to get more creative with the front-end coding as well. Thanks!
    1 point
  45. Version 1.3.0 ist out! This version supports mail sending with Postmark mail sending service. Read the full changelog.md for more information about Postmark and what has been changed. If you have one of the Postmark modules as mentioned in the changelog installed, you will find a new configuration field inside the module configuration. Here you can select if you want to send your mails with Postmark or not. Selecting "none" means using the default WireMail class for sending mails. In order to work properly, you will need at least FrontendForms 2.1.57 installed (as mentiond in the changelog.md). As always, this is Beta-status, so please take care that everything works as expected. Happy testing! 😃 Jürgen
    1 point
  46. I asked it: "What language model are you based on?" It replied: "Hello! I'm based on the LLaMA model (LLaMA: Open and Efficient Foundation Language Models, Touvron et al. 2023), a neutral and respectful AI assistant developed by the company Brave. I'm here to help answer your questions to the best of my ability. How may I assist you today?" Next I asked: "Please describe what ProcessWire is." Replied: "ProcessWire is a powerful and flexible open-source content management system (CMS) that offers a unique and intuitive way of managing your website's content and structure. It is built with PHP and MySQL, and is designed to be lightweight, fast, and easy to use. With ProcessWire, you can create complex websites with ease, using a logical and intuitive page tree structure that makes it easy to organize and manage your content. Additionally, ProcessWire has a robust set of features, including support for templates, layouts, and modules, making it a great choice for building custom websites." Next I asked: "Where can I download ProcessWire?" Reply was: "ProcessWire is a free, open-source content management system (CMS) that you can download from the official ProcessWire website. To download ProcessWire, please visit the following link: <https://processwire.com/download/>. From there, you can select the version of ProcessWire that best suits your needs and download it to your computer. Once you have downloaded the software, you can install it on your web server and start using it to manage your website."
    1 point
  47. Yeah the same technique applies to custom page classes as well. Just add methods there with a talking name and your code will get a lot cleaner and better. Think for example of a situation where you are using $pages->find("template=something") in your template files in several spots and you realise that you forgot to change the sort order to random. When using $pages->find() in your template files you need to find all instances and change the code there. When using $page->findRandomSomething() you simply change the logic in your custom page classes method and everywhere it will be changed immediately. Check out my videos on youtube for that topic: 1) https://www.youtube.com/watch?v=7CoIj--u4ps&t=2124s 2) https://www.youtube.com/watch?v=D651-w95M0A
    1 point
  48. Does this help? https://processwire.com/blog/posts/processwire-3.0.107-core-updates/#trash-for-all Found here:
    1 point
  49. Ok. 1. We need to generate a unique token for a user and store it. The simple way to do that is to add a field to user page (login_token in the example). To make process easier we make a method for that via hook: // site/init.php $wire->addHook("User()::getToken", function(HookEvent $event) { $page = $event->object; if (empty($page->login_token)) { $page->of(false); $page->login_token = generateToken(12); $page->save(); $page->of(true); } return $event->return = $page->login_token; }); The genereateToken() function is yours to implement as you wish. 2. Now we can generate a link: $link = $page->httpUrl . "?user=". $user->id . "&token=". $user->getToken(); 3. Finally we need to handle those parameters and make user autologin: // site/templates/_init.php if ($userToLoginId = $sanitizer->int($input->get->user)) { $url = $page->url; $userToLogin = $users->get($userToLoginId); $tokenToLoginWith = $sanitizer->text($input->get->token); if ($userToLogin->id && $tokenToLoginWith && strcmp($userToLogin->login_token, $tokenToLoginWith) == 0) { $loggedInUser = $session->forceLogin($userToLogin); if ($loggedInUser) { $user = $loggedInUser; }; $session->redirect($url); } } We can then nullify user token if we want it to be only a one-time ticket. I rewrote whole lot of stuff, so might not work straight away, but surely you can fix it @szabesz)) Hope I am not missing something essential.
    1 point
  50. I am sure it does. But the point here is that i made something because i wanted to try it with PHP and to do one thing very good. Not everything has to be a module. This script is not meant to be a swizz army knife. The point is to experiment, and share my findings so others could see have they could use PHP in different ways.
    1 point
×
×
  • Create New...