Leaderboard
Popular Content
Showing content with the highest reputation on 12/10/2018 in all areas
-
Hi Sam, there is PageimageManipulator available for PW: With it you can do something like: $imageBase = // get the base image here $imageOverlay = // get the thumbnail overlay image here // first wrap a 50px transparent (rgba) canvas around the overlay image and convert it to png format: $imageOverlay = $imageOverlay->pim2Load("prefix")->canvas($imageOverlay->width + 100, $imageOverlay->height + 100, array(0,0,0,0), "center")->setOutputFormat("png")->save(); // now stretch the overlay image canvas to match the base image dimensions: $imageOverlay = $imageOverlay->pim2Load("prefix")->canvas($imageBase->width, $imageBase->height, array(0,0,0,0), "northwest")->save(); // now merge both images together $imageResult = $imageBase->pim2Load("prefix")->watermarkLogo($imageOverlay, "center", 0)->save(); // The resulting pageimage can also be adjusted using regular pw image functions, if necessary $imageResultThumb = $imageResult->width(150); Better is to chain the manipulations of the overlay image into one call: $imageBase = // get the base image here $imageOverlay = // get the thumbnail overlay image here // two steps to create the canvas with the thumb at the desired position and convert the output to png format: $imageOverlay = $imageOverlay->pim2Load("prefix")->setOutputFormat("png")->canvas($imageOverlay->width + 100, $imageOverlay->height + 100, array(0,0,0,0), "center")->canvas($imageBase->width, $imageBase->height, array(0,0,0,0), "northwest")->save(); // now merge both images together $imageResult = $imageBase->pim2Load("prefix")->watermarkLogo($imageOverlay, "center", 0)->save(); Please refer to the PageimageManipulator page for the documentation of all methods and params, but ask here, if something is not clear. ?4 points
-
Yes I did read the announcement from Ryan regarding the Mail module. I don’t know what features Ryan’s module will provide (it will be for sure a very pro tool), but we have an extremely strong sending engine with multi-processing which can handle a huge set of mails. We tested with about 100.000 subscribers without any problems. Mailings can be sent in a reasonable time. Plus GoodNews will be free.3 points
-
Which Theme/Font is That? Tired of hearing that question when you share a screenshot or a tutorial on YouTube? Your problems are over! ? Introducing "Which Theme is That" Visual Studio Code extension. This extension will show on the status bar your workspace's current theme name and font. Install Grab it here: https://marketplace.visualstudio.com/items?itemName=sjardim.whichthemeisthat How to Run Install the extension and run the Command Palette Ctrl+Shift+P or Cmd+Shift+P on Mac. Search for "Which Theme is That?" and hit Enter. Screenshot Enjoy!2 points
-
Sounds like a job for https://modules.processwire.com/modules/admin-restrict-branch/2 points
-
Hi All, I realise there is work that still needs doing on this module. This includes supporting a full set of selector operators and publishing the support for use in Form Builder. Unfortunately I'm buried deep in some non-PW development at the moment and can't put the time in that's needed, this also explains my absence from the forum for the past month. It is on my radar though and I'll get back to it when I can - probably in late Jan. ?2 points
-
I'm really in love with FormBuilder, but the one thing missing to match all my end users' expectations were repeatable field groups. Think repeaters, in ProcessWire terms. Our primary application of PW is our corporate intranet, so "lines" of fields are quite common in the forms I build. We have all kinds of request forms where the information for a varying number of colleagues needs to be entered (from meal order to flight booking request) and where it is simply impractical to send a form for each, and I don't want to clutter my forms with multiple instances of fields that may only get used ten percent of the time. That's why I started to build FormBuilderMultiplier (link to GitHub). What it does: Adds an option to make a regular Fieldgroup repeatable Lets you limit the number of instances of a Fieldgroup on the form Adds an "Add row" button the form that adds another instance of the Fieldgroup's fields Adds a counter suffix at the end of every affected field's label Stores the entered values just like regular fields Makes the entered values available in preview and email notifications Supports most text based fields, textareas and selects (really, I haven't had enough time to test all the available choices yet) What it doesn't do (yet): Support saving to ProcessWire pages (i.e. real Repeaters) I haven't tested all the validation stuff, Date/Time inputs etc. yet, but since I'm utterly swamped with other stuff at work, I didn't want to wait until I have it polished. Any feedback is welcome. There might also be some issues with different output frameworks that I haven't encountered yet. The forms I work with mostly use UIKit. Status: Still alpha, so test well before using it in the field. Known issues: When rows are added, the form's iframe needs to be resized, which isn't completely clean yet. How it works: The Fieldgroup settings are added through regular hooks, as is the logic that adds the necessary field copies for processing the form and displaying previews. "Multiplied" field instances are suffixed with _NUM, where NUM is an incremental integer starting from 1. So if you have add two fields named "surname" and "givenname" to a fieldgroup and check the "multiply" checkbox, the form will initially have "surname_1" and "givenname_1" field (I'm still considering changing that to make the risk to shoot oneself into the foot by having a regular "surname_1" field somewhere else in the form less likely). When a "row" is added, the first row is cloned through JS and the counter in the fields' IDs, names and "for" attributes as well as the counter in the label are incremented before appending the copies to the Fieldset container in the form. To keep backend and frontend in sync, a hidden field named [name of the fieldset]__multiplier_rows is added to the form. Both the backend and the frontend script use this to store and retrieve the number of "rows". ToDo: Naturally, add the option to store the data in real repeaters when saving to pages. Do a lot of testing (and likely fixing). Make a few things (like the "Add row" button label etc.) configurable in field(set) context. Add a smooth API to retrieve the multiplied values as WireArrays. The mandatory moving screenshot:1 point
-
Hi all, I am new to ProcessWire module development. Just recently getting back to using PW again after a couple of years away from it. I was looking for a SASS/SCSS/Compass pre-processor module for PW and couldn't find any. The closest I could find was AllInOneMinify but it doesn't do SASS/SCSS. I decided to make this module (with heavy inspiration from AOIM). This is a pretty basic module that takes one or more sass/scss/compass file(s) and compile them automatically in your template. Github link https://github.com/lesaff/ProcessWire-Sassify I really appreciate any comments, suggestions, bug fixes, etc. Hopefully this is the first of many modules. Thanks Rudy Note: Added to Modules directory, under http://modules.processwire.com/modules/sassify/1 point
-
Thanks. I'm not completely sure if I read your question right. The screencap above shows the front end form (it's just included in the backend interface on the preview tab, but it's the same as if you embed your form anywhere on the frontend).1 point
-
I think that means that existing keys will not be overwritten, cf WireArray class: public function import($items) { if(!is_array($items) && !self::iterable($items)) throw new WireException('WireArray cannot import non arrays or non-iterable objects'); foreach($items as $key => $value) { if(($k = $this->getItemKey($value)) !== null) $key = $k; if(isset($this->data[$key])) continue; // won't overwrite existing keys $this->set($key, $value); } return $this; } It seems that the line above if(($k = $this->getItemKey($value)) !== null) $key = $k; causes the problem. getItemKey() uses array_search and returns the key of the first value found, so the second, identical value is missed...1 point
-
Ah, yes. As documented here as well: http://processwire.com/api/ref/wire-array/import/1 point
-
No, it behaves in that way when different 'keys' have the same values. One more example $array = WireArray([ 'test' => 'test1', 'test1' => 'test1', 'test2' => 'test2' ]); d($array); count => 2 items => array (2) - test => "test1" (5) - test2 => "test2" (5) Actually, I think that it's a bug in WireArray() function as if use new WireArray() it works as expected $test = [ 'test' => 'test1', 'test1' => 'test1', 'test2' => 'test2' ]; $array = new WireArray(); $array->setArray($test); d($array); count => 3 items => array (3) - test => "test1" (5) - test1 => "test1" (5) - test2 => "test2" (5) Here is code for WireArray(); public static function newInstance($items = null, $class = '') { if(empty($class)) $class = get_called_class(); /** @var WireArray $a */ $a = new $class(); if($items instanceof WireArray) { $items->wire($a); $a->import($items); } else if(is_array($items)) { $a->import($items); } else if($items !== null) { $a->add($items); } return $a; } So the issue is in the usage of import method as it skips any items already present in WireArray.1 point
-
Thanks! It was as it's a pretty simple extension (source below). I followed the VS Code official docs: https://code.visualstudio.com/docs/extensions/example-hello-world and looked at the examples they gave. ? // The module 'vscode' contains the VS Code extensibility API // Import the module and reference it with the alias vscode in your code below const vscode = require('vscode'); // this method is called when your extension is activated // your extension is activated the very first time the command is executed function activate(context) { // Use the console to output diagnostic information (console.log) and errors (console.error) // This line of code will only be executed once when your extension is activated console.log('Congratulations, your extension "whichthemeisthat" is now active!'); // The command has been defined in the package.json file // Now provide the implementation of the command with registerCommand // The commandId parameter must match the command field in package.json let disposable = vscode.commands.registerCommand('extension.whichThemeIsThat', function () { // The code you place here will be executed every time your command is executed // context.subscriptions.push(disposable); // create a new status bar item that we can now manage myStatusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 100); context.subscriptions.push(myStatusBarItem); myStatusBarItem.show(); updateStatusBarItem(); // register some listener that make sure the status bar // item always up-to-date context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(updateStatusBarItem)); context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(updateStatusBarItem)); }); } function updateStatusBarItem() { const theme = vscode.workspace.getConfiguration().get('workbench.colorTheme'); const font = vscode.workspace.getConfiguration().get('editor.fontFamily'); myStatusBarItem.text = '$(eye) Theme: ' + theme + ' + ' + 'Font: ' + font; } exports.activate = activate; // this method is called when your extension is deactivated function deactivate() { } exports.deactivate = deactivate;1 point
-
I updated some dependencies and bugs (e.g. the php 7.2 bug with each() ) in this push request.1 point
-
Agree @Gadgetto what is your goal? What do you want to build? If we knew that it would be easier to help you. You have 3 main options to customize ProcessWire: Hooks in ready.php Very easy, but can get hard to maintain if you have lots of customizations https://processwire.com/blog/posts/processwire-2.6.7-core-updates-and-more/#new-core-files-for-site-hooks Regular modules You can include your own scripts, libraries, hooks etc. You can modify almost anything you want - for example inject custom scripts, modify rendering of fields in the admin, sending emails on special events in the frontend etc... https://github.com/ryancramerdesign/Helloworld Process modules They are used to build custom admin pages in the backend. See my forum + blog post to get a quick introduction. https://github.com/ryancramerdesign/ProcessHello1 point
-
Our sending engine is capable of running multiple parallel send-processes. Therefore the time needed to send out such number of mails can be drastically reduced (of course if your sever can handle the load). I already had a look at the implementation of WireMail. I'll definitely use existing modules as dependencies wherever applicable.1 point
-
That isn't actually necessary; Process module execute methods don't have to be hookable. (Gadgetto, in case you haven't yet looked into the hook system, three underscores are only required if you want to make the function hookable – i.e. allow code in template files, modules, init.php / ready.php files within site directory, etc. to "hook" into their execution. Otherwise it's fine to leave them out.) On a loosely related note, you also don't have to set up your own PHP version comparison. You can define required PHP version with the "requires" setting ?1 point
-
1 point
-
@Leftfield I am happy that you solved your problem ;). Maybe you can consider and few other options to get granularity or selection inside different types of featured posts (favorites). Option 1) Using Autocomplete page reference field Create and place Page Autocomplete field on some template (eg. on home or on some "widget" template). As example, if field "featured" is on Home page: $fav = $homepage->featured->eq(0); // or $homepage->featured->first $favs = $homepage->featured->slice(1); // skip first and get others $cards = $pages->find("template=blog-post, id!={$homepage->featured}"); Option 2) Get pages by priority levels Currently you are going with 3 check fields to get "sticky", "fav", and "favs". There is option how to get the same (checkboxes/radio) with only 1 field, but here I will try to describe (something different) how you can get "granularity" inside featured posts also using 1 field. Create integer field, and as example, set min to 0, and max to 3, and place it on your "blog-post" template. Later, in your code, it's very easy to get desired post by priority level. $fav = $pages->findOne('template=blog-post, priority=3, sort=-blog_date'); $favs = $pages->find('template=blog-post, priority=2, limit=2, sort=-blog_date'); // etc... $all_others = $pages->find('template=blog-post, priority<1, sort=-blog_date'); With this you can "describe the importance" of some post, and later, if it's needed, you can extend that with more levels without additional fields (changing only integer field range). Also with this option you can order posts by priority (sort=-priority). Option 3) Post priority levels with the addition of hooks (need to test) Here is option (for testing) to get on the website only 1 post with priority level 3, and later when someone add new page with the same level (3), previously post automatically would go to level 2, and so on. Here is working example using hooks, but please note that in some situation maybe could not works as expected. Before using this hook, you need to create "priority" field (option 2) and set your template inside hook part. Place this hook inside site/ready.php. // site/ready.php /* Before using this hook please create integer field "priority" and place it on desired template. */ $this->addHookAfter('Pages::saveReady', function(HookEvent $event){ $page = $event->arguments[0]; // if not desired template do nothing // note: set your own template if($page->template != 'blog-post')return; // priority level limit $limit = array( 1 => 3, // priority level 1, allowed max. 3 pages 2 => 2, // priority level 2, allowed max. 2 pages 3 => 1 // priority level 3, allowed max. 1 page ); // processing only if priority has changed and not changed to zero if($page->isChanged('priority') && $page->priority > 0) { $level = 3; // max priority level while($level > 0) { // test with different "sort" selector (eg. -modified, -created, or by custom date field) $group = $this->pages->find("template=blog-post, priority=$level, sort=-modified"); if($level == $page->priority) { $count = $group->has($page) ? $group->count : $group->count + 1; } else { $count = $group->has($page) ? $group->count - 1 : $group->count; } if($count >= $limit[$level]) { for($i = 1; $i <= ($count - $limit[$level]); $i++) { $group->eq($group->count - $i)->setAndSave('priority', $level - 1); } } $level = $level - 1; } } }); Regards.1 point
-
@LuisM Hey Luis, yes I saw it on Github. I'm a little short on time from last week to in a few days, I'm going to get back at you at the PR as soon as possible!1 point
-
@Robin S I don't think there is any particular way to know sort of manual analysis (looking to see what you are currently using). I suppose a crawler or creative find() could be coded up to find all the image sizes currently used on a site, but that's maybe more time and trouble than potential benefit. Though you did just give me the idea that perhaps I could have this module perform a find() on fields like "body" to see if any <img> references to each variation exists, before it matches it. That would be relatively simple. But I think where this tool comes in the most handy is when you are making a change to the dimensions in some Pageimage::size() calls, and you want to clear out the old variations that you know are no longer needed. For instance, I knew very clearly what image sizes I could clear out of the sites directory because I was aware of the dimension change I was making in the code. Of course, if it turns out that some automatically generated image variations were still being used, then PW would just re-create them. Where you'd have to be more careful is with manually-generated variations like custom crops or sizes in a CKEditor field. You can exclude these automatically by using the exclude suffix option, though I'd always recommend using the "dry run" option to see what it's going to delete, before you let it actually delete them.1 point
-
@cb2004 – https://jumplinks.rockett.pw/features/smart-wildcards.html – you'll probably want to use {segments} or {all} here. ?1 point
-
Thomas, I recently found your module, good job. Right now im thinkering with Electron and making Processwire to serve as a headless CMS. So your module is quite handy. I forked the module on GitHub and made it a little bit more connected to Processwire. To sum things up, I creates a "Endpoint Container" in the page tree where you can add your routes and methods. It still needs to add responding classes to provide content ;) I added a skeleton Class called "Blog" to get all contents under the "Home" Page or a specific Page via ID. I created a Pull Request, maybe you like my approach. https://github.com/Luis85/RestApi1 point
-
I'm looking forward to client-side image resizing in PW. I have clients who will upload massive 24-megapixel 10MB images without a second thought. I use the "Max width for uploaded images" option but it's not working reliably because the oversized images still get through somehow (perhaps out-of-memory issues). Anyway, I was looking for a foolproof way for non-tech-savvy clients to resize images and found this: https://bulkresizephotos.com/ Images are resized client-side so it's much faster than many of the other online tools. You can resize multiple images at once and get a ZIP file back with the results. And the best feature is that you can set the tool up how you want and then generate an embeddable drag-and-drop widget, so it's super-easy for clients to use and there are no options for them to mess up. I created a Hanna Code for the widget and added it to the online documentation I supply to clients so it's right there when they need it. Could even potentially be embedded directly in the admin theme. Until client-side resizing comes to PW this is a useful stopgap.1 point