If you’re like me, it might not always be easy to get new posts out to your blog. I’m trying to keep a new tech-tip going every regular weekday for a while to see how I keep up with that.

Since my content might not always be the newest, I may want to highlight when something was recently published.

Calculate posts published in the last two weeks

In the following example, I’m going to check to see if a post was published within the past two weeks. If so, I’m going to attach a notice to the title of the post. I’m assuming that the following code is going to go into a loop of posts, or somewhere that we’re already using the correct post ID.

$post_title = get_the_title();
if ( get_the_date( 'U' ) >= date( 'U', strtotime( '-2 weeks' ) ) ) {
    $post_title .= ' — New Post!';
}
echo $post_title;

First, on line one, we’re creating a variable in PHP called $post_title. This will hold the title of the post, which we get with the built-in WordPress function get_the_title(). Again, I’m assuming that we’re already in a loop for a specific post, but if not you can pass the ID of the post as an argument in that function.

Next, line two is going to get the date that the post was published in Unix Timestamp format. I’ve put it into that format to make it easy to compare. I am grabbing the date instead of the exact time since it doesn’t really matter to me if it was exactly within two weeks down to the second, just generally two weeks by day count.

The post publish date is compared to the current time minus two weeks, also in Unix Timestamp format. The PHP function strtotime() allows you to use human readable formats for time conversions, which we’re using to say “give me the time in Unix seconds for two weeks ago”.

If that comparison is true and the post was published less than two weeks ago, we’re going to append the text ” — New Post!” to the post title. By using a period followed by the equals sign, we’re saying that we want to concatenate, or add the new value to the existing variable.

Finally, on line five we’re echoing out the value of $post_title, meaning we’re printing it to the screen. So if I were to use the above code to display titles for this site and this post was published less than two weeks ago, the title would display as Display a Notice for New WordPress Posts — New Post!

How else could this be used?

One way that I use this code is for a custom post type that displays properties for sale for a client. They wanted to highlight some recent listings, and using this code along with some CSS let me put a fancy ribbon on the corner of property listings, as well as list the number of days that the home has been on the market.

Property Listing with new listing notice and number of days on the market

If you have the need to calculate WordPress post publish date compared to the current date, I hope the above snippet has been a good place to start!

Sometimes you’ll have a Gravity Form that you want to keep visible after it is submitted. Maybe you want people to be able to fill out the same form multiple times, or maybe your design looks better with the form still showing.

Gravity forms has a filter hook built in called gform_pre_submission_filter, which can be used to make changes to the form, among other things, after the form has validated (ensured that required fields are filled, nothing is blocked, etc), but before the form submits and notifications are sent. You can learn a bit more about that filter on the Gravity Forms documentation.

We’re going to use this filter and create our own PHP function that will check the form before it is submit, and create a div that holds any confirmation messages that we have set.

// Allow the Gravity form to stay on the page when confirmation displays.
add_filter( 'gform_pre_submission_filter', 'dw_show_confirmation_and_form' );
function dw_show_confirmation_and_form( $form ) {
	$shortcode = '
. '" title="true" description="false"]'; if ( array_key_exists( 'confirmations', $form ) ) { foreach ( $form['confirmations'] as $key => $confirmation ) { $form['confirmations'][ $key ]['message'] = $shortcode . '<div class="confirmation-message">' . $form['confirmations'][ $key ]['message'] . '</div>'; } } return $form; }

First, on line two we add our function, dw_show_confirmation_and_form, to the filter. Notice that we use the parameter $form in our function, which gives us access to details about this specific form.

On line four I’m getting the shortcode that inserts the form into the page. In this case I want it to get the proper ID of the form, and I want to display the title of the form but not its description.

Below that, from line six to line ten, we’re checking to see if there are any confirmations for this form. If so, we’re going to loop through each confirmation and append it to the form shortcode (so the form will display again), then put the confirmation text inside of a div that we’ve given the class .confirmation-message. That class can then be used to style the display of the confirmations.

Finally, on line twelve, we return the form. Since we’ve prepended the shortcode with the ID of the form, when the form submits it will display the form again, followed by our confirmation message.

Gravity Form displaying with confirmation text below it.
Our post-submission form, with the confirmation text displaying below

The code above will make this change to all forms. If you need to target just one form, use the ID of the form and change the filter to include the form number after an underscore at the end. For instance, if we’re making this change to form three, we’ll change our filter call to 'gform_pre_submission_filter_3'.

Edit: A few people have pointed out that this can cause issues with using ajax="true" for your form. This can be due to when the JavaScript is loaded, and some necessary jQuery not loading before this. The following post gives an easy way to make Gravity Forms files load in the footer, but it could potentially cause problems with other extensions or plugins.

You may also want to do other things, like control whether any fields stay filled or not, update without refreshing the page, or scrolling down to the confirmation when complete, but those are lessons for another day!

I have clients that want to ensure that their pages print well so that people can save things offline for later, like recipes or instructions. I don’t print webpages myself, but I can see plenty of useful reasons to do so.

One of the issues when printing a webpage is that you lose context and interactivity. This is usually fine, as the site is probably intended to be read online anyway. But sometimes you want to make it easier for people to use that printed site, like still being able to find a linked page from a printed article.

The Solution: Print Styles for Links

Let’s say that you want to link to FixUpFox, my WordPress maintenance service. You can put https://fixupfox.com as the text on your page so that it prints properly and people can visit the site from their computer later.

The above works for print, whether you link it or not, but usually you’ll want to say something like “For site support I use FixUpFox, because they provide great service at an affordable price for unlimited tasks”. In that case, you’ll want to have some way to display that URL next to the linked text when printing.

Thankfully, there is a media query in CSS that is for print styles. Your browser will pull up that style when viewing the print version of a site. We’re going to use that to create our links.

Making the Print Styles

First, we’re going to make a media query in our stylesheet. This can go at the end of your existing stylesheet, or you can place it elsewhere as long as it loads on the page that you want print styles for.

@media print {
}

Next, we’ll add an underline style for links, so they’re easier to see among text in a printed document that might be in black and white. We’ll add that style to visited links as well to override any potential visited link styling already on the page for underlines.

@media print {
	a,
	a:visited {
		text-decoration: underline;
	}
}

Finally, we’ll use a CSS pseudo-class of :after on links that have an href attribute selector (so it’s not just an empty <a> tag), which is the target URL. We’ll add that target URL attribute of the link (the page that we’re linking to) to the content, after any links on our site. We’ll add a space before the link, and wrap it in parentheses to set it apart from the text. That code looks like this:

@media print {
	a,
	a:visited {
		text-decoration: underline;
	}
	a[href]:after {
		content: ' (' attr(href) ')';
	}
}

This works with any anchor tag that has a target link, even if it’s a text link instead of the URL. So when I type Ongoing WordPress Support and Maintenance, the printed version of that link will be the text of the link underlined, a space, and the URL in parentheses.

The following screenshot shows what the link looks like when we view the page in print mode:

screenshot example of a CSS print style for links
This is a saved PDF of part of this article. Note the URL in parentheses after the link text.

Finishing Up

You’ll likely find that you have lots of things displaying links that you probably don’t need, like the menu to your site, or sidebar content.

One solution would be to use the print styles to hide those portions of the site entirely. After all, if I’m printing a recipe out for later, I don’t need the navigation, header, footer, or anything else to print besides the content of that recipe. Another solution would be to target links in your content specifically, such as using the .entry-content class to get links that are only in your page and post content if you’re using a theme like the Genesis Framework.

Whatever method you choose is up to you, but I hope that this helps you consider the ways that you can use print stylesheets, CSS pseudo-classes, as well as CSS attribute selectors to add more context to your site, whether printed or on the web.

Thanks for following along and putting up with the shameless plugs for my maintenance business!

I don’t remember exactly when I started using Homebrew, but I know that I had been using a Mac as my regular computer for a while and wanted an alternative to manage dev tools. Homebrew would turn out to be my first foray into the concept and practice of package management, and it’s been tremendously useful for me.

I keep a personal MacOS setup guide on Github because I swap laptops or reformat my laptop enough that I want to keep track of what tools I use. Adding Homebrew to my software management suite has been instrumental in making this work. I can install and update software and clean up outdated versions. I even wrote a tutorial on setting up a keyword script last week that makes this even easier for me.

What is Homebrew

Homebrew describes itself as The missing package manager for macOS and for good reason. It allows me to install/uninstall/update/downgrade/manage software used on my Mac directly from the command line.

This saves a bunch of time and overhead, and allows me to bulk install programs. I can take a list of install commands, paste them into my terminal, and have them all run at once. Below is a list of programs that I install with Homebrew on a new machine currently, which turns hours of installation into a few seconds of typing and a few minutes of letting the machine run in the background.

brew install arp-scan
brew install asciidoc
brew install brew-cask-completion
brew install cmake
brew install composer
brew install docbook-xsl
brew install ghostscript
brew install git
brew install highlight
brew install imagemagick
brew install lastpass-cli --with-pinentry --with-doc
brew install nmap
brew install node
brew install openssl
brew install php72
brew install php-cs-fixer
brew install phplint
brew install pkg-config
brew install python3
brew postinstall python3
brew install thefuck
brew install vassh
brew install vim
brew install wget
brew install wrk
brew install zsh-syntax-highlighting

Homebrew Cask

Some programs don’t exist in Homebrew, usually the apps that you use with a GUI, as opposed to command line tools. For these there is
Homebrew Cask, an extension of Homebrew for the software that doesn’t exist in core.

So instead of having to open up Safari on a new machine (or IE for the Windows folks, with a tool like Scoop or Chocolatey – The package manager for Windows) just to download Chrome, I can open my terminal after Homebrew is installed and type brew install chrome to get the latest version of the browser installed and ready to use. No more downloading zipped files, unzipping a package, running the package and accepting pages of prompts, and having to eject the package to delete the install files.

Updates are great too. With the script that I shared last week I update all of my apps every morning, ensuring that I have the latest, greatest, and most secure version. This also means that I am far less likely to open an app on my computer as I’m ready to use it, only to be greeted with a “new version available” dialog to either forget or stop my workflow.

Here are the cask packages that I currently install after I reformat my computer, which covers the majority of apps that I use.

brew cask install alfred
brew cask install arduino
brew cask install boostnote
brew cask install calibre
brew cask install cleanmymac
brew cask install dropbox
brew cask install etcher
brew cask install evernote
brew cask install firefox
brew cask install google-chrome
brew cask install imageoptim
brew cask install iterm2
brew cask install nordvpn
brew cask install owasp-zap
brew cask install qlcolorcode
brew cask install qlmarkdown
brew cask install qlprettypatch
brew cask install qlstephen
brew cask install quicklook-csv
brew cask install quicklook-json
brew cask install sequel-pro
brew cask install signal
brew cask install skype
brew cask install slack
brew cask install spectacle
brew cask install sublime-text
brew cask install suspicious-package
brew cask install telegram
brew cask install transmit
brew cask install vagrant
brew cask install virtualbox
brew cask install vlc
brew cask install webpquicklook
brew cask install caskroom/fonts/font-source-code-pro

Followup and Conclusion

I just learned that Homebrew has a Patreon to support development of the project, and I just pledged a token monthly donation. For all that it’s given me, it’s definitely proven valuable.

Read the documentation for Homebrew for all of the cool things that you can do with it. The project homepage has fairly straightforward installation instructions.

You can see a list of the current Homebrew Formulae, as well as search the available Homebrew Casks to see if your favorite tools are available.

Do you use Homebrew yet? Do you have another method to manage updates that I should know about, or some tools that I’m missing? Let me know here or on Twitter!

One of the first suggestions that I was given when I switched from Windows to Mac was to install and use Alfred, a productivity app for Mac OS X. I have to thank Mason James for the suggestion, as Alfred has been an integral part of my Mac usage ever since. Tomorrow I’ll give an overview of what Alfred is and does, but for now I want to talk about a specific workflow that I made. It’s very simple, but that’s a plus for a starting up tutorial.

Update 11 January 2019: I wrote about a workflow for Homebrew that I started using.

What are we going to create?

The task that we’re setting up is going to be a keyword that will run a series of terminal commands for us. I use Homebrew as a package manager for software on my Mac. This, along with Homebrew Cask allows me to manage most of the software that I use on my computer from the command line.

Similar to an overview of Alfred, I’ll give an overview of Homebrew later, but for now I’ll assume that you can setup both from those sites. Backwards maybe, but I want to show something simple that it can do before walking through setting it up.

So with Alfred I can set keywords that run commands. In this case, I’m going to make a keyword, brew, that when used will run a series of commands to check for updates of installed software, perform those updates, clean up outdated software versions, and check that everything is functioning properly.

We’re going to have eight commands run sequentially, so instead of having to type each of those commands manually and wait for each to run, we can type one keyword, have terminal open for us, and let it run in the background while we continue working.

Let’s get started

1. Create a new Workflow.

Open Alfred Preferences, and navigate to the Workflows screen. In the lower left of the screen click the plus button to create a new Workflow. To save time, go to Templates > Essentials > Keyword to Terminal Command, and select that template. Give a name and description to your workflow, and add an icon if you want.

Setting up a template Workflow
Starting with a template for our Workflow
Adding details to the Workflow
Setting the details of our Workflow

2. Set the options and commands for your Workflow.

The two nodes of the workflow
The two nodes of our Workflow

When you create the Workflow you’ll have two nodes to work with: the keyword, and the terminal command. Double click on the keyword box to pull up the options for the keyword. We’re going to set brew as our keyword, and change to no argument since we aren’t adding any other commands. If we wanted to we could say setup an argument to update brew, cask, or both, but I just do both by default. I add a title and icon to display when I run the command and click save.

Setting a keyword for the Workflow
Setting the keyword options for our Workflow

Next, double click on the terminal command node. This is where we’re going to put the commands that are going to run after the terminal is opened. The below commands are what I have setup for my Workflow.

brew update
brew upgrade
brew cask upgrade
brew cleanup
brew cask cleanup
brew prune
brew doctor
brew cask doctor

The above updates Homebrew and Cask, then upgrades software that is currently installed and out of date for both. Next we use cleanup to uninstall older versions of the apps that have been updated. Prune will cleanup any outdated symlinks, and doctor will display any notes for potential problems that we can review.

Add terminal commands to the Workflow
Adding terminal commands to our Workflow

Let’s save this series of commands and give it a go!

3. Try running the command.

To use this command we need to type our keyword into the Alfred menu. Use whatever hotkeys that you have set to open Alfred (the default is option+space). When you start typing the brew keyword you’ll see the workflow appear as an option. Click enter when it’s selected to run the command.

Running our Workflow with a keyword
Typing our keyword pulls up our Workflow

If everything is setup properly your terminal application should open and paste in the series of commands. Since each is on a separate line they will run sequentially. You can see the commands as they run and any output they have. Since I ran this command shortly before taking screenshots for this tutorial everything is already up to date for me except for a bit of cleanup.

Commands running in our Workflow
Running the Workflow opens terminal and runs our commands

Awesome! This saves a bunch of time!

This Workflow saves me a bunch of time by updating applications in the background without having to wait for me to open them and have each application run their own update check. Since I’m opening an app when I want to use it the need to update can interrupt my workflow.

The benefits of this system include:

  • All applications stay up to date with new features and bug fixes
  • I don’t have to wait until I want to use an app to update
  • I won’t click ignore on an update and forget to do it later
  • I can make sure that my computer stays clean with outdated versions of applications getting removed for me
  • I don’t have to remember all of the commands to run, what order to run them in, or have to wait for each one to run before typing the next one

If you use Homebrew already, I’d suggest setting something like this up to make it easier to manage. It only took me a few minutes to setup, takes a second to run whenever I have time to update (generally every morning for me), and provides the kind of background benefits that save a bunch of headaches over the long term.