Whether you’re a seasoned speaker or just starting out, this guide will provide you with tips to help you make the most of your conference talk submission and increase your chances of being selected to speak.
Don’t let perfect be the enemy of good. The best way to start giving talks is to just start submitting and see what happens. You don’t need to craft the perfect proposal and you don’t need to be an industry-leading subject matter expert.
Don’t let any excuse stop you. So many conferences and events are desperate for anybody who simply has the willingness to speak and a little something to share.
But if you’re still unsure, you may want to consider…
If you’re not sure about your public speaking and want to start in a low-pressure environment, I would definitely recommend pitching any topics to a local meetup or user group.
As a former meetup organizer, I can tell you that they are constantly looking for willing speakers.
Meetups are also a great place to workshop a talk or topic that you are planning to present for larger audiences at a conference.
A lot of people that I talk to feel that they need to be an expert on a topic in order to give a talk about it. This couldn’t be further from the truth. While conferences and audiences love to highlight deep subject matter experts, the insight of beginners can be just as valuable.
A common tactic for conference talks is to submit a topic that you are interested in learning more about. If your talk is accepted, it gives you an excuse to learn that topic deeply — and your fresh perspective can make the topic more accessible to other beginners.
This tactic is sometimes referred to as “Conference Driven Development” 😂
Choosing a topic can be difficult. There is a strong temptation to only submit original topics that the world has never seen before. Resist this urge. Your topics don’t have to be unique or novel to be valuable.
In fact, “A beginners guide to X” is probably going to have much broader appeal than “How we combined seven really specific and niche technologies to solve this one problem” — although both of those topics could be interesting!
If you’re stumped for deeper ideas, consider:
I am thrilled to see the resurgence in conferences that is currently underway. There is no shortage of venues in need of up-and-coming speakers.
As a starting point, I would recommend looking at smaller community-organized conferences like DevOpsDays and Code Camps. Often these conferences are hosted by a local meetup group, which makes it very easy to get connected with the organizers and ask them exactly what kind of talks they are looking for.
Don’t be afraid to submit the same talk to multiple conferences (unless the conferences disallow this, but most don’t). Here are some websites I use to find conferences:
Some conferences just require a few sentences or bullet points about your talk, while others may require a few pages of information including a detailed abstract and bio. In either case, remember to think about the abstract from the (potential) audience’s point of view.
It’s important to cover what technologies you will discuss, of course, but you also want to make sure you do a proper introduction to the use case for people who may not know the technology.
One of the most valuable talks I ever attended was about a topic I needed (debugging strategies) in a language I had never used at that point (.NET)
So really, what you want to tell your audience in your abstract is: what will they learn from attending your talk?
Making the most of a conference could be a topic for an entirely new blog post, but I want to share my top two most important tips:
The first point should be obvious. Most of us are used to spending 10-12 hours a day on our butts. Shifting that weight to our feet for a week can be a lot.
The second point is less obvious. At my first conference I felt that I was missing out any time I wasn’t in a session. Now I know better. While the talks are amazing for revving my mental engine, the “Hallway Track” is where the best conversations and connections happen.
The only way to take advantage of this is if you leave some wiggle room in your schedule and aren’t afraid to take breaks when you need them.
This post was inspired by the discussion in the OTel End User Working Group’s session on writing CFPs to help OTel community members submit talks for the upcoming conferences, including Observability Day at KubeCon EU.
Many thanks to Reese Lee, Daniel Kim, Rynn Mancuso, Juraci Paixão Kröhling, and Adriana Villela, and the other members of that session. A lot of the ideas in this post come from the amazing people in that group and the discussions held. (If you were in that group and would like me to add your social link to this list, please let me know!)
]]>I don’t really do New Years Resolutions, but one of the side effects for me of the past three years has been an ever increasing clarity on what works for me and what doesn’t. Along with that clarity has come a willingness to simply say “Ok, Bye!” to anything and anyone that doesn’t bring me in the direction of being the person that I want to be.
With that in mind, there are some professional tools that I have been using for most of my career that I will be stepping away from this year, for various reasons.
Here’s what I’m ditching, in no particular order:
As a blogger and internet professional, I have always believed in the importance of convenience as well as security. That is why, for a long time, I have been using CloudFlare as a content delivery network (CDN) and DNS provider for my websites. However, after the events of last fall, I have decided to ditch CloudFlare and find a new provider.
The reason for my decision is CloudFlare’s support of Kiwi Farms, a website that has been known for promoting illegal speech and harassment. While CloudFlare eventually agreed to repeated requests from members of the community and advocacy groups to de-platform the website, it took them way too long.
I believe that companies have both an ethical and a legal responsibility to take action against hate speech and harassment. By refusing to take immediate action against Kiwi Farms, CloudFlare failed to live up to that responsibility. Their initial reluctance to ditch a website that promoted hate speech and harassment is unacceptable, and I cannot in good conscience continue to use their services.
I’ve been using twitter on-and-off since 2006! This past year I moved into Developer Relations and twitter took a prominent role in my day-to-day activities.
Twitter has always been there as a sort of virtual rolodex of the amazing people I’ve met in tech and life over the years. At conferences, I maintained the line that a twitter handle was better than a business card — and as a result I rarely carried business cards.
I’m not completely quitting twitter or deleting my account, but I am going to be stepping back and no longer actively engaging or posting original content. Instead, I’ll be focusing my social energy in community-built spaces like hachyderm.io, and smaller communities on discord and slack.
I am extremely eager for the future of federated and distributed social networking. Mastodon and ActivityPub represent huge strides to the open, interconnected internet that I imagined in the 90s. As others have pointed out, the discussion and communities on Mastodon feel much more like the bulletin boards and forums of my early internet life.
I look forward to seeing how the community handles the challenges of scale that come with the new wave of interest in Mastodon and other federated social networks. I’m not yet convinced that ActivityPub is the final destination for social networking, but it is absolutely an exciting stepping stone.
Here are some places where you can find me in 2023:
I love WordPress for what it has done to democratize publishing on the web. I am also forever grateful for the accessible on-ramp to development that WordPress represents for so many software professionals. But I’m moving this website to a static site builder.
This is a really tough one for me. WordPress has been a tremendous part of my development career. I first used WordPress in 2006 and started building custom themes in 2010. WordCamp NYC 2012 is where I decided that I wanted to commit to becoming a developer. I was the organizer for the Burlington WordPress Meetup for six years.
Why am I walking away after all of that?
Well, mostly just because it doesn’t work for me any more. But I’m also not sure who it works for now. The leadership of the WordPress community needs to decide if WordPress is going to embrace the consultants and agencies that made it the defacto publishing standard or if it is going to continue trying to be a less usable alternative to Square Space.
It’s been a while now since I’ve been paid to build anything in WordPress, and my own WordPress installation was starting to look a little… crusty. I never even updated it to start using Gutenberg.
And so, I’m moving this website to Jekyll. I’m looking forward to the ease of publishing with markdown and a future-proof JAM-stack.
I can’t remember the last time I launched a website without the Google Analytics tracking snippet — it probably had a hit counter. But whether its a low-res gif in the style of a car odometer or Google’s “Universal Analytics”, it serves the same purpose for me — a little hit of dopamine at the knowledge that you somehow stumbled across my blog.
I don’t have anything to sell you here, and I don’t have any reason to gather any information about you. I certainly don’t have any reason to involve a 3rd party in the process of tracking your identity and time here. So for those reasons, I am ditching Google Analytics.
For now, I’m giving Plausible a try. I pay for this service to anonymously track traffic and protect your privacy.
If you like something that I wrote, please come find me and tell me. I’d love to hear from you.
]]>If you’re a senior engineer who wants to understand the architecture of WordPress, then this guide is for you.
So let’s pull back the curtain and take a look at some of the architecture in WordPress:
WordPress was initially built for blogging, and so its core model is called the post. In WordPress, almost everything is a post. The built-in post types besides post
(blog posts) are: page
, attachment
, and link
*.
Pages are of course exactly what they sound like — static pages displayed on the site without regard for chronological order.
Attachments are used to identify file uploads (which can then be included in other posts).
(*) There are also some “hidden” post types used for navigation menus and other content. The link
post type is deprecated, but was once used for “related blogs.”
Part of what makes WordPress so extensible is this fundamental concept that everything is a post. Plugins and themes can define their own custom post types which gain all of the behavior of posts or pages right out of the box. Of course, they can also be further customized from there.
Custom post types were fully introduced in WordPress 3.0 released in June 2010. They are one of the features that first attracted me to the WordPress ecosystem.
With one table for everything, it would be insanity to attempt to create a column for every possible meta field for every possible post type. Instead, WordPress relies on a post_meta
table which contains key-value pairs of metadata.
The keys can be anything and the metadata persists even if the plugin that originally created it is uninstalled. User meta is handled similarly.
This provides WordPress a great amount of flexibility for managing content and for displaying pages and sections of a website. It also makes WordPress posts much more difficult to index and query against than a normalized SQL database.
If your content management system depends on complex querying based on metadata, you may want to look beyond WordPress… or you may want to integrate a service like Elastic Search or Algolia into your WordPress site.
In addition to metadata, WordPress posts (and other post types) can belong to any number of terms. Terms belong to a taxonomy. The built in taxonomies are post_category
and post_tag
. They are only applied to the post post type, although they can be extended to other post types, including page, through hooks.
Creating custom taxonomies and connecting them to custom or built-in post types is extremely straight forward, requiring a single function call.
Now we get into the meat and potatoes of WordPress customization: action hooks. Action hooks are called at various points in the request lifecycle, as the page is built. They allow callback functions to be injected at essentially any point in the WordPress system.
This is the key to WordPress’ extensibility and also a cause for frequent developer frustration. Action hooks are a bit more finicky than more advanced solutions like pub/sub or event listeners. They have a concept of priority, and they often operate on global variables that are “built up” through a series of callbacks which may lie in multiple plugins.
WordPress includes myriad built-in action hooks. Many well-made plugins will also include their own action hooks so that they can be extended as well as WordPress core. These “extendable extensions” are like a dream come true for developers.
All of this combines to give WordPress unparalleled extensibility amongst CMS platforms.
In addition to hooks, WordPress provides a number of filters. Filters are essentially action hooks except that the callback function takes an argument (the data being “filtered”) and returns the processed argument.
There are few distinctions in WordPress between plugins and themes. Either one can run any arbitrary PHP at any point after it has been loaded. In the case of themes, this is done through the functions.php file. In plugins it is the main php file for the plugin.
Plugins are loaded just before the theme, however most plugin and theme developers rely on the init
action hook as the first available action hook to begin customization. This ensures that all plugins and the active theme are fully loaded.
WordPress is not an MVC framework. It provides the routing layer for you, and then interprets your templates following a cascading hierarchy — meaning you can have a custom template for every single category, or even every single post, or you can build your entire theme from a single index.php file.
The WordPress template hierarchy, via Michelle Schulp ☜
WordPress 5.0, released in late 2018, introduced the “Block Editor” (also known as the “Gutenberg” editor). Blocks represent a fundamental reimagining of the core WordPress editor, providing a more “WYSIWYG” experience than the classic editor.
Under the hood, the Block Editor uses React.js for the admin editor experience. The content of the blocks is rendered as HTML and saved inside the content of the post or page.
There are several dozen blocks built into WordPress and theme and plugin authors can create their own custom blocks. Registering a custom block requires creating a custom javascript file which can be loaded in the admin using the enqueue_block_editor_assets
hook. This javascript file must call registerBlockType()
in order to alert WordPress to the blocks’ presence and settings.
For most use cases, you can probably find a plugin that provides the block types you need. You can also use the Advanced Custom Fields plugin to create your own custom block types without writing any javascript or react code.
WordPress sidebars are really just “widget buckets” and widgets are simple content blocks that are configured once for all pages on which they appear. I’m not the biggest fan of the way that the sidebars API works, however it is undeniably effective at empowering non-technical users to layout their own websites with pretty much any custom functionality they can imagine.
These can get unwieldy. It is not uncommon to have to go on a plugin and sidebar widget purge after inheriting a WordPress website.
WordPress relies on a lot of global variables. In recent years the core team has made a push to move away from the singleton pattern in core APIs. That work is still in progress and the singleton pattern still persists in core as well as in plugins and themes.
In addition, globals are used for most of the content that appears on a page during a typical request, the_post being the primary of these.
WordPress, quite controversially, relies on absolute URLs for all internal linking. On top of this, PHP arrays are serialized in the database, meaning that find-and-replace operations must be performed in PHP on the deserialized data, rather than directly in MySQL with queries. These two factors make migrating WordPress websites cumbersome relative to simpler PHP platforms.
Clearly, despite some of the potential anti-patterns employed, WordPress is quite successful, powering ~20% of the websites on the internet. As with anything WordPress’s success is multi-factorial; I would argue that it boils down to three things, some of which are actually served by what could be considered anti-patterns:
Accessibility.
One of the core principles of WordPress is to always cater to the least-technically savvy as much as possible. While many of us have heard horror stories, really it is quite remarkable that WordPress makes it possible for regular users to install any of the plugins available and build their own websites.
*This is because even when implementing developer-oriented features, the WordPress core developers carefully consider the impact on their millions of end-users.
On top of this, WordPress provides a gentle curve from non-technical writer to semi-competent developer; I’ve seen myriad users progress from editing a few lines of CSS to building complete custom plugins.
Extensibility. As I noted while discussing hooks, WordPress is immensely extensible, to the point that even it’s plugins can be extended with other plugins. Many of the anti-patterns in the core code persist because of the WordPress community’s commitment to backwards compatibility with the approximately 46 thousand plugins available.
The Right Opinion at the Right Time WordPress was born with a core thesis about website structure: a website is fundamentally a collection of posts and pages, and everything can be boiled down to one of those two types. This strong opinion provided a shared foundation on top of which the many plugins could be developed with impressive interoperability.
Well, that depends.
If you’re just trying to put a few static pages online, you may want to consider a static website builder, but WordPress could also work well.
If you need a simple eCommerce website, you may want to compare Woocommerce (the WordPress plugin for eCommerce) and Shopify.
Clearly, it is purpose-built for blogging and a great solution for that.
Marketers are often already familiar with WordPress, and it provides integrations with most marketing automation and analytics services.
If you need a content-oriented website with multiple authors and editors, WordPress is also a clear choice: Content marketing and WordPress go together hand-in-hand.
While WordPress may not be for everybody or every situation, I hope I have shown that it has merit when applied correctly. Fear not, all hope is not lost.
Many dungeon masters fall victim to the trap of over-preparation.
Spending a lot of time preparing a specific plan for a game can make it difficult to let go of that plan (as I wrote in Part II). One might conclude that planning is a waste of time. As an absolute, this could not be more wrong.
“Planning is essential. Plans are useless.”
Rather than preparing for one story, a good dungeon master prepares for any story.
These days, I need only prepare a few bullet points for any specific session. The rest of my preparation is the accumulated library of material that I have gathered. I can use this material in any combination to guide a story.
This allows me to say “yes and…” to my players more often, building on their ideas rather than squashing them.
When we turn to building software, our goal is to quickly adapt, providing solid solutions to whatever problems arise. In this context, our “library” of material (knowledge) is two-fold: domain knowledge, and technical knowledge.
Technical knowledge is the clearest. It is our knowledge of the tools and patterns that we will use. For example, when using a framework, do we know it well enough to extend existing features instead of reinventing the wheel? Do we know how each feature will scale?
Domain knowledge is more vague, and more often ignored by technical team members. It is no less important though. This is the knowledge of the real-world objects and systems that our software models.
In any project of significance, we will find many domains. These may or may not interact and overlap. For example, consider a simple e-commerce application. For this example we will only have one product for sale, and no shopping cart.
E-Commerce sounds pretty specific for a domain. But when we break it down, we’ll find that there are many subdomains all involved in selling a single item. On a first pass we identify: financial transactions, marketing analytics, shipping.
We could break this down even further. Shipping depends on a system of knowledge for addresses & locations. We’ll also need a way for handling dates, times & durations.
Smarter people than me have written about how to model the real world with domain driven design. That is not the point of this allegory.
Once we have broken down the project domains, it is our job to understand them as well as we can. Most projects will involve both domains we are familiar with and some that are new to us.
If no project ever added new ideas, we would never grow as developers and nothing novel would ever be built. On the other hand, if we attempt a project with no knowledge of any of the relevant domains and tools, we will be doomed to flounder.
The deeper we understand something, the more we can expand upon it or integrate it with something else. The more of a business or project that we understand, the easier it will be to add innovations.
Have a plan from which to deviate.
Part I: Align on your goals
Part II: Letting go
Part III: Know your domain
When an entire QA department is not available, the best QA gains can be had by ensuring every single line of code is seen by at least 2 developers before being merged into the master branch.
There are myriad branching strategies all discussed at length online. My recommendation for small, distributed teams without dedicated QA Engineers is to follow a simplified version of the “git-flow” model. Rather than manage the complexity of release and integration branches, the simplified model has feature and fix branches coming off of master and being merged directly back into master. Keeping each feature or concern on a separate branch makes it much simpler to back out of specific changes, to identify the source of bugs, and to understand how the codebase is changing over time.
Every commit should be as small as possible without breaking functionality, with a good commit message explaining WHY the change was made. For consistency, I like to write commit messages in the present tense, starting with a verb e.g.: “Adds compatibility with Twitter Bootstrap 4.” By keeping commit messages descriptive about the why (rather than the what, which should be self evident in a small commit), other team members can clearly reason about what they might need to change for their future tasks.
The whole point of a VCS (Version Control System) is that you don’t have to do this… the history of you deleting the line is maintained. And if you make a small commit with a good message it will also be easy to find.
Deployments should happen from the master branch, not a specific environment or test branch. The same git ref (commit) on master should be deployable to any environment, so that production can be a binary copy of what was tested on staging. Which brings us to…
Best practices dictate that an “artifact” (or package) be created for staging deployments, and that artifact then be deployed as-is to production, without the build process being re-run. This eliminates a potential avenue for disparity between environments and allows you to always know bit-for-bit what code is running in production.
Large teams can benefit from multiple repositories and a submoduleing system. For teams under ten, I generally prefer to keep all code required to run the entire product in a single repository. This allows the application to be managed in it’s entirety and deployed as a single unit. Internal tools that are re-used between projects should be made available via a package manager such as npm, bower, composer, etc.
Committing vendor code can cause merge conflicts and disparity with packaged libraries. Vendor code should always be .gitignored and redownloaded directly from the source by a build server. This includes internal tools mentioned above, managed via package manager.
Compiled files (usually css, js) are often minified and will cause a merge conflict on every merge unless great care is taken to avoid this. Having the build server re-run compilers ensures consistency between environments. ### Only merge using Pull Requests
Merges make for a very messy git history, making it harder to find information about the code. Merges should only happen into master via pull request. If you are working on a feature branch, and there are new commits on master which you would like to include in your branch, use a rebase instead of a merge. With master updated and your feature branch checked out, type git rebase -i master
— you’ll be prompted to edit the “TODO” using your preferred command line editor. This lets you squash, rename, or delete (drop) commits.
As developers, we love to fix things as soon as we see them. If, after coding for a while, you find that you have committed changes in many areas not related to the feature you are currently working on, a soft reset will allow you to completely undo all of the commits while maintaining the changes in your working directory. You can then commit the changes to individual feature/fix branches as necessary. This is also useful when you would like to rebase but also have the option to SPLIT (instead of squashing) commits. From your branch, run:
git checkout -b my_branchname_backup
git checkout my_branchname
git reset master
Thats it. my_branchname
will now be at the last commit on master, and all of your changes will still be there in your working folder.
Game masters also have an inside joke: “No plot survives contact with the players.”
When I attempt to drive the plot, dictate the player options and the pacing, the players begin to disengage. The same thing happens on teams when a leader begins to white-knuckle the steering wheel.
The heroes are facing almost certain doom.
Upon entering a room full of bones, they catch a glimpse of the artifact they seek. But it turns out to be a fake. And then the bones come to life.
I’ve invested a lot of time preparing for an epic and climactic battle. I spent at least 6 hours preparing this scene, arranging scores of skeleton miniatures.
It is our first hero’s turn to attack…
I wait for them to tell me how many feet forward they’d like to step and which spell they’d like to cast.
Instead, they announce that they’d like to use one of their abilities to teleport the entire party away from the combat… My head rolls in exasperation.
No plot survives contact with the players.
As GM, I could have easily hand-waved a reason for the teleportation not to work. I could have forced the players to follow my plan that I had so carefully prepared.
But that would have deprived my players of agency. In the game, my role is to provide challenges — ideally at the edge of achievable — and it is my player’s role to provide solutions. Just because I haven’t anticipated a solution doesn’t make it the wrong solution.
I quickly dismantled the battle scene that I had spent so long creating, and we move on. In the end, it’s one of the most dramatic and satisfying sessions of the entire campaign.
(Of course, I didn’t let them get away completely — but used the teleportation as a way to take them out of the frying pan and into the fire. The analogy for professional life breaks here.)
Even with the god-like powers of a game master, I cannot create a compelling narrative alone; The players drive the plot as much or more than I do. And the party often goes places I never expected — which is fantastic.
When this happens sometimes I can adapt on the fly, appropriating whatever material I had prepared for what I thought would happen. Often though, I end up discarding carefully prepared material in order to go with the flow.
I just have to let it go. Something entirely new and unexpected happens. The story is better for it and the sessions are more fun.
Being willing to let go is crucial to success with a team. But it certainly isn’t easy. We get attached to our work, our ways of doing things, and even (especially!) our opinions.
New priorities caused by external events (or internal ones) can necessitate letting go of carefully crafted plans and schedules. New requirements can mean discarding days or weeks of work.
This is ok.
As I wrote in the last piece about goals, it is important to stay focused on the overall objective. A truly agile (not Agile) team must be able to check their egos and find a new path forward even when the landscape shifts.
So how can you foster this open, ego-free collaboration and problem solving?
One key is psychological safety. HBR has written on the importance of psychological safety in the workplace.
At my tabletop, our psychological safety comes from the knowledge that we’re all friends and all only acting out a story — and even then, egos can flare and clash.
On a professional team it is even more difficult to maintain trust and psychological safety. We must repeatedly remind ourselves and our team that it’s ok for anybody to:
On my own teams, I like to use the mantra “Problems are ok, surprises are not.” as a quick encapsulation of these permissions.
How do you foster an environment for open collaboration?
Part I: Align on your goals
Part II: Letting go
Part III: Know your domain
In the game, 4-6 players act as characters that they create using randomized dice rolls. One player, the game master, tells the other players about the world and what they see. The players respond by saying what they’d like their characters to do, and the game master will tell them if they need to roll any dice to determine the outcome of the attempted action.
Unlike most RPG video games, the (usual) goal of Dungeons and Dragons is not to win. The goal is to tell a good story. To that end, it is an extremely collaborative game. The players and game master together craft a narrative. There are heroes, villains, growth, remorse, and the usual range of human (or humanoid) emotion. Usually there is a fair bit of conflict too.
In my group, I act as the game master. Even though I’ve been leading professional teams for over a decade, I have learned a lot about project management in the process of adjudicating a world born out of my friends’ collective imaginations.
Join me for lessons from the tabletop…
There is a joke within the roleplaying community: “Never split the party.” Each hero’s individual talents are not enough to stay alive in the dangerous fantasy settings where these games take place.
The first mistake that I made as a new game master was a big one. Instead of giving my group a shared sense of purpose and a common goal to work towards, I let each one of my players decide the individual motivations for their character.
This mistake actually led to a more realistic, though detrimental, dynamic within our group. In the real world, individuals come to a team with their own personal motivations and priorities, just like my D&D players did.
Some are motivated by financial success, others by a sense of craftsmanship. The motives that drive us are as varied as we are.
A team without aligned motivations and goals will find that they often argue unproductively. Consensus becomes nearly impossible without the common ground of shared values.
On the other hand, a team with a shared purpose and a set of common values will find unexpected opportunities. When differences of opinion do arise, there can be healthy debates grounded in objectives.
In the end, I solved my storytelling problem by having a sit down chat with my players, “out of game.” We discussed each person’s real motivations for playing. We then worked to create a set of character motivations that would be compatible (mostly — a little conflict can make the game fun).
As a group we decided that we wanted to tell a story about heroism and saving the world. From then on any debates were about how to achieve the group’s goals, rather than about what the group’s goals were in the first place.
Talk to your team about your organization’s values. This can be a mission statement, but it doesn’t have to be. What is important is that every member of your team is willing to embrace and advance your stated purpose.
Part I: Align on your goals
Part II: Letting go
Part III: Know your domain