Skip to content

Commit

Permalink
Migrate old "post" content from www.danott.co
Browse files Browse the repository at this point in the history
1. Move the date out of the File.basename and into a data comment
2. Make sure to retain any previously established leading-line data
3. Make sure the paths match my new "year/slug" format
4. Make images for the one post with images work, which never even
   worked on the previous site
5. Limit RSS to the newest posts.
  • Loading branch information
danott committed Jan 14, 2024
1 parent 70bf3f9 commit bf5e172
Show file tree
Hide file tree
Showing 100 changed files with 5,431 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
_site
_scratch
test/_site
20 changes: 20 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,24 @@ task :serve do
server.start
end

desc "Temporary task to convert old posts"
task :convert_old_posts do
old_posts =
Dir
.glob("_scratch/old_posts/*.md")
.map { |path| Temp::PostMigrator.new(path) }

if old_posts.size != old_posts.map(&:next_path).uniq.size
fail "Naming collision!"
end

old_posts.each do |p|
puts "*" * 20
puts "prev: #{p.path}"
puts "next: #{p.next_path}"
puts p.next_content
# p.write
end
end

task default: :build
6 changes: 5 additions & 1 deletion lib/rss_target.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ def write
end

def items
Build.data.posts.map { |p| PostDataRssItem.new(p) }
Build
.data
.posts
.select { |p| p.fetch("date") > Date.new(2023, 12, 1) }
.map { |p| PostDataRssItem.new(p) }
end

def render
Expand Down
2 changes: 1 addition & 1 deletion lib/source.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def self.for(path)
case extname
when ".md"
MarkdownSource.new(path: path, content: MagicFile.read(path))
when ".css", ".jpg", ".js"
when ".css", ".jpg", ".js", ".png"
FileCopier.new(path)
when ".yml"
DataSet.new(path)
Expand Down
41 changes: 41 additions & 0 deletions lib/temp/post_migrator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module Temp
class PostMigrator
attr_reader :path
attr_reader :content

def initialize(path)
@path = path
@content = File.read(path)
end

def next_path
"site/" +
path.delete_prefix("_scratch/old_posts/").sub(
/\d\d\d\d-\d\d-\d\d-/,
date_string.first(4) + "/"
)
end

def date_string
path.delete_prefix("_scratch/old_posts/").first(10)
end

def data_line
wip = content.start_with?(/#[a-z]/) ? content.lines.first : ""
wip = [date_string, wip].join(" ").strip
"<!--data #{wip} -->\n\n"
end

def next_content
lines = content.lines
lines = lines.drop(2) if content.start_with?(/#[a-z]/)
lines = [data_line] + lines
lines.join.strip
end

def write
FileUtils.mkdir_p(File.dirname(next_path))
File.write(next_path, next_content)
end
end
end
39 changes: 39 additions & 0 deletions site/2011/pick-your-pain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!--data 2011-07-16 -->

# Pick Your Pain

There is a principle that has been fermenting in the sweet juices of my mind grapes over the past few months. There’s a place that Jesus has been leading me to that holds some previously unknown truths. Not new truths. Just unknown to me in my infancy and ignorance in the faith.

The truth I’m learning is pain. Pain exists. We think we can avoid it. We think with enough modern comforts or prescriptive remedies we can eliminate it. This simply isn’t true. Pain, in one form or another, will be a part of our lives until Jesus returns and makes all things new.

Knowing that pain will always be present, the question is: what is the source of your pain? Some people have debilitating ailments that cannot be controlled. That’s not what I’m talking about. I’m talking about the self-selected pain we will experience in our lives.

A couple of examples from scripture:

> **2 Timothy 1:8**\
> do not be ashamed of the testimony about our Lord or of me his prisoner. Rather, join with me in suffering for the gospel, by the power of God.
Paul is telling Timothy there are two options in regards to the gospel. Shame because of it, or suffering on behalf of it. That’s it.

Shame is painful - the resulting isolation of not being known is the very thing that God has said is not good. Most of us can attest from some experience in our life that loneliness is painful. Shame from caring more about man’s opinion than God’s is even worse. The seared conscious won’t let our souls rest. It’s not physical pain, but the relational disconnect and ensuing sadness is very real, and in my experience, painful.

Suffering is painful - it needs no clarification. Whether it’s enduring physical beatings for Jesus’ name, or being on the receiving end of family members’ insults - the pain is very real to varying degrees.

There is no third option. There is either the pain of shame, or the pain of suffering for His name.

> **John 15:1-2**\
> I am the true vine, and my Father is the gardener. He cuts off every branch in me that bears no fruit, while every branch that does bear fruit he prunes so that it will be even more fruitful.
Jesus is telling the disciples that pain is coming. A branch being removed receives a cut. A branch being pruned receives a cut. In this regard, fruitfulness or fruitlessness is irrelevant - either way a cut is coming.

What is relevant is what the desired outcome of that painful cut will be. Will it be relational disconnect from God? Or will it be increased intimacy with God as he disciplines you and refines you as any loving father does? The bottom line - the pain of a cut simply cannot be avoided.

Shame or suffering? Those are the options. I’ll close with what Jesus had to say regarding the two options that lay before us.

> **Mark 8:38**\
> If anyone is ashamed of me and my words in this adulterous and sinful generation, the Son of Man will be ashamed of them when he comes in his Father's glory with the holy angels.
> **Matt 5:11-12**\
> Blessed are you when people insult you, persecute you and falsely say all kinds of evil against you because of me. Rejoice and be glad, because great is your reward in heaven, for in the same way they persecuted the prophets who were before you.
You can pick your pain. Choose wisely.
62 changes: 62 additions & 0 deletions site/2012/sharing-is-caring-about-code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<!--data 2012-01-20 -->

# Sharing is Caring About Code

Sharing buttons for Twitter, Facebook, Google+ and the like are becoming a frequent request when doing web work. It's a good ask most of the time &mdash; but often it comes at the cost of readable and/or maintainable code.

Things used to be worse. I recall the first time I tried to use a copy/pastable JavaScript snippet from Flickr, and it prevented my entire page from loading. That particular script was a blocking script, using JavaScript's `document.write()` profusely. If Flickr was down, my site was down.

Today's scripts are a lot smarter, They're placed at the bottom of a document, and dynamically insert new scripts into the document `head` to load them asynchronously. This means they don't block the rendering of your webpage, and your site will work independent of the other service(s).

That's an improvement, but I still don't feel good about the huge chunks of copy/pasted code. It can be particularly bad when inheriting a project where scripts were pasted haphazardly with little knowledge of what they're actually doing.

For the major three, I have an improvement that I cooked up using [Modernizr](http://modernizr.com)'s load function.

The old copy/pasted scripts:

```html
<!-- Twitter's copy/paste script -->
<script type="text/javascript" src="//platform.twitter.com/widgets.js"></script>

<!-- Google+'s copy/paste script -->
<script type="text/javascript">
;(function () {
var po = document.createElement("script")
po.type = "text/javascript"
po.async = true
po.src = "https://apis.google.com/js/plusone.js"
var s = document.getElementsByTagName("script")[0]
s.parentNode.insertBefore(po, s)
})()
</script>

<!-- Facebook's copy/paste script -->
<script>
;(function (d, s, id) {
var js,
fjs = d.getElementsByTagName(s)[0]
if (d.getElementById(id)) {
return
}
js = d.createElement(s)
js.id = id
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1"
fjs.parentNode.insertBefore(js, fjs)
})(document, "script", "facebook-jssdk")
</script>
```

Can be replaced with one finely crafted `Modernizr.load()` call:

```javascript
Modernizr.load([
"//platform.twitter.com/widgets.js",
"//apis.google.com/js/plusone.js",
{
test: document.getElementById("facebook-jssdk"),
nope: "//connect.facebook.net/en_US/all.js#xfbml=1",
},
])
```

20 lines of code replaced with 7. A nice refactor in my opinion. And if you're not the Modernizn' type, you can always use the smaller underlying library, [yepnope.js](http://yepnopejs.com/).
43 changes: 43 additions & 0 deletions site/2013/deploying-ember-on-rails-to-heroku.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!--data 2013-06-20 -->

# Deploying Ember On Rails To Heroku

Working with the [ember-rails][] gem and [Heroku][] require some application settings that aren't immediately intuative.

For ember-rails, you need to tell Rails which variant of ember to use. This is done in your application config.

```ruby
# config/application.rb

Sample::Application.configure do
# ember-rails requires this setting in the Rails application.
config.ember.variant = :production
end
```

Heroku doesn't play nice with the default Rails asset pipeline settings. You'll need to configure your Rails app to serve up the assets in production.

```ruby
# config/environments/production.rb

Sample::Application.configure do
# Defaults to false. Heroku needs to serve the assets,
# as there is no file system in Heroku.
config.serve_static_assets = true
end
```

Also, in `config/environments/development.rb` you can set ember to use the development variant.

```ruby
# config/environments/development.rb

Sample::Application.configure do
config.ember.variant = :development
end
```

And with that, deployment is as easy as `git push heroku master`.

[ember-rails]: https://github.com/emberjs/ember-rails
[heroku]: https://www.heroku.com/
58 changes: 58 additions & 0 deletions site/2013/eliminating-nested-blocks-in-ruby.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!--data 2013-09-13 -->

# Eliminating nested blocks while looping through Arrays in Ruby

Today I learned a new trick in Ruby that is useful for minimizing nested blocks.

Let's say you are trying to create a list of mutant animals from two arrays. One
array contains animals. The other array contains modifiers on those animals.
Here's how you might generate them using two `Enumberable#collect` calls:

```ruby
animals = ["Platypus", "Tiger", "Squirrel"]
modifiers = ["Duck-billed", "Bengal", "Flying"]

animals.collect do |animal|
modifiers.collect do |modifier|
"#{modifier} #{animal}"
end
end.flatten
# => ["Duck-billed Platypus",
# "Bengal Platypus",
# "Flying Platypus",
# "Duck-billed Tiger",
# "Bengal Tiger",
# "Flying Tiger",
# "Duck-billed Squirrel",
# "Bengal Squirrel",
# "Flying Squirrel"]
```

That works just fine, but nested blocks can quickly become hard to follow. Also, that trailing `.flatten` can be easily missed when scanning the code.
This is where [`Array#product`](http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-product) comes into play. `Array#product` gives every possible
combination of elements from all arrays. With this, your mutant-animal generator
can be re-written:

```ruby
animals = ["Platypus", "Tiger", "Squirrel"]
modifiers = ["Duck-billed", "Bengal", "Flying"]

animals.product(modifiers).collect do |animal, modifier|
"#{modifier} #{animal}"
end
# => ["Duck-billed Platypus",
# "Bengal Platypus",
# "Flying Platypus",
# "Duck-billed Tiger",
# "Bengal Tiger",
# "Flying Tiger",
# "Duck-billed Squirrel",
# "Bengal Squirrel",
# "Flying Squirrel"]
```

The nested block is eliminated, and that easy-to-miss trailing `.flatten` is gone. Hooray.

I still don't quite understand how `collect` knows to look at array elements when the passed block takes two arguments instead of one. Can't find anything that alludes to this in the [docs](http://www.ruby-doc.org/core-1.9.3/Array.html).

It's [some kind of magic](http://rd.io/x/QVtm-TcYPEk/).
28 changes: 28 additions & 0 deletions site/2013/instant-savings-in-vim.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!--data 2013-05-23 -->

# Instant Savings In Vim

I save text files hundreds of times every day. I hope to have a long career developing software, so anything I do hundreds of times a day needs to be as efficient as possible.

To speed up this oft-used task I added this little bit to my `.vimrc` today.

```vim
" Save all the things.
nmap <Leader>s :w<CR>
imap <Leader>s <ESC>:w<CR>
```

So what do these mappings do? Whether I'm in insert mode or normal mode, the key sequence `,s` saves the file.

First thing to note, is that I have my [leader key][] set to comma. So when looking at [my .vimrc file][], `<Leader>` can always be interpreted as a comma.

`nmap` defines a mapping in normal mode. `<Leader>s` is the _left hand side_ of this mapping. It's what triggers the mapping. `:w<CR>` is the _right hand side_ of the mapping. This is what is executed when the mapping is triggered.

So when I type `,s` vim executes `:w<CR>`, saving the file.

`imap` defines a mapping in insert mode. When in insert mode, we need to escape to normal mode before writing the file. Hence, the prepending `<ESC>` on the right hand side of the mapping.

To see more that you can do with mapping keys, Vim's `:help map` is a great place to start reading.

[leader key]: http://vimdoc.sourceforge.net/htmldoc/map.html#mapleader
[my .vimrc file]: https://github.com/danott/dotfiles/blob/master/vim/vimrc.symlink

0 comments on commit bf5e172

Please sign in to comment.