Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/06/2021 in all areas

  1. Agreed. Biggest benefits you get from using an external mail service are a) ease of use — which is largely a non-issue for ProcessWire users, since WireMail modules provide a consistent API — and b) confidence that someone else is making sure that your emails are sent, can be received correctly, and don't miss their target or end up in spam. With hosting your own SMTP server there are always potential gotchas, but again if you're on top of things they can be (mostly) avoided. When I say "mostly", I mean things like someone reporting your message as spam, which could become an issue for you. Not much you can do about that, really, except for making sure that your recipient list is full of folks who really want to receive your newsletter ? In addition to what Horst mentioned above, I would recommend using a service such as https://www.mail-tester.com/ to make sure that your messages are a-OK before sending them to actual recipients. Edit: one ProMailer-specific benefit for using external service is that this way you can easily handle bounces and spam complaints etc. ProMailer supports webhooks for this stuff. You can set up a webhook for these without external service as well (at least for bounces, not entirely sure about spam complaints), but it could get tricky ?
    3 points
  2. ProcessWire 3.x markup module for rendering meta tags in HTML document head section. Note that this module is not a full-blown SEO solution, but rather a simple tool for rendering meta tags based on module configuration. Adding custom meta tags is also supported. Built-in meta tags The following meta tags are supported out-of-the-box: Document title consisting of page title and site name Character set Canonical Viewport Description Keywords Hreflang tags Open Graph og:title og:site_name og:type og:url og:description og:image og:image:width og:image:height Twitter meta tags twitter:card twitter:site twitter:creator twitter:title twitter:description twitter:image Facebook meta tags fb:app_id The full documentation with configurable options can be found here: https://github.com/Fokke-/MarkupMetadata Requirements: ProcessWire>=3.0.0 PHP >=7.1 Installation using Composer composer require fokke/markup-metadata Manual installation Download latest version from https://github.com/Fokke-/MarkupMetadata/archive/master.zip Extract module files to site/modules/MarkupMetadata directory.
    2 points
  3. Just noting that I managed to resolve this (non-Tracy-related) problem. My script was getting sucked inside the pw panel markup due to loading order. All I had to do was to move my script markup before my pw panel markup. No more warnings, unnecessary ajax calls, etc ?.
    2 points
  4. Last week we released the new ProcessWire 3.0.184 master/main/stable version. This is our biggest version release in a year. It's been a very smooth stable version launch with no major issues so we're keeping the version number where it is this week. If you haven't upgraded yet, it's an easy and worthwhile upgrade. For full details see the blog post that covers it all. This week I have 3 new Textformatter modules released in the modules directory. These are modules that I developed earlier for recurring needs that I had, but this week decided to finish them up and release them. I hope that you might find one or more of them useful sometime. TextformatterFindReplace This module applies find/replace patterns to formatted text or markup at runtime. The patterns may be simple text or more complex regular expressions. This module can be handy if you perform a text replacement on all output from a particular field, without having to manually make the change on all instances where it might appear. For instance, maybe you need to insert a trademark symbol ™ after every appearance of a brand name, or maybe your website hostname has changed and you need to replace all references to it, or perhaps you need to replace all <h1> headlines with <h2> headlines. These are just a few examples of any number of possibilities. Read more / Usage / Examples TextformatterMarkdownInMarkup Enables you to use Markdown formatting codes in CKEditor (or HTML). A significant amount of content that is populated into the “bodycopy” field of websites is not actually written in the admin and instead originates from text editors, word processors, and other tools outside of the CMS. It then gets pasted into CKEditor, and then manually formatted into HTML using tools in CKEditor. This process of manually converting links, lists, headlines, bold, and italic text and more can be sometimes very time consuming. This module provides a time saving alternative, enabling use of markdown formatted text in CKEditor (or any HTML/richtext editor). It remains as markdown formatted text in the editor, but as soon as it is rendered on the front-end it is automatically formatted as HTML. This means that text like **this** gets converted to this, links like [this](https://processwire.com) get converted to this, and so on for most types of markdown formatting. This enables markdown formatted text to be written anywhere and the formatting to be rendered properly in your bodycopy when viewed on your website. Using this module means that you can mix richtext and markdown in the same copy. No longer do you have to manually convert all of the links, lists, bold/italic, and so on in pasted in text. This module saves me quite a bit of time when writing blog posts like the one last week. Much of the formatting in that post was markdown based, since I wrote the post in my text editor over a period of a couple weeks. Once I got it into CKEditor, I did some formatting with that too, but when it came to other formatting (especially links and inline `code`) it was a big help to have them just work, and not to have to re-do all of them manually with CKEditor tools. So why not just work exclusively in Markdown? Well I don't like working with just markdown most of the time, I much prefer CKEditor. But I also can't deny the convenience of markdown for a lot of cases too. So being able to use Markdown within CKEditor is the best of both worlds, to me at least. Read more / Supported markdown / Configuration options TextformatterEmoji This module converts more than 800 named shortcode emojis in ProcessWire text or textarea fields to the corresponding UTF-8 emoji character. ? This can be especially useful if your ProcessWire database uses the utf8 character set rather than utf8mb4, as it enables you to use emojis on an installation that typically would not be able to save them. This is because emojis usually require utf8mb4 (4 bytes characters) to be used by the database in order to store them. Though when you want to specify an emoji by name, this module will be useful regardless of your database charset. Read more / Supported emojis reference
    2 points
  5. 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.
    1 point
  6. Update - 24.12.2021 After long days of reconsideration and experimenting I will deprecate the current state of Symprowire. I decided to get rid of my trys to integrate the whole Symfony experience as it grew pretty large pretty fast. Whats left you may ask? Well, the project is not dead. I am currently refactoring the whole setup to just use SymfonyHttpFoundation and Twig. I have a working proof right now, but have to polish some things first. The whole setup will come as a simple composer package to get called via a controller.php template file. Much like WireFrame. As you can see in the picture we will use the normal ProcessWire Workflow and just use the normal PageRender process. You as a Developer will get in control if to use the Setup for a particular Template or not. Looking forward to publish the proof. Cheers, Luis Debug Dump WIP 25.12.2021 Symprowire is a PHP MVC Framework based and built on Symfony using ProcessWire 3.x as DBAL and Service-Provider It acts as a Drop-In Replacement Module to handle the Request/Response outside the ProcessWire Admin. Even tough Symfony or any other mature MVC Framework could be intimidating at first, Symprowire tries to abstract Configuration and Symfony Internals away as much as possible to give you a quick start and lift the heavy work for you. The main Goal is to give an easy path to follow an MVC Approach during development with ProcessWire and open up the available eco-system. You can find the GitHub Repo and more Information here: https://github.com/Luis85/symprowire
    1 point
  7. This week we have a new master/main version released after a full year in the making. With nearly 40 pull requests, hundreds of new additions and more than 100 issue reports resolved, this new version has a ton of great new stuff and we’ll cover most of the new stuff here— https://processwire.com/blog/posts/pw-3.0.184-master/
    1 point
  8. I did, only like a a hundred times ?. Maybe I was refreshing the wrong site! I'll give this a go. Thanks for sharing! And the pointers as well.
    1 point
  9. Bear in mind each time you make a change to your .module file you need to refresh modules. Here's a working sample that should get you started. namespace ProcessWire; class ProcessSiteOptions extends Process { private $cmsPath = null; public static function getModuleInfo() { return [ 'title' => __('Site options', __FILE__), 'summary' => __('Custom site options', __FILE__), 'version' => '0.0.1', 'permanent' => false, 'useNavJSON' => true, 'permission' => 'page-edit', 'nav' => [ [ // URls relative to where this admin page is added 'url' => '../page/edit/?id=1023', 'label' => 'Settings', // These labels are HTML entity encoded 'icon' => 'cog' ], [ 'url' => '../page/edit/?id=6601#ProcessPageEditChildren', 'label' => 'Project filters', 'icon' => 'filter', 'navJSON' => 'navJSON' ] ] ]; } public function ___execute() { return $this->render(); } protected function render() { $html = '<p>Manage site options.</p><ul>'; $sanitizer = wire('sanitizer'); $nav = self::getModuleInfo()['nav']; foreach ($nav as $item) { $html .= '<li><a href="' . $sanitizer->entities($item['url']) . '">' . $sanitizer->entities($item['label']) . '</a></li>'; } return $html . '</ul>'; } public function ___executeNavJSON($options = []) { $options = []; $options['list'] = []; // Unlike nav children above these can be dynamic $options['list'] = self::getChildArray(); return json_encode($options); } private function getCMSPath() { // Caches the CMS path return $this->cmsPath === null ? wire('pages')->get(2)->path : $this->cmsPath; } private function getChildArray() { $page = wire('pages')->get('/'); $sanitizer = wire('sanitizer'); return [ ['url' => $this->getCMSPath() . 'foo-bar', 'label' => 'Arbitrary CMS link', 'icon' => 'smile-o'], ['url' => '/about/', 'label' => 'Arbitrary site link', 'icon' => 'user-o'], ['url' => $page->path, 'label' => $sanitizer->entities($page->title), 'icon' => 'home'] // Dynamic; these labels are not HTML entity encoded ]; } A few points: Don't put any comments before the namespace declaration as PW can't pick up on the module info properly As @Robin S pointed out the first level of items are static, the rest (navJSON) can be dynamic Questions (just me being picky/trying to understand): I don't know how you add third-level items, i.e. children on navJSON but I probably don't need these anyway The labels on navJSON aren't HTML encoded but the labels on 'nav' are — why is this? Is it so you can add HTML into the dynamic options? (strong, em) — just wondering why they are different How can you make a link in 'nav' not do anything when clicked — i.e. just act as a parent for the child links (not a big deal, just curious) How can you add a link (in either 'nav' or navJSON) that goes to an external site? I.e. to a different HTTP host
    1 point
  10. If you do not have limitations for outgoing (SMTP) E-Mails per/Day or per/Month and if whether your company nor any other user on the same shared hosting is blacklisted in spam protection services, it should be pretty fine to send them on your own.
    1 point
  11. I posted you a link 2 month ago: I think it can be done with language alternate fields. Have you checked it?
    1 point
  12. I have managed to find the code that is causing the issue. In InputfieldTextTags.js, at the end of the file, the css class '.InputfieldPage' was added, changing the code from this (GitHub 3.0.183 ) // InputfieldTextTags.js ProcessWire 3.0.183 jQuery(document).ready(function($) { InputfieldTextTags(); $(document).on('reloaded', '.InputfieldTextTags', function() { InputfieldTextTags($(this)); }); }); to this (GitHub 3.0.184 ) // InputfieldTextTags.js ProcessWire 3.0.184 jQuery(document).ready(function($) { InputfieldTextTags(); $(document).on('reloaded', '.InputfieldTextTags, .InputfieldPage', function() { // <= '.InputfieldPage' addition causing error(?) InputfieldTextTags($(this)); }); }); I have no solution at the moment ?.
    1 point
  13. @AndZyk, @ryan I can confirm this (?). I have been having a similar issue since I upgraded to 3.0.184 when it was still in dev. Back then, I just assumed the issue was the code in my module. I have since confirmed that by downgrading to 3.0.181, the issue goes away. I'll dig further to find out when it was introduced and what is causing it. In my situation, I am trying to reload/init a fieldset that has been added to an inputfield via ajax. The fieldset contains a multi page field that used Text Tags as the inputfield type. Here's the screenshot of the error: The 'u' token comes from an 'undefined' string in what was supposed to be the JSON response. The use ajax options is not enabled under Text Tags for the page field. I am on WAMP. Thanks.
    1 point
  14. Thank you @ryan for your response. I made some tests and think that I can provide some additional informations to my issue: It is not the browser cache. Incognito mode or reseting didn't help. It is not another module. It was still there after disabling all third party modules. It happens after the upgrade from 3.0.165 to 3.0.184. It worked after upgrading from 3.0.182 to 3.0.184. It probably has something to with the language pack. I got no issue with the default language. The latest language pack (German in my case) still has this issue. So it seems, that something in the InputfieldTextTags module causes a conflict with the translation of language packs. I hope this helps, but as it seems that no one else had this issue so far and it happens only on my local MAMP server, this seems to be an isolated issue. ? Yes, I have posted this issue on GitHub. It would be great, if this could be solved in the future, but until then I just avoid using the new InputfieldTextTags with Selectize.js. ? And thanks again for the new master release. Reading through all the changes again makes you realize how much has changed since the last master release. Regards, Andreas
    1 point
  15. I am confused by this. Surely it should not be necessary to both add the namespace in the Hanna code AND call the function \ProcessWire\myFunction()? So I looked at the TextFormatterHannaCode.module - getPHP() method and found this: $php = '<' . '?php'; $openPHP = $php; $openPHPNS = "$php namespace ProcessWire;"; $firstLine = 'if(!defined("PROCESSWIRE")) die("no direct access");'; if(strpos($code, 'namespace') && preg_match('/(namespace\s+ProcessWire(?:;|\s*;))/', $code, $matches)) { $openPHP = $openPHPNS; $code = str_replace($matches[1], '', $code); } if(strpos($code, $openPHP) !== 0 && strpos($code, $php) !== 0) { // prepend open PHP tag to code if not already present $code = "$openPHP\n$firstLine\n$code"; } else { // otherwise insert our $firstLine security check $code = str_replace($openPHP, "$openPHP\n$firstLine\n", $code); } It seems that the method is removing "namespace ProcessWire;" from the Hanna code. Looking at the cached files shows this to be the case. In other words, adding "namespace ProcessWire;" to the Hanna code is pointless as \ProcessWire\myfunction() is still going to be needed. I really don't know why the above code has been added or what it is trying to achieve?
    1 point
  16. No, I haven't forgotten. The module is still under review. After approval I'll post all links.
    1 point
  17. Thank you for the new master version. ? But after the upgrade from 3.0.165 to 3.0.184 I get an JavaScript error on the field editing page, which results in a blank page: Has anybody else this issue? I think I have to wait for the upgrade a little bit. Regards, Andreas Edit: Ok, this issue seems to only occur on my local MAMP PRO server so far. I try to investigate further. ? Edit 2: By the way, I use to add tags to my fields and templates for better organization. The tags I add have usually capitalization like "Foo" or "Bar". It seems to be an issue with the newly introduced InputfieldTextTags.
    1 point
  18. Hi @elabx, Great point, I hadn't thought of this. When we were using GD for image resizing the WEBPs were often larger than the JPEGs, but we got ImageMagick in place around the time I developed this module and forgot about this quirk. I'll need to do a bit of research before implementing something but I'm a bit swamped at the moment. Will let you know when I figure something out. Cheers, Chris
    1 point
  19. For anyone who is interested in integrating tailwind inside a processwire project here is a little walktrough based on my workflow. This little guide is based on Tailwind 1.9.6 (latest before 2.0 release) because some PostCSS library I use are still not compatible with 2.0 version (not a big deal, really). You can find the necessary files here. - Place package.json, tailwind.config.js, postcss.config.js inside your template folder. - Create a "pcss" folder, and make a structure like this: pcss ├── inc │ ├── colors.pcss │ ├── fonts.pcss │ ├── media_queries │ │ ├── lg.pcss │ │ ├── md.pcss │ │ ├── sm.pcss │ │ └── xl.pcss │ └── sitewide.pcss └── kickstart.pcss Now you got everything to get started, let's have a look at the files: package.json Inside "package.json" you have different dependencies I've installed to mimick my "old" scss workflow (importing, nesting, etc..), the important part however is the script section: "start": "npx tailwindcss build pcss/kickstart.pcss -o css/dist.css", "watch": "npx postcss pcss/kickstart.pcss -o css/dist.css --watch", "build": "cross-env NODE_ENV=production npx postcss pcss/kickstart.pcss -o css/dist.css" "start" is the bootstrap script you have to run at first, to let node compile tailwind as a whole. Do it at the beginning of the project or everytime you make some changes to "tailwind.config.js" Change the name of your pcss files accordingly (I've used pcss as an extension, but css would work perfectly fine) "watch" is the next script you have to run in order to have live reload of your stylesheets. "build" is the script you have to invoke once you are ready to deploy to production (you need to specify your purge rules inside postcss.config.js, keep reading.) tailwind.config.js Here you can specify your tailwind configurations, read the docs here. One thing to notice inside mine is that I've set purge: false because I prefer to configure the purge part inside a dedicated file, which is: postcss.config.js This file is responsible to handle postcss options, and purge is one of them. The paths you declare inside the content array are the ones whom will be scanned and purged eventually. Mine could be different than yours, so pay attention. The whitelistPattern array is useful when you want to exclude some classes from the purge phase, below I'm excluding the ones whom starts with "fff-". ... content: [ './*.php', './inc/*.php', './fields/*/*.php' // etc. ], whitelistPatterns: [ // Pattern to exclude during extraction /^(fff-)/ ], ... The other settings are pretty explanatory (cssnano is used in production for minification). As a final note you'll notice that every pcss file I use starts (and ends) with: /* purgecss start ignore */ css... /* purgecss end ignore */ Those tell purgecss to ignore completely the file, since I know I want to retain every rule/class I write in there. If you got everything setup correctly you can start having fun ? Run: npm install then: npm run start and finally: npm run watch Hope this little "guide" could enlighten in using Tailwind ?
    1 point
  20. hi @kongondo sorry for being unclear. I played around a little and came up with this solution: I think that's a quite good solution. It's easy to type, easy to read and it is efficient, multi-instance ready and supports code completion (and is always in sync with your current pw version)... What do you think? // php.json "Import PW Module": { "prefix": "mod", "body": [ "$$1 = \\$this->wire->modules('$2'); /** @var $2 $$1 */", "$$1$0" ], "description": "Import PW Module" }, "Get Wire Instance": { "prefix": "wire", "body": "$$this->wire->$0", "description": "Get Wire Instance" },
    1 point
  21. I did some more testing and got one step further. You might also be interested in this thread regarding intellisense: I can now answer my question of the day before yesterday: The correct syntax is this: /** @var InputfieldButton $button */ This way you get proper code completion even for your very own variables. @kongondo do you think you could do (or guide me how to do it) a snippet that adds the IDE variable type hints automatically? This could improve the workflow and code completion even more. For example here I define a RockGrid as variable $f and with the /** @var ... */ comment I get the suggestion of "setData()" method for my grid:
    1 point
  22. I have updated the original snippet (variables API) in the Gist. This addresses the > issue reported by @adrian. Typing doesn't change. E.g.g pagesfind vs pages find will return the same suggestion.
    1 point
×
×
  • Create New...