Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Posts posted by millipedia

  1. After having logged this on GitHub and having wiser people than me investigate, we managed to figure out that this only happens when using Varnish cache (in particular using Varnish on a Cloudways server). Disabling Varnish was enough to fix the problem.

    I'll leave it here though because hey, it's a nice bug, and maybe it'll help someone else.

  2. Here's a fun one this morning.

    I normally set a custom logo in the admin masthead using the settings in the AdminThemeUikit module (mostly so I know which site I'm in when I've got serveral open at the same time). Today I mistyped the logo name when I was setting this for a site so the logo didn't load. But then when I logged out and tried to log in again I got the dreaded red screen of death.

    After checking all the usual suspects (file permissions, disc space etc) I renamed the logo file to match my misspelled setting and Bob's your uncle, I can log in again. If I delete the logo file the CSFR error comes back, replace it and it's all good.

    This only happens in debug mode so my guess is that there's some PHP warning message that's mucking up some javascript but I've not managed to find it yet.

    I'll log it as a bug on GitHub but thought I'd stick it up here cos it's the kind of bug that could have ages to find and I'm feeling smug that I got it quickly (so no one tell me it's a known bug and I could have just Googled it).



    • Like 1
  3. @DaveP Thanks for spotting that broken link - fixed now (Its a hard coded link in the template so the weirdness was due entirely to my fat fingered typing).
    It is possible to get decent scores in WordPress but it's just so much more effort than it is with PW.

    and @bernhard - good spot on that layout issue. It was a long URL that was pushing a div out wider than it should have been.

    Interestingly it was fine in Firefox, which is what I use for development, and only breaking in Chrome  / Webkit browsers. I guess this means I really ought to use Chrome for development more to catch this kind of bug which is going to affect more users. Shame because I feel we ought to support FF as much as possible.


    • Like 2
  4. Migzen.net is a site we designed and built for Lancaster and Birmingham Universities that gathers academic research into the effect Brexit is having on migration.

    Obviously we'd best not get into the whole Brexit debate here, so just let me apologise profoundly on behalf of my country and move on to the site...

    It was a new project, so we were able to create the brand and design from scratch which is always nice. It also gives us the opportunity to make sure colours are accessible for use on the website.

    As well as the usual blog posts and pages, there's a couple of slightly fancy things we did for them; one of which was to automatically import pages and media whenever they add a new episode to their podcast feeds. We do this using a cron job which loads the MarkupLoadRSS module and parses their XML podcast feeds. If we find any new episodes then we create pages for them with the episode summary from the XML and a nicely styled embedded media player to listen to the audio.



    We also built them a searchable database of academic resources. That was fairly straighforward, but we do make use of WireCache to build the tag cloud when a page is saved - we use $page->references to work out an article count for each tag which would be expensive to do each page load.


    There's also a neat looking Timeline which is just built using a repeater field. Honestly PW is ideal for this kind of thing.


    The site gets good scores in Observatory and Lighthouse (thanks ProCache), and most importantly the client is very happy using PW to keep the site up to date.


    • Like 11
  5. When I need to shift data over from an old site I normally export the data to a csv file and then just write a PHP script to loop through that csv and add pages.

    Once you get the idea it's a very flexible way to import data.

    Here's some completely untested code as an example of how I'd approach it:

    // bootstrap PW
    // loop through this CSV
    if (($handle = fopen($filename, "r")) !== FALSE) {
        while (($data = fgetcsv($handle, 2000, ",")) !== FALSE) {
            // say we have a csv that is in the form 
            // 'artist_name', 'artwork_name', 'artwork_dscription'
            // (I'm assuming this csv doesn't have a header row)
            // see if we have a page for this artist already
            // if not then add this artist - in this example
            // using the template 'artist' and the parent '/artists/'
            if($ap->id < 1){
                $ap = $pages->add('artist', '/artists/', [
                        'title' => $artist_name
            // now add our new artwork page using the artist_page as a parent
            $artwork_page = $pages->add('artwork', $ap, [
                'title' => $artwork_name,
                'description' => $artwork_description
        echo 'cant open csv file for import';


    • Like 2
  6. In the past when a client has asked us to show PDFs in the browser rather than being downloaded we've used Mozilla PDF.js  and then created a link that passes the doc name in the form pdfjs/web/viewer.html?file=whatever.pdf

    In this day and age though I'd question whether this is really necessary. Most browsers have built in pdf viewers anyway : https://caniuse.com/pdf-viewer and if you're overriding the users choice as to which pdf viewer they use then it's probably not great for usability.




    • Like 1
    • Thanks 1
  7. There's also the pw-optional parameter for your Markup Regions:


    You'd need to use an id on your section tag rather than the content div you have at the moment but that would remove the section if it was empty.

    <section id="section2" class="section" pw-optional>
        <div class="container is-fluid">
            <div id="content2"></div>


    • Like 1
  8. 3 hours ago, bernhard said:

    If you do some testing note that it's really easy to add custom markup to any inputfield via hook:


    Before I spotted your reply though I'd hooked into ProcessPageEdit to load an external js file:

    function resizeEditor(HookEvent $event){
            $js_path=wire()->config->urls->templates . "resize_editor.js";
    wire()->addHookAfter('ProcessPageEdit::execute', null, 'resizeEditor');

    and then that JS looks like this:

    // resize ckeditors to height of container.
    if(typeof CKEDITOR !== 'undefined'){
    	CKEDITOR.on('instanceReady', function(event){
    		var input_name=event.editor.name; // this is the id of our field.
    		var parent_height = document.getElementById(input_name).parentElement.offsetHeight;
    		console.log('Setting editor ' + event.editor.name + ' height to' + parent_height);
    		event.editor.resize( '100%', parent_height );

    That sets all the editors to the height of their containers.

    • Like 2
  9. 18 hours ago, bernhard said:

    You can increase the number of "rows" in the field's settings (input tab). Is that what you are looking for?

    That's certainly helpful thanks (and honesly will probably do me).

    I still feel like it should be possible to automatically resize the editor to the height of the container div though. Probably a bit of javascript that uses the CKEditor resize function  to match the editor height to its parent.

    I'll have a play when I have a moment - I was just hoping someone might have done it already....

  10. This is really minor thing but it annoys me that I can't get an instance of a CKEditor to use the full height of a container in the admin.

    This is especially noticeable where I have fieldset that's pushing the height of a row down; as per this screenshot:


    I've poked around at various CSS settings but no luck so far. Has anyone managed to do this?


  11. 3 hours ago, SwimToWin said:


    SEO matters and so hiding pages behind a "section" is not necessarily good - example:

    Hopefully those other suggestions will help answer your question, but like @AndZyk I'd be interested to see what the justification is for not organising your pages in sections.

    My feeling is that hiding navigational elements is more likely to have a detrimental effect on usability (and hence SEO). I can't be the only one who occasionally edits a URL to navigate up a level (ok, I might be). Perhaps it's different if you have a limited number of products on a site but I think having a decent hierarchy is going to be better for users.

    • Like 1
  12. Right - as part of my efforts to show off more of the work we've done recently, here's a site we launched earlier this year.

    On The Record are a not-for-profit that specialise in oral histories and creative media. We've done a few nice projects with them ( A Hackney Autobiography was a lovely project we did with them in our pre PW days).

    A creative design was very important to them as well as being accessible and usable.

    There's not too much bespoke backend coding going on. We needed to provide them with a way of easily adding audio and video files but that was mostly done using normal fields and a modified version of Ryan's TextformatterVideoEmbed module adapted for use on plain text fields.

    Apart from that, it's just the usual supects for extra modules:

    and Macrura's ProcessDocumention module which we normally use for provide help pages in the admin area.

    The front end is pretty much bespoke but with a few components lifted from various places; looks like we used Bootstrap grid for one.
    It's another site where we used CSS filter properties to apply a consistent look and feel to images the client uploads.

    I think it looks nice anyway and the client is very happy with it and took to using the PW admin with no problems.



    • Like 9
  13. I'm with you in that I like the look of Tailwind but I've never quite found the right project to justify using it.

    These days I rarely use a framework at all. Support for flexbox and grid has meant that a lot of the advantages of using a framework don't apply any more. Browsers are a lot more consistent these days as well, so there's not as much need for polyfills and resets and vendor specific tweaks that might have been baked in to a framework.

    My starting point for a project is a single CSS file that has some minimal styles and utilities in that I'm pretty sure I'll always need. Originally that was based on Wing css but I've tweaked and added to it over the years.

    I then have other css files for components that I've used over the years - so if I need an off screen menu for example I have one that I can reuse and adapt.

    The same applies to javascript; In the old days (a couple of years ago anyway) I would have just included jQuery by default in a project but now I just have a few native javascript functions I can include when I need to.

    Most of the work we do is pretty bespoke stuff so this works better for us. I imagine that if you were doing lots of sites that were fairly similar then a framework might be useful.

    One situation we would use a framework for is when we need to do an admin interface (we a did a great project that had a SMS bot the client could manage for example). For that we've used ModularAdmin which is based on Bootstrap 4 (and which hasn't been updated for a few years so probably not that useful a link).

    Now I'm essentially a solo dev, so bespoke code is easy to manage. If you're part of a larger team (or looking for a job) then I bet having decent documentation and consistency is much more important so learning a framework is probably a smart move.

    • Like 4
  14. There's a propery _pfscore (page finder score) returned from full text searches. You can use that to filter out low scores.

    For a recent site I appear to have used:

    		foreach($matches as $match){
    				if($match->_pfscore < 900){

    but you can fiddle around with that value to suit. Not sure if there's a way of specfying a minimum score in your query.

    • Like 2
  15. 50 minutes ago, Zeka said:

    How did you get forcing of PDF downloading?

    Honestly I didn't even try. I'm literally using

    // download file.

    in my download script, so no options at all.

    I don't know the ins and outs of wireSendFile but in the past when I've had to implement my own downloads then I've had issues using "application/octet-stream"  for large pdf files and had to switch to redirects. Does Chrome consistently open all your files inline whatever the size?

    But hey, try taking out the options and see what happen...

  16. Ok - this write up got quite long so I reckon it counts as a case study.

    Crest Research is a hub for academic articles and information about security research collated by the University of Lancaster  and other universities in the UK.

    Their old site had been running for several years on Word Press. There was a lot of content that wasn't brilliantly organised and there was lots of plugins that had been added to WP (honestly one of the things I like least about WP is that it's too easy for users to add plugins without really understanding the implications).

    We persuaded the University that it would be much better to make the move to Processwire. No small part of that was being able to demonstrate that PW was a much better option from a security point of view. We also wanted to be able to develop an API that provides content to a native app we built for Crest a while back; that probably would have been doable in WP but much easier in PW.

    This was our first reasonably large move from WP to PW so we learnt a lot on the way.

    So - first step was to import all of the posts from WP. For this we headed to Adrian's ProcessMigrator module which worked well at getting the data over. Once we had the data over we used Wanze's ProcessBatcher module to do bulk updates and moves to try and organise things (including deleting a load of WP tags we didn't want to keep).

    We found that we needed import certain things manually as well, in particular some thumbnail images. For these we just created an import script that read through a CSV of data that we'd dumped from the WP database. Honestly PW is just great at this - we had a column of page aliases and a column of image URLs and with about 10 lines of code we manged to download the images and add them to our imported pages.
    We've used this method of a CSV and an import script on a couple of other projects where we've needed to load content from other platforms and it's been very straightforward and effective.

    Once we had the content over there were a couple of other bits of functionality from the WP site that needed to replicate. One of these was a download manager. The old site kept statistics of the number of file downloads which we needed to replicate (and retain the old data) so we built a modue to handle that. This was pretty much our first foray into PW module development and Bernhard's blog on building admin modules was very useful.


    We tried to remove as many WP short codes as possible but those we need to keep we replicated in the Hanna Code module.

    The search on the new site was very important to the client - a lot of their targe audience is researchers and academics. We ended up with a system of filters (author, tag etc) together with the text matching operators that appeared in 3.0.160.


    The client also asked if we could add some kind of fuzzy searching for misspelled words and US / UK spelling differences which we did by adding to the lemmas in Ryan's WireWordTools module. Our additions our available on GitHub. I think there's still plenty of refining to do on the search but it works well.

    Another thing the client asked for was an indication of 'Reading Time' for an article as Medium have on their articles. We added a hook to calculate the reading time for an article when the page is saved. Can't seem to find the blogpost on Medium where they explained their formula but I've stuck the code we ended up with up on GitHub as a gist here.

    Other modules we used include:

    AIOM+ - this was before we got a license for ProCache. We used AIOM and then some hooks to generate cached versions of some chunks of html using MarkupCache. Probably wouldn't bother now and just use ProCache.

    Redirects - we tried to keep the site structure the same as the old site for SEO, but there was quite a lot of organising. We grabbed the top few hundred pages from Google Analytics and then ran those through a PHP script to check their status on the dev site (gist of that script on GitHub as well ). We dumped those results into a spreadsheet and decided where they needed to be directed to. Then we imported that list back in the Redirects module.

    Other honourable mentions go to Connect Page Fields, Page Field Edit Links, Dashboard, Schedule Pages and of course Tracy Debugger (which was particularly useful on this project).

    So... I'm sure you're asking (assuming anyone has made it this far) what the end site was like and whether the client was happy?

    Well comparing the old and new sites in Lighthouse gave us this:


    And Mozilla Observatory gave these rather nice results (especially since it's a security focused site)


    This resulted in a big upswing in traffic. We're seeing about a 500% increase in vistors compared to this time last year (and from pretty good numbers in the first place).


    IMO the biggest factor in this increase was the improved page speeds.

    Now - of course we probably could have got similar results in WordPress if we'd spent enough time and energy on the site but by using PW we've ended up with a much cleaner site which the client is happy to use. Logging into the old site with it's upselling of plugins and so on is just painful. We've also educated the client as to why adding random plugins is not a good thing; the old site loaded 18 javascript files from various sites most of which we didn't know anything about - we have 3 now (and one of those is analytics which we tried to persuade them to lose.).

    Anyway - they're happy and we've got plans to keep developing the site over the next couple of years so hopefully it's just going to keep getting better.



    • Like 15
    • Thanks 1
  17. So today I learned that on MacOS you need to update settings to allow keyboard navigation of links in Firefox:


    Chrome just ignores this setting on MacOS and seems to do what it wants (and which in this case is what I was expecting to happen).

    Anyway, the upshot is that whilst I still can't fire the drop down menus in the UIKit admin theme I can at least navigate the top level menu items using a keyboard without having to change browsers.

    • Like 1
  18. Mostly we've shifted domain registration over to Google Domains (cos hey, it works) but annoyingly they don't provide .org.uk domains which our clients often use .. and they're expensive for .co.uk names. The registrar we have been using for .org.uk domains has now been taken over by GoDaddy and so I'm thinking it's probably time to look at alternatives.

    Does anyone have any recommendations? I'm not interested in any hosting services, I just want to be able to manage the domain.

  19. I really must make more of an effort to add more sites to this forum - we've done some nice work really.

    Women / Theatre / Justice is a case in point. WTJ is the umbrella title for research and public engagement activities undertaken by academics from various universities in partnership with Clean Break theatre company.

    Clean Break was founded in the 1970s by two women in prison and focuses on using theatre to help create positive change in the lives of women with experience of the criminal justice system.

    We wanted to reflect the origins of the organisation so we created a home made 'zine' like design with typewriter fonts and adding noise to the photographs and images to get a photocopied feel:



    There's not too much bespoke coding going on functionally - we created the usual blog and events as well as a simple photogallery, but most of the technical effort went into working out the best way to apply textures and filters to the images so that the admins could upload new content without needing to phaff around in photoshop ( CSS 'backdrop-filter' for the win).

    One interesting thing got thrown up in accessibility testing; originally we'd created the design using a fixed with typewriter font and even though we'd set a pretty large font size with good contrast that passed our automated accessibility testing, we found that real world users still had difficulty reading it. So we changed that to a more modern and readable slab serif. Testing with real users is always a good move.


    • Like 8
    • Thanks 1
  20. I've tweaked the default colours (using the handy tool at https://learnui.design/tools/accessible-color-generator.html ) to be as close to the current colours as possible but still hitting AA contrast requirements.

    Here's before and after screenshots for comparison. I don't think it's too drastic a change...



    The admin.less changes for that are:

     * Primary variables
     * Adjusted to hit AA accessibility.
     @reno-text-color: #354b60;
     @reno-link-color: #df2b5b; // #e83561;
     @reno-link-hover-color: darken(@reno-link-color, 10%);
     @reno-dark-background: #1C2836;
     @reno-muted-background: #f0f3f7;
     @reno-muted-text-color: #6f7580; // #8d939e; 
     @reno-muted-text-color-alternate: #577898; // #6c8dae; 
     @reno-primary-background: #008668; // #3eb998;
     @reno-secondary-background: #e2e9ef;
     @reno-success-background: #8bccde;
     @reno-success-color: @reno-text-color;
     @reno-warning-background: #FFD15E;
     @reno-warning-color: @reno-text-color;
     @reno-danger-background: #bc283d;
     @reno-danger-color: #fff;
     @reno-alert-background: #ffd;
     @reno-alert-color: @reno-text-color;
     @reno-primary-headline-color: #1C2836;
     @reno-secondary-headline-color: lighten(@reno-primary-headline-color, 30%);
     @reno-notes-text-color: @reno-muted-text-color;
     @reno-notes-background: #ffd;
     @reno-masthead-background: @reno-dark-background;
     @reno-masthead-link-color: rgba(255, 255, 255, 0.7); 
     @reno-masthead-link-hover-color: lightblue;
     @reno-masthead-link-current-color: #fff;
     @reno-masthead-icon-color: #6f7580; // #8d939e;
     @reno-masthead-search-text-color: #8d939e; // #008668
     @reno-masthead-search-background: transparent;
     @reno-masthead-search-border-color: lighten(#253447, 10%);
     @reno-masthead-search-focus-background: lighten(#253447, 5%);
     @reno-masthead-search-focus-text-color: #fff;
     @reno-masthead-search-focus-border-color: @reno-masthead-search-focus-background;
     @reno-masthead-search-icon-color: @reno-masthead-icon-color;
     @reno-button-text-color: #fff;
     @reno-button-background: @reno-primary-background;
     @reno-button-hover-background: @global-link-color;
     @reno-button-secondary-background: @reno-muted-text-color-alternate; 
     @reno-dropdown-background: #fff; 
     @reno-dropdown-color: @reno-text-color;
     @reno-dropdown-hover-background: #e2e9ef;
     @reno-dropdown-border-color: #d9e1ea;
     @reno-dropdown-border: 1px solid @reno-dropdown-border-color;
     @reno-dropdown-nav-icon-color: #667982; //#97aab4;
     @reno-page-list-link-color: #7a002b;
     @reno-page-list-link-open-color: #bb153e;
     @reno-page-list-icon-color: @reno-link-color;
     @reno-page-list-link-active-color: @reno-link-hover-color;
     @reno-page-list-link-hover-color: @reno-link-hover-color;
     @reno-page-list-action-link-color: #fff;
     @reno-page-list-action-link-background-color: @reno-link-color; 
     @reno-page-list-action-link-hover-color: #fff;
     @reno-page-list-action-link-hover-background-color: @reno-link-hover-color;
     @reno-inputfield-border: 1px solid #d9e1ea;
     @reno-inputfield-input-background: #f0f3f7;
     @reno-inputfield-input-border-color: #b1c3d4 #cbd7e3 #cbd7e3 #cbd7e3;
     @reno-inputfield-select-background: #f0f3f7;
     @reno-inputfield-select-border-color: #cbd7e3;
     @reno-form-radio-checked-background: @reno-muted-text-color-alternate;
     @reno-offcanvas-text-color: @reno-text-color;
     @reno-offcanvas-link-color: @reno-text-color;
     @reno-offcanvas-link-hover-color: @reno-link-color;
     @reno-offcanvas-link-open-color: @reno-link-color;
     @reno-offcanvas-background: @reno-secondary-background; 
     @reno-offcanvas-search-background: #fff;
     @reno-language-tab-background: transparent;
     @reno-language-tab-color: @reno-text-color;
     @reno-language-tab-current-background: #d2dce6;
     @reno-language-tab-current-color: @reno-primary-headline-color;
     @reno-language-tab-hover-background: @reno-muted-background;
     @reno-language-tab-hover-color: @reno-text-color;
     @reno-language-tab-empty-color: @reno-muted-text-color;
     @reno-table-header-color: @reno-muted-text-color-alternate;
     @reno-table-header-current-color: @reno-primary-background;

    I think it'd be worth updating to the defaults to something like this - seems an easy step in the right direction.

    • Like 5
  21. We're very keen on producing accessible websites (hey, I'm sure we all are) and we make sure that any website designs we create hit accessibilty targets. We do a lot of work with public sector bodies who have legal requirements to meet. But it looks to me as if the default admin interface doesn't hit those targets.

    Running the WAVE accessibility tool on a default admin page pulls back a bunch of contrast errors and about 10 other errors.


    We can fix the contrast errors easily enough (especially now we have the Less module) and I suspect most of the other errors should be relatively east to fix (they mostly seem to be missing labels and broken aria tags) but one thing that looks more problematic is being able to navigate using the keyboard. At the moment you don't seem to be able to use the dropdown menu or page lister without using the mouse. Keyboard navigation is one of the legal requirements for lots of our clients here in the UK.

    So before I dive in has anyone done any work on fixing accessibility in an admin theme? Or is this a fundamental issue with UiKit?


    EDIT: seems you can tab onto the page lister in Chrome even if you can't in Firefox, which improves things a lot but I still can't seem to use the dropdown menus...
    EDIT 2: So in Chrome you can tab to the top nav menu items but there's no visible focus. And whilst you can't view the dropdowns (at least I can't) then you can navigate to top level page.


    • Like 3
  22. This was a site we put together for the department of Arts and Culture at Queen Mary University in London (QMUL).



    QMUL invited artists to converse with academics from across the university: A dentist spoke to a sculptor. A performance artist to a historian. A mathematician to a choreographer...


    The site needed to showcase not only the work of the artists but also reflect the back and forwards of the conversations which toook place during lockdown and were recorded over Zoom. We ended up implementing templates which allowed the admins to upload various different types of media for each side of the conversion - mostly video clips of the Zoom sessions but also slideshows, mp3 audio files, images and documents. To do this we used a few ProFields fields, most notably Repeater Matrix.


    We also built a simple events management system for an online Conversation Week event.

    Other modules we used included ProCache and Page Field Edit Links and Login Persist.

    On the front end we used PhotoSwipe for the slideshows and Plyr for the embedded audio and video files (mostly to give a consistant look).

    Oh and the css animated menu icon is from https://jonsuh.com/hamburgers/ - which are really useful (honestly I think I've used them in our last 4 projects).

    • Like 6
  • Create New...