CSS Grid Layout is the most groundbreaking thing that has happened to CSS specs — in the past 2 years at least. I won’t do the whole genesis of how it came to be, others have done it already. Instead, let me tell you how the websites of Montreal’s high profile music festivals were the perfect use case for it.
The challenge
First, a little backstory. Last year, we developed a platform for our client evenko — producer and promoter of these festivals — that endowed them with greater content management capabilities along with implementing a clean and consistent UI on the front-end across all websites.
A greater level of control for the administrative users comes with the necessity that every UI container be highly modular. One of the things that kept us on our toes about that aspect is how these blocks were going to systematically arrange themselves. To put it simply, one feature — which we refer to as module — can be displayed in a container which in turn could have various widths. Here’s a sketch of the different containers we find on the websites:

- ContainerA:
Spans the full width - Container B:
Spans the full width inside the layout wrapper - Container C:
Spans half the window width - Container D: Spans half the layout width
These blocks all stack up inside this one parent div (.module-container) and the order is entirely to admin’s discretion. With that in mind, some Flexbox fiddling had to be done to take into account every possible order — especially the half-widthblocks. For instance, combinations like:
- C – C
- D – D
- C – D
- D – C
- D – C – D
- C – C – C
- and so on…
are all problematic at first. In a normal set up, 2 half-width blocks sharing the same row is business as usual: just wrap ’em in a flex parent. But this is not possible here, remember? Admin has full control of what’s being thrown in the module container and we therefore cannot assume they’re going to group them 2 by 2 or have an even amount of half-width blocks.
CSS Grids to the rescue
This past winter, with the websites theme overhaul phase and with a now strong cross-browser support for CSS Grid Layout Module, it was time to let go of the way it was done last year — which was based on Flexbox and required lots of CSS classes and exceptions to cover ALMOST all scenarios.
The solution
#sass
$gutter: 20px
$layout-max-width: 1180px
$latGutter: calc((100% - #{$layout-max-width + 2 * $gutter}) / 2)
.module-container
display: grid
grid-template-columns: minmax(0, #{$latGutter}) repeat(2, 1fr) minmax(0, #{$latGutter})
grid-column-gap: $gutter
There’s actually a bit more that goes with it, but it is essentially the backbone of the entire grid system. This bit of code deserves some explanation, so let’s break it down by superimposing it on top of our mocked layout (sorry in advance for all the arrows).

When creating a new modules, the admin user is given 2 parameters to select from to set its size:
Module size:
- Full width (default)
- Half width
Constrain module (is the above size relative to wrapper or window):
- Yes
- No (default)
The value of the parameters yields a specific CSS class.
#sass
.module-span-full
grid-column: 1/-1
&.module-constrain
grid-column: 2/-2
.module-span-half
grid-column-start: 1
grid-column-end: span 2
+ &
grid-column-start: -3
&.module-constrain
grid-column-end: span 1
Now for example, creating modules with size A, B, C, and D respectively, blocks will naturally stack up inside the module container as follows:

That’s the gist of it. Go see it live in action on Osheaga, IleSoniq, Heavy Montreal websites.
Editor’s note: Last week Chloé attended the “Advancing Women in STEM Forum” upon invitation from YES Montreal. The goal of the event was to put forward recommendations on 4 discussion points as part of a pilot project for SAP, CAE, and the Xaphan group. We’re exceptionally proud of Chloé’s commitment to championing diversity in the science and technology industries, and present her summary of the event here (in French only).
L’organisme YES Montréal organisait lundi 29 janvier, un forum pour aider à l’avancement des femmes en STIM (sciences, technologie, informatique et mathématique): «Advancing women in STEM forum». L’évènement se déroulait dans les bureaux de SAP à Montréal.
Le forum était sur invitation seulement. Faisant partie de la communauté des femmes en tech de Montréal et dû à mon engagement auprès de celles-là, j’ai eu la chance d’en faire partie.
Pour celles et ceux peu familiers avec l’état de la femme en STIM, voici une courte explication.
Les femmes sont évidemment présentes de façon significative sur le milieu du travail, de nos jours. Cependant toutes les industries ne se valent pas quant à la présence égale des femmes et des hommes. L’industrie des STIM est une de celles-ci. Confrontées à un certain nombre d’obstacles économiques, sociaux et institutionnels, les femmes comptent en général pour 20% des effectifs totaux. Ce chiffre peut descendre à moins de 10% si on considère plus en détails par exemple, l’intelligence artificielle ou
les cryptomonnaies. Pourtant, il est avantageux et nécessaire pour une entreprise souhaitant se démarquer au niveau de sa productivité, d’avoir plus de femmes dans son équipe, et plus de diversité au sens large. En effet, de nombreuses études citent cet aspect comme un avantage numéro un à ne pas sous-estimer. Le cabinet Deloitte a sorti un rapport en novembre 2017:
Deloitte déclare que pour assurer la prospérité future du Canada, nous devons véritablement faire preuve d’inclusion et que nous ne pouvons nous permettre d’attendre
Les organisateurs et organisatrices de YES Montréal ont souhaité rassembler des personnes de l’industrie technologique mais pas seulement. Il y avait également des femmes et des hommes qui venaient du monde des affaires, du milieu universitaire, etc.
Le but était de mettre ensemble des cerveaux qui allaient réfléchir ensemble à quatre problématiques bien précises, inscrire des actions claires en face de celles-ci, puis appliquer ces recommandations lors d’un projet pilote dans trois entreprises: SAP, CAE et le groupe Xaphan.
Les quatre problématiques à discuter étaient les suivantes:
1. L’environnement de l’industrie des STIM
Manque dans l’équilibre vie-travail, disparité salariale, surmonter les défis de la réinsertion sur le marché du travail après une période d’absence professionnelle, etc. Tout ceci continue d’aggraver le phénomène de “leaky pipeline” des femmes en STIM.
2. Les biais consciences et inconscients contre les femmes en STIM
Le parti pris sexiste inhérent à l’industrie considère les STIM comme un champ masculin, qui continue d’imposer des stéréotypes sur les femmes, leur performance et leur capacité à diriger en STIM.
3. Le chemin vers le leadership
La recherche a montré que les femmes parlent moins de leurs réalisations en tant qu’expertes sur un sujet donné sur le terrain par rapport à leurs homologues masculins.
4. Systèmes d’avancement et de soutien de haut en bas
Manque d’encouragement, de modèles, de programmes de mentorat et de soutien systématique dans le milieu du travail continuent à entraver l’avancement des femmes dans le domaine.
J’ai assisté aux deux premiers ateliers. Nous étions un groupe de personnes rassemblées dans une salle, une modératrice orientait la discussion et une autre personne prenait des notes. Le tout a été par la suite compilé dans un document qui sera donc remis aux trois entreprises afin de les mettre en pratique et de tester par la suite les répercussions de ces recommandations.
L’évènement étant soutenu financièrement par l’organisme gouvernement Condition féminine Canada, il se devait d’avoir un impact important sur l’avancement des femmes dans l’industrie. Que les retombées soient positives ou négatives, des conclusions pourront en être tirées et au moins alimenter les débats.
YES Montréal est un fournisseur de services communautaire, en langue anglaise exclusivement, qui aide les Québécois à trouver un emploi à l’échelle de la province, ainsi qu’à créer et développer des entreprises. Il s’agit d’un OSBL, crée en 1995.
A new composer package from Plank for handling arbitrary data in Laravel 5 applications
It has been roughly six months since we released Laravel-Mediable, our first open source Laravel package. Developing this project has been a truly fulfilling experience. Leading this project has made me a better developer by making me better at thinking about API design, writing unit tests, documenting my code, and much more knowledgeable about the internal workings of the Laravel framework. The response has been even more amazing: to date, our package has been downloaded through composer over 2,700 times, has been starred 250 times on Github. We have merged 22 pull requests from the community, and have received nothing but positive feedback and accolades from the many developers who have made use of our code. Our package has even been featured by Freek van der Herten.
With all of that in mind, it was only natural that we would want to find new things to contribute to such a welcoming open source community. Today, we are happy to announce Laravel-Metable our newest Laravel package. Check out Laravel-Metable on GitHub, browse the documentation or read on for more information about how this package came to be.
Customizing Templates
While building a custom CMS for one of our clients, we came across an interesting problem. The site we were building allowed our client to create new pages and assign each page to a template to customize its appearance. However, each template needed a handful of additional fields to modify how the template would behave. We needed to figure out how to store and retrieve these additional fields. With dozens of templates, each having up to ten extra fields, we couldn’t simply add all of these as columns to the pages table as it would quickly become unwieldy.
It immediately occurred to us that other publishing platforms had previously solved a similar problem. Though Plank has mostly moved away from using WordPress for our client work, the platform was able to serve as an inspiration for how to tackle our problem. In WordPress, just about all content is some form of “post” in the wp_posts
table and all custom fields describing or modifying these posts are “meta” in the wp_post_meta
table. Meta is effectively a key/value pair with a foreign key to the wp_posts table. This simple structure allows WP developers to attach a virtually unlimited number of additional fields to their post types, without needing to change anything in the database.
Of course, we didn’t want to simply rewrite WordPress’s implementation of Meta for Laravel. Though the post meta API is relatively straight forward, We had a number of complaints with the way WordPress handled things:
- Meta is intrinsically tied to the wp_posts table. Though the code base does include mechanisms for attaching meta to other WP Object types (e.g. users, taxonomies, terms), the database tables for these need to manually created, and each requires a separate table.
- Anything added as meta is cast to a string and always returned as a string. If you need to handle any more complex data types, it is up to the developer to serialize the values before applying it as meta, and then unserialize it before using it in a template.
- The API allows setting multiple values to the same key and sometimes returns an array of strings instead of a string. This inconsistency can cause confusion and problems for indexing.
We searched the ecosystem of existing laravel packages hoping to find something that would address our needs. We found a handful of packages that tried to address the problem, but each came up a little short. Most of the packages we found suffered from similar issues: a lack of polymorphism, a lack of dynamic typing and/or a complete lack of caching. Clearly, there was a gap in the ecosystem that we could fill.
Building a Package we are Proud to Release
Over the course of the holidays, I devoured Adam Wathan’s stellar video course, Test-Driven Laravel. Having completed all of the videos published to date, I was eager to give TDD a spin. Given its clear feature set, this project seemed like an ideal candidate to be able to think about what the tests might look like before writing any actual code. This approach proved to be a significant boon to the project, as thinking about testable features instead of going straight to implementation made it much easier to think about meaningful abstractions, and helped keep the code cleaner. I am happy to announce that the initial release of the package has 100% test coverage!
The final package is comprised of three primary components:
PlankMetableMetable
Most users of the package will interact almost exclusively with this trait, which can be dropped into any Eloquent model to extend it with all of the features of this package. The trait adds a number of helper methods and query scopes to the model to allow them to interact with Meta.
The trait uses a polymorphic one-to-many relationship under the hood for associating Meta records, however, this behavior is abstracted away from the users, who only need to concern themselves with the key/value pairs that the meta represent. For example
$model->setMeta('key', 'some value');
$model->getMeta('key');
By building on top of Eloquent’s relationship system, we were able to take advantage of built in functionality for eager loading and caching the loaded meta in memory to save unnecessary database queries. We are patching into the system, however, to keep the meta indexed by key, to make lookups even faster.
PlankMetableMeta
Meta is an Eloquent subclass which keeps track of one key/value pair of data. In addition to these two fields, each meta record also tracks a polymorphic foreign key to the Metable model it is attached to and a “type” field which keys track of the kind of data it is storing, so that it can be returned in the proper format.
Meta records store the value field in the database as a string. Any values passed need to be serialized to a string for storage and then unserialized back to their original type. The data type Registry (below) handles this serialization, but each Meta instance will cache the unserialized value upon access, to optimize cases where rebuilding the value is an expensive operation (e.g. loading other models from the database).
PlankMetableDataTypeRegistry
One of our most important goals was creating a system which could store and retrieve any number of data types, whether they be scalar values or complex objects. Rather than implement a long switch or if/elseif statement for determining how to handle a particular value, we resolved to construct an abstracted solution that would be fully extensible. Though our package comes with a fairly exhaustive set of supported data types out of the box, users can add support for their own classes by registering their own Handlers which take care of serializing and unserializing the data.
The result of this implementation is a package that we think is not only very robust, efficient and extensible, but extremely intuitive and user-friendly. We hope you enjoy it!
Enjoy our Laravel package? We would love your input! We encourage anyone to report any issues or feature requests on the project GitHub page. Pull requests are also welcome.
Updating our Toolset
While the world was busy ushering the new year with parties and celebrations, the Gregorian calendar wasn’t the only thing experiencing a transition. December 31, 2016 marked the end of active support for PHP 5.6,
the final release of the PHP 5 branch. PHP 5.6 will continue to receive support for critical security issues only for the next two years, but now is as good a time as any to make the leap to PHP 7.
Due to the end of active support for PHP 5.6, Plank is announcing that all new projects will be written in PHP 7.0 or above. This means that our contracts have been updated to require our clients provide hosting with PHP 7.0 or PHP 7.1. As always, we are happy to consult with our clients to help them find hosting tailored to their needs or even perform the server set up ourselves.
We will continue to support existing maintenance projects on older versions of PHP, though we will be encouraging site owners to consider upgrading whenever significant changes are planned.
What’s the Rush?
While it is true that with a full two years of security support still ahead of it, PHP 5.6 is far from unusable at this point, moving to PHP 7 comes with a large number of benefits.
- Efficiency: First and foremost, PHP 7.0 is leaps and bounds faster than its predecessors, pages load faster and the server can handle more requests in parallel. Zend’s benchmarks showed that PHP 7.0 roughly doubles the requests that can be handled per second by most of the major frameworks and content management systems. PHP 7.0 even edges out HHVM.
- Scalar Type Hints: One of the most requested and also most controversial new features of PHP 7.0 is the ability to enforce the method argument type for scalar data types (
boolean
,integer
,float
, andstring
). This helps to ensure that code is always operating on expected values. It also serves a secondary benefit of making code more self-documenting, as the method signature can inform the type of input expected.public function setScore(string $player, int $score){ ... }
- Return Types: Similar to scalar type hints, it is now possible to declare the data type of the return value of a function or method. The PHP engine will throw an exception if the return value is not of the expected type, helping to catch unintended bugs. Again, this also makes code more self-documenting.
public function getScore(string $player) : int { ... }
- Null Coalescing Operator: A common task in PHP development is checking if a variable is set before it can be worked with. The process for this can be somewhat verbose:
$name = isset($_GET['name']) ? $_GET['name'] : 'John Doe';
With PHP 7.0, a new operator makes this process much cleaner. The “null coalescing operator” checks if a variable and return it if it exists and is not null, otherwise returns a fallback.
$name = $_GET['name'] ?? 'John Doe';
These are only the features that most excited us, but these are just the tip of the iceberg. Find out about these features and a number of others on the official PHP 7.0 migration page.
What about PHP 7.1?
PHP 7.0 has been out for over a year now, so hopefully most of the above is already common knowledge. In fact, PHP 7.0 isn’t even the newest version. In early December, PHP 7.1 was released, bringing with it a number of other exciting changes.
- Nullable Type hints and Void Return Type: The method argument and return type hints added in PHP 7.0 become more robust, making it easy to specify that an argument or return value can be of a specified type or null. The void return type
has also been added to specify functions which should not return anything. - Class Constant Visibility: class constants can now be restricted to
protected
orprivate
visibility, to keep information important to the internal workings of a class from being exposed. - Iterable Pseudo-Type: A long time headache in PHP has been the fact it is possible to typehint for arrays or objects implementing
Traversable
(such as iterators and collections), but not both. Theiterable
pseudo-type will now allow you to ensure that your input will work with aforeach
loop.
For the full list of features introduced in 7.1, see the PHP 7.1 migration page.
Plank is not requiring 7.1 in our contracts yet, but we always encourage our clients to use the most up-to-date software available. Whatever version you use, we look forward to crafting great websites with you using the best tools available!
A new composer package from Plank for handling media in Laravel applications
A few months ago, Plank decided it was time to redesign our own website. Rather than just reskin our old WordPress site, we wanted to rebuild from the ground up. The Laravel project was chosen for the project as the it has recently become a favorite among our developers. In reimagining our website, we didn’t just want to recreate what we had before. We sought to embark on a project that would allow us to innovate and come up with new tools that we could provide our clients.
Today, Plank is happy to open source one little piece of innovation that emerged from this exercise: Laravel-Mediable. Feel free to check out the code on GitHub or read on to learn a little but about how this new tool came to be.
Building a Media Management Interface
While building the CMS for the new plankdesign.com, we realized that we would need to come up with a way of handling the many media files that would be used throughout the site. The various content types that make up the site make use of thumbnails, banners, galleries, inline images, and even downloadable attachments. hardcoding links to the files in the public/webroot directory is not a sustainable solution.
Fortunately, over the years, we have experimented with numerous ready-made file management plugins, such as CKFinder, ELFinder, Filemanager, WordPress’s Media Library, etc. This has given us plenty of time to get a sense of which features make programming easier and what kind of interfaces lead to a smooth user experiece. We came up with the following list of requirements.
- Files should be presented in a grid or list similar to Mac OS Finder or Windows Explorer.
- Folders are a great way to keep content organized.
- Drag/drop uploads are a must, system uploader should be used as a fallback for older browsers.
- Files should present some kind of thumbnail.
- Models should attach to media files using a unique identifier, not by url, path or filename.
- Models should not require any change to their schema to attach new media
- Models must be able to attach multiple different media for different needs (e.g. thumbnail, featured image)
- Models should be able to have any number of media files attached for a single need (e.g. a gallery)
- Media should be reusable without needing to be re-uploaded
- Allow media to be stored in either public and private directories, as needed
- Must be easy to restrict uploads and attachments to particular file types, to avoid causing errors (e.g. thumbnail must always be an image, download should be an archive)
After a few weeks of work, we came up with a system which met all of our requirements. Here is a little peek at the user interface that lives on the backend of plankdesign.com

The code that we are open sourcing today represents the backend component that we built this media management on top of. It sadly doesn’t include the interface shown above, but could serve as a foundation for others to build something similar – or something completely innovative.
A Quick Tour
The Laravel-Mediable package consists of three main classes:
PlankMediableMedia
: an Eloquent subclass which keeps track of one file, including its location on disk and its type.PlankMediableMediaUploader
: A utility class which uploads files to your server and generatesMedia
records for themPlankMediableMediable
: a trait that can be added to any other Eloquent model and provides a number of methods for easily attaching and detachingMedia
records
Example Usage
Upload a file to the server, and place it on the filesystem disk named “uploads”. This will create a Media record that can be used to refer to the file
$media = MediaUploader::fromSource($request->file('thumb'))
->toDestination('uploads', 'post/thumbnails')
->upload();
Attach the Media to another eloquent model with one or more tags defining their relationship.
$post = Post::create($this->request->input());
$post->attachMedia($media, ['thumbnail']);
Retrieve the media from the model by its tag(s).
$post->getMedia('thumbnail')->first()->getUrl();
For more in-depth documentation and installation instructions, check out the readme page on github.
Comparing to Laravel-MediaLibrary
A popular Laravel package called Laravel-MediaLibrary released by the Belgian agency Spatie already attempts to do something very similar to our Laravel-Mediable package. We drew a lot of inspiration from this fantastic package, but found that it didn’t quite meet all of our needs. Our package is a little bit more complex to use, but offers more flexibility. Here is a quick comparison to help you decide which package best suits your use case.
spatie/laravel-medialibrary | plank/laravel-mediable | |
---|---|---|
Relationship | many-to-one polymorphic, each media record is owned by one related model | many-to-many polymorphic, each media record can connect to any number of related models, and vice versa. |
Filesystem | Files are stored in directories named after the media id relative to the disk root | Files can be stored anywhere on the disk |
Association Identifier | Each media record belongs to one “collection” | Media can be attached to a model with any number of “tags” |
Aggregate Types | Support for images and pdfs | Configurable support for any number of custom types |
Miscellaneous Features | Glide manipulations | Synchronization commands |
Enjoy our Laravel package? We would love your input! We encourage anyone to report any issues or feature requests on the project GitHub page. Pull requests are also welcome.
After 10 happy years of working together, the Plank team is happy to announce that we’ll once again be collaborating with non-profit publisher Sun Magazine on the next version of their website—an entirely reimagined digital home for over 40 years of high-quality content and articles.
A shared history
Plank first began working with the Chapel Hill, NC based magazine in 2006, when their team was looking to redesign their entire site. It was an exciting challenge that fell smack into an industry we were – and still are – deeply passionate about; arts and culture. Together, we created an online destination where readers could explore all of the rich literary and visual content The Sun had to offer. Since that day, Plank has been there to support and partner The Sun as it navigates the shifting paradigms and standards of both the web and publishing industries. We’re extremely proud of our shared history and of the trusting relationship we’ve forged with this talented and creative team of publishers.
A shared vision
The Sun contract comes on the heels of a series of intensive on-site workshops meant to get at the root of the client’s needs. This initial stand-alone discovery process allowed us to better understand every stakeholder’s unique perspective and desires. It also allowed us to scope out some of the more granular technical details up front and to really collaboratively consider the future of online publishing and direct subscriber business models before diving into development. Once we were all on the same page, we delivered a unified Digital Project Strategy alongside our project proposal—which included the need for a responsive design refresh, a modernized CMS to accommodate their extensive archive and considerable UX-oriented upgrades. Our common goal? To create a more immersive and enjoyable reading experience for loyal and new readers alike.
“We’re pleased to be working with Plank to make thesunmagazine.org the online home of our forty-year archive and an inviting site for longtime subscribers and new readers alike. We’re excited to see what Plank develops.”
David Mahaffey, Digital-Media Director at The Sun
Shared values
Beyond a great working relationship, Plank and The Sun share a few core values that truly drive the kind of business we try to seek out and attract. Defined as a “an independent, ad-free magazine that for more than forty years has used words and photographs to evoke the splendor and heartache of being human. Each monthly issue celebrates life, but not in a way that ignores its complexity. The personal essays, short stories, interviews, poetry, and photographs that appear in The Sun’s pages explore the challenges we face and the moments when we rise to meet them.” Centered around transparency, accessibility, diversity and simple stories, The Sun team delivers content that’s meaningful and impactful, and that’s a mission we’re proud to be a part of.
We don’t want to give away too much, but suffice to say, we’re delighted to be building on an already excellent working relationship with The Sun, we’re having a blast working on this new project and we’ll be sharing our new work as soon as we can.
While we’re very proud of Plank’s 12 years running, the beloved building we call Home is celebrating its 100th anniversary this year.
Montreal’s cultural aficionados, yogis, the art vernissage crowd — they all know about the Belgo, but . . . do you?
Getting to know the Belgo Building:
- Built in 1910;
- Originally a department store;
- Situated in downtown Montreal in the heart of the Festival District;
- Home to 5 floors of galleries, artists studios, agencies, yoga studios, and other important cultural organizations.
Plank’s been a part of the Belgo for over a decade. There are lots of little things we have spotted over the years that make working in this iconic building even more “interesting”.
- Located just behind several important government offices, we have a perfect view of virtually any march, protest, or demonstration in Montreal.
- Situated next to Musique Plus means lots of visits from Boy Bands. This also means lots of teenage girls and lots of shrill screaming and crying! Plankers often get caught in the action.
- A very happening place during Montreal’s annual Nuit Blanche.
- For aerial navigation, someone made sure to add this important marker in the back alley.
- Alien crop circles on the roof!
- Lastly, the building’s hallways provide excellent lighting for impromptu photoshoots.
One new piece of Belgo trivia we discovered this fall was that our office was previously occupied by a company called Aavanti Tuxedos — first as a whole warehouse and then secondly as a split warehouse and stone washing factory. The irony here is that Plank’s President, Warren Wilansky, would rather starve than ever wear a Tux.
If you’ve never visited the Belgo Building, we encourage you to spend an afternoon or even just a lunch hour to come explore the great Belgo. We promise you will see the unique charm that makes this building so special.