Leaderboard
Popular Content
Showing content with the highest reputation on 04/10/2020 in all areas
-
Last week I posted in the blog about current projects in progress, and consistent with that, this week I’ve been working primarily on the upgrades to our file/image fields. To start, this focuses on storing additional info in the DB table, including file size, created/modified user info, and for image fields: width and height. This is useful in making these properties searchable from page-finding selectors, but also a necessary pre-requisite to supporting external file systems. A “ratio” floating point property is now available on image fields as well (and also stored in the DB) and this value reflects the width divided by the height. This is a searchable property and will be useful for quickly finding portrait images, landscape images, square images, or any proportion you need to find. If you want to find images that are at least twice as wide as they are tall, then you’d be looking for a “ratio” of 2.0 or larger (“ratio>=2”). If you needed to find perfectly square images (i.e. 300x300) then you’d be looking for a ratio of 1.0. If you needed to find portrait images, then you’d be looking for images with a ratio under 1.0 (or twice as tall as wide would be 0.5). You can figure out what ratio you are looking for just by taking your target width and dividing by your target height. Longer term, combined with the other added properties, the goal is that this will help with finding pages that have images suitable for specific placements, proportions and dimensions. These new properties won’t be useful at first on existing sites because the data just isn’t present in the DB, even if the columns to store them are. They are populated over time whenever the page is saved. But I’m going to enable an option to have it populate all of this automatically whenever the field is even loaded. It’s actually there in the core right now, but I’ve got it disabled so I can test it out on a few more of my installations before others start using it. There were some other upgrades to the core as well, including improvements to the Selector and Selectors classes, addition of a $database->columnExists() method, lots of new (mostly internal) methods in FIeldtypeFile/FieldtypeImage, and some refactoring of the FieldtypeMulti class, among other minor updates. While there were a lot of changes and additions this week, it’s not stuff that you’ll likely be using right away, so I’m going to hold off on bumping the version till next week. Thanks for reading and have a great weekend!11 points
-
Hey Ryan — just wanted to say thanks. Assuming that I've got this right and this could mean that eventually ProcessWire can natively (or at least with a module that doesn't have to rely on any weird tricks) support something like S3 or Google Cloud Storage, this is a brilliant move! Very much looking forward to that. Thanks again, and keep up the great work ?5 points
-
Hi Ryan, as always great to hear about the progress ? I have no idea how that will work internally, but this sounds like it might be a good time to also think about having a setting for a custom storage path in core file fields. Maybe that will be possible anyhow by default (like providing an external file system driver that actually stores files on the local file system). But if not this would be a huge improvement in many cases: File fields in module config File uploads with custom storage path in processModules Maybe having a file field on multiple pages sharing one single storage location (like a global gallery) Thx ?5 points
-
... ...and show it visually! Following is a snippet, not a tutorial. But maybe it is useful for someone. Everyone knows the possibility to define a checkbox as required. However, a submit button would then visually execute the click movements and show the active color on hover. Depending on the status of the checkbox, you can either disable the functionality of the submit button via CSS ( pointer-events: none; ), or display a not-allowed cursor. But IMO, each of the two is asking for the other. If you embed the button in a wrapper element, you can marry both of them together. <fieldset class='gdprconsent'> <input type='checkbox' name='gdprconsent' id='gdprconsent' required='required' autocomplete='off' /> <label for='gdprconsent'>I agree to the privacy policy.</label> <div class='submitWrapper'> <input type='submit' name='submit' id='submit' value='Submit'> </div> </fieldset> #gdprconsent:not(:checked) ~ div.submitWrapper { cursor: not-allowed; } #gdprconsent:not(:checked) ~ div.submitWrapper > input[type='submit'] { pointer-events: none; } #gdprconsent:checked ~ div.submitWrapper > input[type='submit'] { cursor: pointer; }5 points
-
Disclaimer: please note that this is how I am doing it, it may or may not suit you, so take it with a grain of salt. Also, I apologize for not obeying ProcessWire's code style, I'm just too old and it feels alien to me. Thing I'm trying to get: not having to input the 'Custom Editor CSS File ...' and 'Custom Editor JS Styles Set ....' for each of the fields using CKEditor. Yeah, I know, call me lazy or sloppy or whatever, it is what it is ? . having the front end styles in the editor container, so the one editing the page would be able to eyeball the styling of the content while stayin in the editor For the first objective I tried to find a way in the CKEditor configuration options, like config.js, or at least a single point to set my options. In the end, what worked for me was hooking the Inputfield in ready.php: if (strpos($_SERVER['REQUEST_URI'], $config->urls->admin) !== 0) { // things I do to frontend pages, believe me, you don't want to know :D } else { $wire->addHookBefore('InputfieldWrapper::renderInputfield', function($event) { // process further if it is an InputfieldCKEditor if (strpos($event->arguments(0)->className(), 'InputfieldCKEditor') === 0) { // store the Inputfield $inputfield = $event->arguments(0); // my custom CKEditor options $my_settings = [ 'contentsCss' => '/site/assets/css/cke.css', 'contentsInlineCss' => '/site/assets/css/cke_inline.css', 'stylesSet' => 'mystyles:/site/modules/InputfieldCKEditor/mystyles.js', 'extraAllowedContent' => '*[id](*); audio[src,controls,preload]; source[src,type]; button[title]; script; i[data-feather]; svg[xmlns,height,width]; path[d,fill,stroke]', ]; // for each option, check if it's empty and if it is set it to the custom value foreach ($my_settings as $key => $value) { if (empty($inputfield->get($key))) { $inputfield->set($key, $value); } } // get the changes into $event $event->arguments(0, $inputfield); } }); } Now, my CSS files are generated by Sass in the /site/assets/css/ directory, because of the second objective. Thus, I'm including the frontend CSS in three places: the two custom CSS files used by CKeditor in regular/inline mode and defined above ('contentsCss' and 'contentsInlineCss' options), and my custom CSS file used by admin.php. The regular mode CSS files contains: // cke.sass - Sass syntax @import "main" where main.sass is my frontend Sass file (I have a real talent for names, I know). So it includes all the frontend styles in the regular CKEditor iframe. The inline mode CSS file contains: // cke_inline.sass .cke_editable_inline @import "main" This way the frontend styles are applied only to elements inside the CKEditor inline container. I know I'm tying myself to the CKEditor markup, but as you may have noticed by now, I'm quite eager to sell myself in slavery for a bit of convenience ? . The admin styles are built the same, changing only the container class and adding some styles to increase readability: // admin.sass /* force a min width for CKEditor combo, so I can read the text */ .cke_combopanel min-height: 21rem min-width: 25rem > iframe height: 100% !important .cke @import "main" The resulting /site/assets/css/admin.css file is loaded by /site/templates/admin.php by adding $config->styles->add($config->urls->assets.'css/admin.css'); before the require($config->paths->adminTemplates . 'controller.php'); line. Lo and behold, Bulma styles available in the editor toolbar and container (there's a short clip attached). Well, this should be it. I hope it helps someone. If you know a better way to do this or if you notice a mistake/omission, by all means, let me know. Thank you for following me until now - here's the medal you rightly deserve: ? LATER EDIT: sorry about the video size, I swear it's just a little 578x472px video. ckeditor-2020-04-10-161245.mp43 points
-
1 point
-
You can use d() from a template file like you are doing in that screenshot, but you might find it cleaner to use bd() AKA "barDump" in that situation so that the dumps are shown in the Tracy bar. The main time I use d() is in the Console panel like in Bernhard's example.1 point
-
We're finally launching a redesign of our website! Doesn't feel like it to us, but our previous design was already from 2013 ? https://ed-works.com/ We like to keep things simple, so the only third-party modules that we installed were Tracy debugger, Admin on steroids and Admin Theme Boss, which we tweaked a little bit to our taste. All in all, there's not much going on inside PW. Our main concern was to serve the frontend with responsive images with a close quality to the originals, and for this, it's important that PW allows us to use ImageMagick for resizing them. We also love to use PW's image tags to add classes to the images. In this case, we use them to display the images with three different sizes. We also had to change the templates to serve the projects to the homepage via Ajax. We hope you guys like our new baby ? Edit: I forgot to refer that we also changed our logo and tweaked our name to ED works.1 point
-
Hi @jonatan, Nice one! No thanks required - you've highlighted issues which has made the module significantly better! Cheers, Chris1 point
-
thank you @bernhard, thank you @Sephiroth. Now I know it is worth to learn the basics and more. I look forward to get my handys dirty in "hello worlds". @Sephiroth, I am interested in your PW video content for my education. Now am busy reading the resources for beginners. Enough for me right now ?1 point
-
Hi @LAPS, I've added a setCampaign() method. It is essentially an alias for addTags(), but takes multiple string arguments instead of an array like addTags(). <?php $mg->to("an@email.com") ->subject"A Subject") ->setCampaign("campaign1", "campaign1-a", "testing") ->bodyHTML("<p>A Message</p>") ->send(); It also enables open and click tracking by default, as this is presumably behaviour you want for campaign analytics. If this isn't required, using addTags() is the way to go, but you can also pass false as the first argument to disable this behaviour and use whatever tracking settings you have by default. Cheers, Chris1 point
-
Exactly, however *shameless insert* , I am working on Screencasting and creating Processwire video contents both for beginners till Advanced level, a bit of me is wondering if it is something that will received by the community. I am currently honing my Video editing skills back. Do you think the community might find this useful. I have always wanted to contribute PW resources since I tend to spend alot of time around the code. Thanks1 point
-
Here "content" is my repeater matrix field. See the first dump - it shows the selector used. If you take that selector you get all items (including unpublished). If you do a status>1 you'll get all that are not regularly published (means hidden etc). Doing status>= Page::statusUnpublished would show only unpublished items (not sure if that makes a difference to status>1). And I'm also sceptical if repeaters are the best option here compared to using regular pages ?1 point
-
Absolutely love your website @diogo! I've looked at it multiple times for inspiration! Such a nice and inspiring portfolio!1 point
-
I don't see why you can't in Processwire, you have can your Business Logic as you would in any PHP Application, but only using Processwire API to handle the information you collect from the front-end, into it's Admin, or you can build your business logic in a Module and save to your Database. so It is possible very much. The Backend will extremely work in your favour as it has good API to easily have a backend view to see your transactions. Others will reply with their view, but it depends on your processwire knowledge and PHP skills. Sephiroth1 point
-
Ok this works for me now: require_once wire('config')->paths->RestApi . "Router.php"; $this->addHookBefore('ProcessPageView::execute', function(HookEvent $event) { $url = wire('sanitizer')->url(wire('input')->url); // support / in endpoint url: $endpoint = str_replace("/", "\/", wire('modules')->RestApi->endpoint); $regex = '/^\/'.$endpoint.'\/?.*/m'; preg_match($regex, $url, $matches); $hasAccess = array( '178.192.77.1' ); if($matches) { if(!in_array($_SERVER['REMOTE_ADDR'], $hasAccess)){ wire('log')->save("sso-debug", "Access denied for ".$_SERVER['REMOTE_ADDR']); http_response_code(403); exit; } $event->replace = true; } }, [ 'priority' => 99 ]); I have added the priority option and set it to 99 so that it gets executed before your hook in RestApi Module. KR Orkun1 point
-
Thank you Robin for pointing me in to the right direction So as you said the issue was from the Page Query Boss module. Actually it was not an issue of the plugin but I had to change the configuration of the output. The default output format is an array with the "PAGE NAME" as keys. Instead I used the ids as keys. $modules = wire('modules'); $modules->get('PageQueryBoss')->defaults['index-id'] = ['Page']; $pages->find('template=templateNAME')->pageQueryJson($query);1 point
-
OK, already fixed it. I dropped the column from the database Then I also had to drop the whole process_jumplinks_nf table and now the error is gone1 point
-
I keep getting this error: Failed to init module: ProcessJumplinks - SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'last_hit' Any ideas how to fix this? thanks1 point
-
1 point
-
1 point
-
Sorry i wanted to write that i changed it to utf8mb4_unicode_ci. Here is query that i used to do it: ALTER DATABASE processwire CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ALTER TABLE field_body CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci Still - I cant save my emojis. ?1 point
-
Despite Soma helpfully telling us we are all wrong, the code I suggested in that thread works for me: So you set up a field in each PageTable template to hold some reference to the container page - in the example below I use an integer field for the page ID, but you could use a Page Reference field instead. You would set the field to hidden so users do not see or change it. But for demonstration purposes I have left the field visible and also show the value in the PageTable columns. Note that the value is only set when the PageTable field does the AJAX reload (when the modal closes), so the value is not available when adding a new page to the PageTable until the modal is closed. In /site/init.php $wire->addHookBefore('InputfieldPageTableAjax::checkAjax', function($event) { $field_name = $this->input->get('InputfieldPageTableField'); // Just for this PageTable field if($field_name !== 'test_pagetable') return; $page_id = (int) $this->input->get('id'); $item_id = (int) $this->input->get('InputfieldPageTableAdd'); if($page_id) $page = $this->pages->get($page_id); // $page is the container page if($item_id) $item = $this->pages->get($item_id); // $item is the PageTable item // Set integer field to $page->id $item->setAndSave('container_page_id', $page->id); });1 point