Leaderboard
Popular Content
Showing content with the highest reputation on 03/24/2019 in all areas
-
I recently mentioned that I was working (more like messing about quickly :-)) on a Visualisation module based on the awesome chart lib Vega. I haven't touched this module in a while. I only realised today as I was transferring my dev setup to WampServer and testing things out that I'd left this off at a stage where one could view a basic Viz. See the screenshots below. Word of warning: this does not even qualify as pre-alpha in my opinion. It is very early days. It is more of a playground to test ideas. It's also not high in my list of priorities so I don't know when it will be ready... Screenshots Create new viz from list of pre-built visualisations/charts Editing a single visualisation/chart4 points
-
Although I don't know what your reasons for using var_dump(), I really recommend that you use the module TracyDebugger instead. It will give you better and cleaner information regarding any ProcessWire objects and their properties.4 points
-
@happywire don't forget that a Page is not an array or similar, but a PHP object with protected and private fields. From the "top" (like print_r($page)) you may see some internal attributes (like the array of hooks), but you can not directly access those fields. To retrieve, for example, the table of hooks, you'll need to use an allowed method, like print_r($page->getHooks()). Same for any field placed on your template. Their content is not retrieved everytime you see a $page but only after an access. If you do something like $page->someField, then you do not access a member from that object, the Page object intercepts the access operator and retrieves 'someField' from the database, caches its content in the page object and performs any kind of output formatting specified for that particular field. So, to obtain a list of fields available on a particular page, you'll do a $page->getFields(), which you may use to enumerate all fields and dump their contents: foreach($page->getFields() as $fldName) { echo "{$fldName}: {$page->$fldName}<br/>"; echo '<pre>'; print_r($page->$fldName); echo '</pre>'; } Edit: if you print_r($page) before and after that loop you'll see the embedded ['data'] array populated. And similar will do for $image->getVariations();3 points
-
@happywire just a little hint about image variations: Image variations (those files with DOT <width>x<height> DOT <ext> nomenclature) only live in filesystem not in the database. If you externally (outside of PW) remove or create additional variants in the proper location (your /site/assets/files/<ImageID>) folder, these changes are instantly reflected to any image enumeration (for example getVariations() method). There is no need to visit the admin or do any manual update after each change. If you do a $image->size() that method only looks into the assets path of that particular image to ensure the requested variation (namely file with specified width and height nomenclature) exists. If that's not the case, it will be created on the fly. There is no big magic happening behind the curtains. I guess its much simpler to accomplish what you intend to do: Just instruct your external script to create the variant next to the original file.3 points
-
3 points
-
or simply reload... ? Why should it? This only would add redundancy of the same information which may go out of sync for some reason. On the downside for this filename-only implementation is, that there only may be one variant with a particular dimension. So you can't have a 300x300 variant with low and another one with high quality, for example. And if you later decide to use different scaling parameters, you'll need to delete the old variant (file) first for the new conversion to happen (see Pageimage::size() for a more detailed description).2 points
-
GridSize was introduced by my work on the image input field. It's the size of the square images in the grid view of the inputfield. Afaik it is duplicated to cater for hidpi monitors by default.2 points
-
Yep, that's it. That error contains non UTF-8 characters, I assume they are in Windows-1250 character set. The best option is to configure MySQL to return errors in English. Your my.ini will most likely be found in %programdata%\MySQL folder, in [mysqld] section add lc_messages=en_US. Restart mysqld service for changes to take effect. I guess this commit is the culprit for the PW error (SQL error is, of course, another thing).2 points
-
Thanks @Robin S - that's a really handy addition for my needs - hopefully others will enjoy also!2 points
-
I have added support for this in v0.1.19. The scenario of editing user pages is a different kettle of fish than "normal" pages because you are then outside the structure of what are normally considered editable pages. So there isn't much that's useful in the dropdowns apart from the last dropdown.2 points
-
A recent GitHub request got me thinking about ways to get an overview of which fields are using which Textformatter modules. Here are a couple of approaches... 1. For all Textformatter modules that are in use, show the fields they are applied to Execute the following code in the Tracy Debugger console: // Loop over fields and get their Textformatters $textformatters = array(); foreach($fields as $field) { if(empty($field->textformatters)) continue; foreach($field->textformatters as $textformatter) { $textformatters[$textformatter][] = $field->name; } } d($textformatters); Any Textformatter modules that are not included in the dump output are not applied to any fields. 2. In the config screen for a Textformatter module, show the fields where the module is applied Add the following to /site/ready.php $wire->addHookBefore('ProcessModule::executeEdit', function(HookEvent $event) { // Get the module name $module_name = $this->wire('input')->get->name('name'); // Return if it's not a Textformatter module if(strpos($module_name, 'Textformatter') !== 0) return; // Add field to module edit form $event->wire()->addHookBefore('InputfieldForm(id=ModuleEditForm)::render', function(HookEvent $event) use ($module_name) { $value = ''; // Find any fields using this Textformatter and build markup value foreach($this->wire('fields') as $field) { if(empty($field->textformatters)) continue; foreach($field->textformatters as $textformatter) { if($textformatter === $module_name) { $value .= "<a href='{$this->wire('config')->urls->admin}setup/field/edit?id={$field->id}#fieldtypeConfig' target='_blank'>$field->name</a><br>"; } } } if(!$value) $value = 'No fields are using this Textformatter module'; // Add markup field to form $form = $event->object; $f = $this->wire('modules')->InputfieldMarkup; $f->label = 'Fields using this Textformatter module'; $f->value = $value; $form->insertAfter($f, $form->children->get('id=ModuleInfo')); }); });2 points
-
2 points
-
Here is GoodKidsClothes.com, a blog about kids clothes - news, style tips, sale alerts, and more. GoodKidsClothes.com originally ran on Wordpress, and I moved it to Processwire recently, the new Processwire version is shown above. There was a fair amount to change over, since it had 4 years on Wordpress before switching! I kept the colors, background, etc in line with what it had been before - a soft, friendly look. I wasn't seeking for it to be identical to its previous appearance, just similar but updated/better/more fun. The html I did from scratch, although I used the W3CSS framework. I love W3CSS because they handle all the responsive breakpoints, and the default styling is a clean flat modern look with plenty of great pre-sets. The reason I moved this site over to ProcessWire was not looks but actually functionality: the new Wordpress editor (Gutenburg) had just come out - one of its quirks is that it couldn't keep up with my typing, so I had to literally slow down my typing, which really defeats the purpose of WP as a blogging CMS. (Processwire's editor keeps up with me just fine). Also it was anyway time for me to manually go through and update old articles, put in new affiliate links etc, so I decided to do everything all at once and switch over to ProcessWire. In case anyone is wondering, the switch-over was manual since I was going to examine every article I'd written to either a) update it, b) move it to another of my sites, or c) trash it. This was not time-efficent but this way I wound up with being certain everything was up to date content-wise, plus no unwanted bloat (like extra WP fields) could make its way into my Processwire database. I simply installed Processwire via 1-click Softaculous install in a subdirectory of the original Wordpress site, with the original site still running. Then after I had the Processwire version fully finished (this took several weeks), I simply uninstalled the Wordpress version and moved the Processwire site into the document root. This way I had less than 1 minute downtime. UX/UI The first menu link is an all-abilities-inclusive version of "skip to content". The actual text displayed depends on which page template is being used ( this text is assigned in _init). For example, the Article template will display "Scroll to article", while Search Results template will display "Scroll to results". Link styling in the body of article content is designed for both the desktop and mobile user, with simultaneous underlining and highlighting showing the entire link region to aim for when tapping on mobile. On the home page and some other templates as needed, skip links are available within the page. They offer the option to skip past a series of links such as social sharing links, pager navigation, etc for a) the screen reader user and b) the fully-sighted keyboard-only user (no mouse). These links only become visible to the eye when focus comes upon them via tabbing. Tab through the home page to see it in action - this is the template where the most skip links have been needed. Cookie manager - originally I used a slider for turning Google Analytics tracking on/off but changed to checkbox because I could not work out a way to manipulate slider without mouse. Newsletter - field, and feed One feature of this site is its newsletter, and you'll see here how Processwire shines. The setup was (and still is) that on days when a new blog post relevant to children's clothes is published, subscribers get a brief email notifying them of the new article and linking to it. This is all handled by MailChimp, which I highly recommend. Under the old Wordpress system, I had to use categories to classify which of the posts wound up going into the newsletter (kids clothes) and which posts didn't (other topics like parenting etc). There was always the chance that under default WP behavior, things would be classified incorrectly if I forgot to specify categories. Under Processwire, I've set up the article template to have a field called "Newsletter" which is a simple drop-down choice of "For newsletter" or "omit from Newsletter". There is no default value, and it's a required field, ensuring that I do remember to specify it one way or another. It's such a relief to do it this way! My newsletter feed was easy to customize under Processwire: I created a feed template that selected a) all the pages using the article template that also had b) the "For newsletter" field selected, and those are listed at /newsletter in feed format. Please note that this feed may be empty right now - I omitted my existing articles from newsletter feed as subscribers have already seen them, and haven't had time to write new articles yet. To clarify, I'm expecting the newsletter feed at /newsletter to only ever be read by MailChimp, although it's certainly possible to be used by feed readers or read by humans. XML sitemap Under Processwire, I was able to generate a list of articles in XML format at /sitemap.xml that I can then submit to Google as the XML sitemap for this site. Best of all, unlike web-based crawler-type sitemap generators which generate a static sitemap that you then upload to the document root, my Processwire /sitemap.xml auto-generates each time the page is loaded, so it's always auto-updated - any changes in back office like article deletion, unpublishing, adding new articles etc are reflected automatically in /sitemap.xml. Some advantages of Processwire features when templating 1. _init.php file - my theme was designed for subsequent use in my other sites, so selected pages for use in nav menu (About, Privacy Policy) are automagically "found" in _init.php as follows: $pp = $pages->findOne("template=BN-infopage, sort=created, title*=Privacy"); $ab = $pages->findOne("template=BN-infopage, sort=created, title*=About"); 2. Made use of Processwire's built-in retina-friendly image resizing class, class="hidpi" to ensure social sharing icon links render at a decent resolution on mobile screens. Other info To check my html and to help identify problems that are not visible to the eye, I found it incredibly helpful to use the "audit" feature available on Chromium and other Chrome-based browsers. (F12->Audit-> select options you want). The order of the blogroll looks a little odd at first glance but it's ordered based purely on publication date. However, I updated some articles and they display the last updated date, which makes the blogroll look like it's not in date order even though it's in publication date order. Also some dates (the older article dates) reflect a user-specified date field, to show the article was valid at the time it was written (e.g. time-sensitive info such as reviews, sale alerts, etc). I'd be happy to explain further if anyone's interested. Moving forward as I write more articles, there should not be an issue, since I usually update only on or very soon after the publication date, so we should not expect to see wildly different dates on sequential articles from here on in.2 points
-
I've finally managed to to remove my 1.5 decades old, all-ugly, frame-based photography site to something more modern. So what looked like this for a much too long time: now present the images much better, has a consistent layout and finally is responsive: The intention of the site is to provide some inspiration for the ambitious photographer and also provides a tips section focusing on some aspects of digital photography. After being idle for too long, I feel new motivation for adding even more tips as time allows. We'll see. https://www.tofahrn-foto.de/en/ Layout is basically pure UiKit and all content (including menu and footer) is managed using my RepeaterFlex as a kind of real world test. The RepeaterFlex is inspired by the commercial RepeaterMatrix fieldtype but uses plugins to define item templates (in case you're interested, there is a small Demo Site for RepeaterFlex including some documentation). The site uses lazy load of images (lazysizes.js) and page transistions (barba.js V1) to obtain a hopefully smooth experience. There also is ProCache running to deliver minimized css and markup. Enjoy.1 point
-
perhaps PHP shortcode is disabled in your server environment. Try <?php ... ?> instead of <? ... ?>1 point
-
Looks like you've placed the inline script into a JS file, right? In that case you'll need a different approach to get the event data into the JS world, the PHP injection from <?= getEvents(); ?> does only work when you embed the whole <script>...</script> block into your markup.1 point
-
Aha, so each side of the square has the same length, so if I put 'gridSize'=>250 then each side of that preview in the admin panel should be 250px long? Regardless of gridSize, when I put <?php namespace ProcessWire; // config.php $config->adminThumbOptions = array( 'width' => 200, 'height' => 0, ); into config.php the default image variation is not 200x0 both either 0x260 or 260x0. How can I get the default image variation to have a width of 180 or 200 and a proportional height please?1 point
-
Well I don't know how could I fix the long menu issue, sticky works just this way. @MilenKo Are you also on Mac? As I know adrian also is.1 point
-
@Autofahrn Excellent! I figured that once the variants have the PW variations nomenclature they are added. However I was only ever in the admin panel and checked the "Variations" tab after making the variants. There they would only show up after hitting Save for that page. To be expected. So this lead me to think that the same thing goes for the frontend. My bad!! That is why I thought I have to Save each page in order for PW to a) put those into its db and b) make them show up as "Variations". Interesting that PW does not put the variations into its db. I thought they have to be there to be able to be shown. Just did a test, made variants of an image in the assets folder, var_dumped the variations for that page in the frontend and they are all there, without having to save them into the db or make PW save the page in the admin panel. Uff!! Great to know. This should be documented somewhere. Super nice.1 point
-
1 point
-
@MilenKo - I have been seeing this since December: https://processwire.com/talk/topic/13389-adminonsteroids/?do=findComment&comment=1776701 point
-
@Matze, if you own or consider ProFields, you may check out FunctionalFields as well. While conceptionally intended for text translations, I do not see a reason why this should not work here. If you write something like this in your template file: $thePainter = __text(' ', 'painter', 'label=painter, required=true'); $thePeriod = __text(' ', 'period', 'label=period, required=true'); $theCanvas = __text(' ', 'canvas', 'label=canvas material, required=true'); $theTechnique = __text(' ', 'technique', 'label=painting technique, required=true'); You'll see that in your page editor: If you add more text replacement in your template file, these are added to all artist's pages immediately. Sidenote: I'll have to set a space for the original text, otherwise the fields do not show up, so they are actually not empty in this example. While this may be what you are looking for on first sight, I'd encourage you to think about using page references instead. Information like canvas material or painting technique are not endless and will repeat over various artists. Using plain text input, you'll have to repeat all this each time. And, if you are going multi-lingual, you'll have to enter every translation for every artist. With page references you'll have many benefits, like faster searches (who is painting with this particular technique in that period), generally less data in your database (less data to transfer to build an index, for example), one point to enter that information and may even add more info about it. You may even create new "attribute-pages" on the fly when entering the artist's page.1 point
-
The MultiValue Textformatter might be of interest for your use case. (I have no own experience with it, though.)1 point
-
It looks familiar with the issue I had with the terminal panel. Would you mind var_dump($data) in WireCache.php at line 442, just before json_encode($data). Examine the $data to ensure it doesn't contain non UTF-8 characters.1 point
-
Okay, it's "Textareas" - found it, sorry … (how can i delete a post?)1 point
-
Hey there. This morning I upgraded AOS for a project to latest version 2.0.15 and started noticing some issue viewing the hidden/unpublished pages in the admin. Tried to uninstall the module and grabbed a fresh copy, however the same issue appeared. If I move my mouse over those that are not showing but only ID's are listed, they all appear fine: Started disabling options of AOS in order to check which one would be causing the issue and it appeared that it is the PageList tweaks and more specifically: Show page IDs (SuperUser only) . I did not set any other options, however if I remove this one, the list shows properly. The issue seems to appear on both themes - default and uikit. Any ideas how could I keep the page ID's showing but keeping the hidden pages visible? Is this a feature/option I've missed or else?1 point
-
Putting this in your ready.php or admin.php should do it. You may want to add additional checks for admin only (not via API). $this->addHookAfter('Pages::added', function($event) { $p = $event->arguments[0]; $p->removeStatus('unpublished'); $p->save(); }); But, @Autofahrn has some excellent points about publishing a page which doesn't have any content other than the title, so use this with caution!1 point
-
1 point
-
You may rename the Save and Publish buttons... ? The first "save" only creates the page in page tree and assigns the template to it. You can not actually enter any content upon page creation, so keeping the page unpublished seems very reasonable to me. Maybe the Save button could be named "Create" to better reflect what happens. At this moment the page really should not be published automatically, since it may contain required fields, where your template code rely on. With the template assigned, you'll have fields to enter content and see the Publish button. After entering the data you press "Publish", which effectively is "Save+Publish" in this case. I don't see an extra step to publish a page after entering its content, since this already is the default. Only in case the selected template does not have additional fields you'll see additional Save+Publish buttons. Are we talking about this situation?1 point
-
User registration example: public static function addUser($data) { RestApiHelper::checkAndSanitizeRequiredParameters($data, [ 'username|selectorValue', 'password|string', 'email|text', ]); $item = new User(); $item->setOutputFormatting(false); $item->name = $data->username; $item->pass = $data->password; $item->email = $data->email; $item->addRole('guest'); $item->save(); }1 point
-
I use Vega and its sister components. Under the hood, it uses D3js. It was created by some of the guys who originally developed D3js and its precursors. The beauty with Vega is that it is visualisation grammar. It uses a declarative language to build visualisations. The language is just JSON! with a few added strings that the parser will recognise as functions. Vega is actively developed at the University of Washington, so, it looks like it's here to stay. I started working on a Vega module for ProcessWire but never got round to finishing it. It's currently on the slow burner but will revisit it once we get to Padloper reports/analytics.1 point
-
Out of necessity, I wrote a little module that ties into UserGroups and allows admins to limit the available templates for new pages based on groups. The module is still very fresh but already in production use in our corporate intranet. If there's interest, I'd be happy to have it integrated into / shipped with the UserGroups module itself. https://github.com/BitPoet/TemplateGroups The settings are stored in their own database table (template_groups).1 point
-
Hi @adrian, A lot of the code is much the same, but tidied up with the the coding style guide implemented, so I'm not surprised the diff doesn't reveal much! The readme is pretty thorough and covers a lot, but here's the gist: addData() - add X-Mailgun-Variables - https://documentation.mailgun.com/en/latest/user_manual.html#attaching-data-to-messages - to be honest don't know what use cases there are for it but it's in the API and was easy to implement addTags() - add multiple tags as an array getHttpCode() - to get the response code from either send() or validateEmail() * Most methods now chainable (see the Advanced Example in the readme) Tracking only used if bodyHTML() is set (As this only works in HTML email) cc() and bcc() only used when batchMode is off - this seems to me to be the correct implementation WireMail::htmlToText() used for generating the text version if only HTML passed (as in WireMail now) The ASCII conversion for tags now uses $this->sanitizer->nameFilter($tag, [" "], "", false, 128); WireMail::replyTo() implemented - doesn't seem to have been before removed addAttachment(), now uses WireMail::attachment() - which adds the ability to set the filename Unixtime is now passed to setDeliveryTime() A bunch of other small tweaks like using $sanitizer->email() in validateEmail() * I'd wanted to use WireHttp for the requests, but it doesn't allow custom cURL options. I have done a pull request for this, but I don't think I'll be changing the module's cURL request implementation now anyway. Cheers, Chris1 point
-
Hi, I think that you don't need to do that because $page->comments->count return number of comments for page. Some options to sort pages by comments: // example: page template "blog-item" // $pages->find($selector)... // from top by number of comments $selector = 'template=blog-item, sort=-comments.count' // by recent comment $selector = 'template=blog-item, sort=-comments.created' // by upvotes $selector = 'template=blog-item, sort=-comments.upvotes' Or options by downvotes or stars. Also, there are and additions, eg. "AND comments.count > 10" etc... Regards. EDIT: read again your question, and if you have page array (results), than you can try to filter results with this: $my_results->sort("-comments.count");1 point
-
If you're using one of those snippets above than exclude them like this: include=all, status!=unpublished1 point
-
Workers are separate processes, which run alongside your webserver stack on the host system. They can process things they get out of the queue without being reliant on the Request->Process->Response cycle of the webserver. E.g. You want to have a way for users to request a big report on your website. As a big report sounds like, it take some time to generate the pdf for it (say ~1 Min). You wouldn't want your user to sit around and watch the nice browser spinner, waiting for the next page to pop up. You can now write the request in a queue and instantly return a message stating that the report will be generated and emailed to the user when ready. To generate that report you may know the option of using a cron to trigger website logic, without an actual user requesting a website, but that's also flawed with things like timeouts and such, also it's only starting in intervals. That's where workers come in. These are php (and other script) processes, which often run as services like e.g. your apache server does. These scripts contain some way to not exit early (e.g. infinite while loop) – which is the biggest difference to website request – and periodically check their queue if there's work to do. If your report request is in it, they generate the pdf, email it and if done delete the queue item. If there are other reports to do they'll move on to them, otherwise they sleep until another queue item is available.1 point
-
Another option that might work (though not yet tested to compare): $result = $pages->find("template!=admin, has_parent!=2, include=all");1 point
-
This turns out more complex than it seems, but it is usually something not used that often or ever at all. Even with my experience took some time to get all pages, unpublished , published, hidden, not in trash and not under admin. This is with superuser logged in as I think as editor or guest user you won't get pages from trash anyway. But something like this is needed currently Unless I'm missing something. $pa = $pages->find("has_parent!=2,id!=2|7,status<".Page::statusTrash.",include=all"); foreach ($pa as $p) { echo "<li>$p->path</li>"; } Note that as soon as you got a few hundred or thousand pages you will get a problem Edit: id = 2 // is the /processwire/ admin parent id = 7 // is the trash include=all // to get all pages unpublished and hidden1 point
-
For a field that can contain multiple images, the value of that field is always going to be a type of array. So you'd have to either check to see if there are any items in the array, or try to retrieve the first time like Soma did. Here's how I usually check if there are any images: if(count($page->images)) { // images here } else { // no images } When it comes to a single image field, you are dealing with just one item that is either set or it isn't (rather than an array). You only need to check if it has a value: if($page->image) { // image here } else { // no image } When you use $pages->find(), $pages->get(), $page->children(), etc., you can also find pages that have a given amount of images. So if you wanted to find pages that don't have any images, you could do this: $pages->find("images.count=0"); ...or pages that have one or more images: $pages->find("images.count>0");1 point