u/StartAutomating

Static Sites are Simple (with PowerShell)

I've been doing WebDev since the dawn of the internet, and I've been doing PowerShell for almost 20 years now. I want to share with you something that I've realized over the years:

Static Sites Are Simple

Static Websites are just a bunch of files. You can make static sites with anything that can make files.

Static Sites are Simple.

Let me show you how:

Static Sites with PowerShell

PowerShell is pretty great at making files.

Most static site files are text: .css, .js.,.html,.svg are all readable and writeable text.

Want to write a website in PowerShell?

Just write a series of strings.

I like this naming convention:

# *.html.ps1 > *.html

We can build a site like this:

# Get all *.html.ps1 files beneath the current directory
Get-ChildItem -Filter *.html.ps1 -Recurse -File | 
   Foreach-Object {
      # Run the file 
      & $_ > $(
          # and redirect the output to the renamed `.html`
          $_.Fullname -replace '\.html\.ps1$','.html'
      )
   }

If we wanted to provide consistent formatting for all *.html.ps1 files, we can do so with a layout.

Just write a freeform script for layout.

function layout {
   
   # Output any common layout.

   # We are outputting a series of strings.

   # When we redirect output, each string will go on it's own line.
   
   # We can use any simple PowerShell string techniques to change content
   
   '<html>' # * Single quoted string (no substitutions)
   "<head>" # * Double quoted string (`$var` and `$(expression)` supported) 
       # * Multiline double quoted strings (with subexpressions)
       "<title>$(
        if ($title) { 
            [Web.HttpUtility]::HTMLEncode($title)
        } else { 'My Website' }
        )
        </title>"
        # * Conditionals output, using if
        if ($Header) {
             "$Header" # * Stringification of variables
        }
        # * Singly quoted here-strings (mulit-line no substitution)
        @'
<style>
body {max-width: 100vw;height: 100vh;}
</style>
'@
        # * Doubly-quoted here-strings 
        @"
$(
# * Subexpressions with conditionals and iteration
if ($css) {$css})
"@

   "</head>"
   "<body>"
    # * `$input` allows us fast, one-time enumeration of a pipeline
    # * `@()` allows us to collect that into a new list
    $allInput = @($input)
    
    # * String operators (`-join`, `-like`, `-match`,`-replace`, `-split`).
    $allInput -join [Environment]::Newline
    "</body></html>"
}

Now, we can build it with:

# Get all *.html.ps1 files beneath the current directory
Get-ChildItem -Filter *.html.ps1 -Recurse -File | 
   Foreach-Object {
      # Run the file, pipe to our layout 
      & $_ | layout > $(
          # and redirect the output to the renamed `.html`
          $_.Fullname -replace '\.html\.ps1$','.html'
      )
   }

If we want to handle multiple file types, a switch statement does a nice job. We can build the site any way we want. This is just one example of how.

Most templating languages can't talk to too much. By using PowerShell to make static sites, we open up a wide world of possibilities with a small amount of understanding.

Static Sites Are Simple

They're mainly just strings.

PowerShell plays with strings quite well 😉.

Hope this Helps / AMA

reddit.com
u/StartAutomating — 3 days ago

Using git in PowerShell

git is great!

It's a wonderful way to store source code.

The git application is also great and powerful. Like ffmpeg, it's also somewhat infamous for how much the command can do and how tricky it can be to understand.

When we try to use git in PowerShell, we get one more annoying problem: It outputs text, not objects. This is the problem I set out to solve about four years ago with ugit.

ugit updates git for PowerShell and makes it so we can return rich extensible objects rather than raw text.

We can install ugit from the PowerShell Gallery

Install-Module ugit -Scope CurrentUser -Force

Import-Module ugit

Once imported, ugit sets git as an alias to Use-Git, which intercepts any calls to git (the application) and sends them to ugit (the function).

You can use ugit like you would use git (and you can pipe it's output)

One of my favorite examples of this is:

git log |
    Group-Object { $_.CommitDate.DayOfWeek } |
    Sort-Object Count -Descending

This works because git log output is automatically parsed into objects, and therefore our Commit Date is actually a [DateTime], and we can use Group-Object to group on it's .DayOfWeek property.

All sorts of git can be turned into PowerShell objects.

For example, make some changes to a repository and then run

git diff 

Then pipe it to Get-Member

git diff | get-member

There is a ridiculous amount of git we can make better with ugit. This module has been growing for four years now and has a lot of git tricks in it.

The most recent hotness is git functions. They allow you to define PowerShell functions ugit will run.

function git.hello.world {
   param($message = 'Hello World') $Message
}
git hello world 'ugit is cool!'

I literally use this module every day. It's one of only two modules I load in my profile. It has completely changed the ways I work with git. I hope it does the same for you 🤞.

Please try this git and let me know what you think.

u/StartAutomating — 3 days ago

Working with FFmpeg in PowerShell

One thing I really love to do is make complicated functionality a few notches easier by exposing it in PowerShell.

I absolutely love ffmpeg. It's a very powerful app for manipulating media. It's also famously dense. It has hundreds of filters, thousands of parameters, and generally obtuse and deeply technical help.

So, a long while back, I started whittling away on this problem. I made this module called RoughDraft to manipulate media, and I figured out a good enough mechanism to slowly build out support for filter after filter after filter.

It lets you play files with Show-Media, convert files with Convert-Media, and do almost any edit under the sun with Edit-Media.

IMO, it's a really fun module. Please check it out and let me know what you think.

reddit.com
u/StartAutomating — 8 days ago