Skip to content

Commit 1ea1f40

Browse files
committed
new layout
0 parents  commit 1ea1f40

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1665
-0
lines changed

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "themes/typo"]
2+
path = themes/typo
3+
url = https://github.com/tomfran/typo.git

.hugo_build.lock

Whitespace-only changes.

archetypes/default.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
+++
2+
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
3+
date = {{ .Date }}
4+
draft = true
5+
+++

assets/css/custom.css

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
:root {
2+
--main-width: 1024px; /* overrides default of 780px */
3+
}
4+
5+
.header-title {
6+
position: relative;
7+
padding-left: 56px;
8+
}
9+
10+
.header-title::before {
11+
content:"";
12+
position:absolute;
13+
border-radius: .25em;
14+
background-image: url("/images/headshot.jpg");
15+
background-position: center;
16+
background-size: contain;
17+
background-repeat: no-repeat;
18+
background-color: black;
19+
height: 48px;
20+
width: 48px;
21+
top: calc(50% - 24px);
22+
left: 0;
23+
}
24+
25+
.intro a,
26+
.small > a {
27+
color: rgb(21, 128, 61);
28+
}
29+
30+
.line-title > a,
31+
.single-content a,
32+
.single-pagination-text > a,
33+
.pagination-control > a {
34+
/* color: rgb(37, 99, 235); */
35+
color: rgb(21, 128, 61);
36+
}
37+
.line-title > a {
38+
font-weight: bold;
39+
}
40+
41+
p > code,
42+
li > code {
43+
white-space: nowrap;
44+
border-radius: .375rem;
45+
background-color: rgb(229, 231, 235);
46+
padding: .4rem;
47+
font-size: .875rem;
48+
line-height: 1.25rem;
49+
}

bin/publish

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
#!/bin/sh
3+
4+
if [ "`git status -s`" ]
5+
then
6+
echo "The working directory is dirty. Please commit any pending changes."
7+
exit 1;
8+
fi
9+
10+
echo "Deleting old publication"
11+
rm -rf public
12+
mkdir public
13+
git worktree prune
14+
rm -rf .git/worktrees/public/
15+
16+
echo "Checking out gh-pages branch into public"
17+
git worktree add -B gh-pages public origin/gh-pages
18+
19+
echo "Removing existing files"
20+
rm -rf public/*
21+
22+
echo "Generating site"
23+
hugo
24+
25+
echo "Updating gh-pages branch"
26+
cd public && git add --all && git commit -m "Publishing to gh-pages (bin/publish)"
27+
28+
echo "Pushing to GitHub"
29+
git push --all

content/about.md

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
hideBackToTop: true
3+
---
4+
# Work
5+
6+
### Mar '23 - Present
7+
***[Tremendous](https://tremendous.com), Senior Software Engineer***
8+
9+
Businesses use Tremendous to send one-off payments to people around the world–for completing surveys, participating in user research calls, doing take-home projects, reporting bugs, booking demos, etc.
10+
11+
At Tremendous, I work on our Platform team to ensure our product is stable, fast and available to customers,
12+
while also supporting our engineering teams by improving our infrastructure and development experience so
13+
they can do their best work.
14+
15+
### Nov '20 to July '22
16+
***[Remote](https://remote.com), Senior Software Engineer***
17+
18+
I've helped Remote rapid growth through working on new features from different product areas,
19+
recruiting and onboarding new engineers and advocating for developer experience and platform
20+
stability as we expand into multiple countries and business verticals.
21+
22+
I worked on product areas like in app and email notification foundations, built support for 2FA authentication for all end users and rolled out SSO capabilities for customers and internal users
23+
use their own identity providers on the platform.
24+
25+
### Mar '20 to Oct '20
26+
***[Podium](https://podium.com), Senior Software Engineer***
27+
28+
At Podium I'm part of the Reviews team that is responsible for the maintenance of
29+
the backend services that powers our Reviews product.
30+
31+
### '17 to '19
32+
***[Magnetis](https://magnetis.com.br/), Senior Software Engineer and Team Leader***
33+
34+
As a Software Engineer, I've helped to adopt [Elixir](https://elixir-lang.org) and [Phoenix](http://www.phoenixframework.org)
35+
for new systems, improve our Kubernetes clustering setup and level up the code
36+
review practices of the engineering team.
37+
38+
Later, as the Team Leader of the Platform team, I worked on projects improving
39+
the integration between our product and [Easynvest](https://easynvest.com.br),
40+
while laying ground work of our own investment broker system. The team went from
41+
2 full time engineers to 8 people working on Elixir and Kubernetes to put the
42+
new services online and Ruby to integrate with the existing user facing application.
43+
44+
### '12 to '17
45+
***[Plataformatec](https://plataformatec.com.br), Software Developer***
46+
47+
At Plataformatec I worked on consulting projects involving greenfield development
48+
of new Ruby on Rails systems and maintenance on apps requiring new features,
49+
performance work and version upgrades. As the company grew over the years, I've
50+
participated on planning and execution of our recruiting expansion and the mentoring
51+
of new hires on Ruby, JavaScript and Git.
52+
53+
I was involved on the maintenance and ownership of the company open source libraries,
54+
[Devise](https://github.com/heartcombo/devise) and [Simple Form](https://github.com/heartcombo/simple_form),
55+
and also had the opportunity of creating new projects like the [Faraday HTTP Cache](https://github.com/sourcelevel/faraday-http-cache) gem.
56+
57+
I've bootstraped an internal tool called Ebert that was spun into its own product,
58+
[SourceLevel](https://sourcelevel.io), working on development, infrastructure
59+
customer support for the product by myself for almost an year.
60+
61+
# Publications
62+
### July 31, 2012 - [HTML5 e CSS3: Domine a Web do Futuro](https://https://www.casadocodigo.com.br/products/livro-html-css)
63+
64+
The book is an introduction to HTML and CSS syntax along with common patterns to
65+
design UI elements like button groups, forms and media elements, using pseudo
66+
selectors to draw icons and avoiding code pitfalls that newcomers usually stumble
67+
upon.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
date: "2012-06-27"
3+
description: "Old trick with the Action Pack `content_for` helper"
4+
title: Flushing content blocks with Rails 4
5+
---
6+
7+
Besides the big and shiny features that Rails 4 holds, there's a lot of small improvements on several other sections of the Rails framework - helpers, core extensions, app configurations and more - that might not even hit the Changelogs but will somehow make our lifes easier in the future. One of these hidden gems that I've found recently is an improvement on the `content_for` helper to flush and replace previous chunks of HTML with new ones.
8+
9+
### The `content_for` that we are used to
10+
11+
The `content_for` method is an old friend of every Rails developer, and it's a pretty simple and flexible helper. You can store a chunk of HTML from a String or a block, and grab it somewhere else in your views or `yield` it directly into your templates. It's a pretty handy trick to move data from your views into your layouts, like page titles, custom meta tags or specific `script` tags that your page needs to include.
12+
13+
```erb
14+
# On your 'application.html.erb' layout, inside the '<head>' tag.
15+
<%= yield :metatags %>
16+
17+
# Then, into a specific view
18+
<% content_for :metatags do %>
19+
<meta property="og:image" content="http://example.com/image.jpg" />
20+
<% end %>
21+
```
22+
23+
Multiple calls of the `content_for` helper using the same identifier will concatenate them and output them together when you read it back on your views, as:
24+
25+
```erb
26+
<% content_for :example, "This will be rendered" %>
27+
<% content_for :example do %>
28+
<h1>This will be rendered too!</h1>
29+
<% end %>
30+
```
31+
32+
On some scenarios this behavior might not be desired, and with Rails 4 you can flush out the stored pieces of an identifier and replace it instead of adding more content to it: using the `flush: true` option. The [first implementation](https://github.com/rails/rails/pull/4226) used an extra `true` argument, but [we changed](https://github.com/rails/rails/pull/7150) to use a Hash instead, so the `flush` key can express better the behavior we're expecting.
33+
34+
```erb
35+
<% content_for :example, "This will be rendered" %>
36+
<% content_for :example, flush: true do %>
37+
<h1>But this will override everything on the ':example' block.</h1>
38+
<% end %>
39+
```
40+
41+
### The gallery situation
42+
43+
I've stumbled upon this on a recent project, where we had a somewhat classic scenario: a partial named `_gallery`, responsible for rendering the piece of HTML to display a gallery of images that also supplies a `content_for` block with a `script` tag to include the required libraries to put the gallery to work.
44+
45+
```erb
46+
<section class="gallery">
47+
<!-- a truckload of HTML tags -->
48+
</section>
49+
<% content_for :scripts, javascript_include_tag('gallery') %>
50+
```
51+
52+
It works like a charm. But with an updated requirement we had the case where multiple galleries could be present on the same page, rendering the `_gallery` partial several times. The required HTML would be present, but the `gallery.js` script would be included multiple times into the rendered page. Instead of working this out using instance variables to check that the partial was rendered at least once, we could let Rails do all the hard work for us, using the `flush` option when including the `gallery.js` script.
53+
54+
```erb
55+
<section class="gallery">
56+
<!-- a truckload of HTML tags -->
57+
</section>
58+
<% # We can render this partial several times and this script will be included just once %>
59+
<% content_for :scripts, javascript_include_tag('gallery'), flush: true %>
60+
```
61+
62+
### Back to the present: Rails 3.2
63+
64+
Well, while this seems to be a perfect solution to my problem, this feature isn't available on Rails 3.2 or on the `3-2-stable` branch - it's only available on the `master` branch that will be released with Rails 4. But, backporting this feature into a 3.x application is pretty simple, using a helper of your own.
65+
66+
```ruby
67+
def single_content_for(name, content = nil, &block)
68+
@view_flow.set(name, ActiveSupport::SafeBuffer.new)
69+
content_for(name, content, &block)
70+
end
71+
```
72+
73+
After some source diving into the ActionPack source code we're done - it just needs to replace any present content with a brand new `SafeBuffer` instance before storing the piece of HTML.
74+
75+
What do you think about this little addition to Rails 4? Can you think of a similar problem that could be solved with this instead of a custom hack?
76+
77+
> This post was originally published at
78+
> http://blog.plataformatec.com.br/2012/07/flushing-content-blocks-with-rails-4/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
---
2+
date: "2013-02-25"
3+
description: "Thoughts on dealing with code dependencies"
4+
title: Extending and customizing 3rd party code
5+
---
6+
7+
We have a gem available for every kind of feature or scenario we might face in our applications and that may help us focus our development time on things that are more important to our applications. But, every now and then, these packaged solutions aren't exactly what we need, and some sort of customization needs to be done on top of that - a different authentication strategy, new ways to query for data and several different things that our business rules might require.
8+
9+
So, we jump on top of the existing code to bend it to our needs but sometimes things can go south and we end up in a mess of hacks, unstable code and bad experiences. After some time, we started to develop a few guidelines of our own to avoid the mistakes of the past and look forward to write better applications. These are some of the ideas that I follow to avoid complications when dealing with 3rd party code:
10+
11+
## Don't fear the source
12+
13+
The source code and its documentation are your best friends on this. Having a local clone of a dependency repository lets you `ack`/`grep` it inside out to see how the code is structured to identify the good and bad parts to mess with. You can test your changes against its test suite to see if you might break something or not and that's already one step closer to contribute back to the project.
14+
15+
## Respect method visibility
16+
17+
Method visibility is an important tool to ensure that you aren't messing with the wrong pieces of code from a gem. Public and protected methods are meant to be overriden when necessary, but private ones aren't. They are usually doing the work that you don't want the trouble to do it yourself, and maybe that's why you are using the dependency after all.
18+
19+
For example, `ActiveRecord` adds a lot of private methods to handle the persistence of your models that you shouldn't mess with, but the public API is stable enough for you to use it for whatever you need.
20+
21+
## Monkey patch at your own peril
22+
23+
Ruby lets you monkey patch everything but that doesn't mean you should. While this might make a lot of sense for libraries that extend the Ruby stdlib (like `ActiveSupport`), monkey patching someone else constant might bite you back later. Overusing monkey patches might be a serious block when updating your application to newer versions of a big dependency of your project (for example, Rails).
24+
25+
When you monkey patch, you are usually messing with a very internal piece of a component that might be far from it's public API. So, you can't predict how that class or module will behave when a new version is released or what other parts of the code are using that internal API. Classes get renamed and refactored everyday, and it's hard to ensure your patches will keep up with those changes.
26+
27+
## Composition (and inheritance) as extension mechanisms
28+
29+
A lot of gems provide a series of configuration options that you can drop in an initializer and get the behavior you need, or maybe a specific configuration might be missing. You might feel the urge to send a pull request adding a new configuration to the project, but hold that idea for a second. Can't you do it by overriding a method or using a custom component of your own?
30+
31+
Inheritance and composition can be a better choice for a lot of customizations since they are easier to test and to isolate the effects on your application. While a configuration setting is global and affects your entire application, an isolated change will have a much smaller impact on your code.
32+
33+
Take for instance the `to_param` and `to_partial_path` methods from `ActiveModel`. You can override them in your models to change how your views will interact with them, and that goes in a per model basis, since you usually won't do that for your entire application. Imagine if you need to change a configuration instead overriding a method: You would have to do something weird like this:
34+
35+
```ruby
36+
# A regular configuration inside an initializer
37+
config.action_view.parameterize_method = :slug
38+
39+
# But what if I need a per model configuration? Well, use a Hash!
40+
config.action_view.parameterize_methods = { post: :slug, user: :id }
41+
```
42+
43+
While just overriding the `to_param` method in your `Post` model is a lot easier than this.
44+
45+
Another example of composition I came across recently was the `tokenizer` option on the `LengthValidator`. Given that you have a description column in your database that accepts HTML tags like `strong` and `em`, and you want to validate the length of the text, but not the HTML, you can provide an object that responds to `call` and strips away the HTML from the string, so the validation will be executed against the raw text instead of the whole HTML of it.
46+
47+
```ruby
48+
class MyOwnTokenizer
49+
def call(text)
50+
# do whatever you need with `text`.
51+
end
52+
end
53+
54+
# on your model…
55+
validates :description, :length { tokenizer: MyOwnTokenizer.new }
56+
```
57+
58+
## Your code, your problem
59+
60+
Remember to test your changes. Once you change a default behavior or tweak some specific configuration that might have side effects on other parts of your application, your test coverage will help ensure that this behavior won't break once you update a dependency on your project.
61+
62+
You usually shouldn't worry about testing library defaults (like testing the validations on your models that you configured with `ActiveModel` validation methods), but once you customize something, that piece of code is your responsibility.
63+
64+
So, if you added your own `tokenizer` use along with a `LengthValidator` on your application, be sure to write at least an unit test for it to ensure that it works as expected.
65+
66+
## Contribute back
67+
68+
Sometimes you might notice (or need) an improvement to a library that won't change anything on its public API but will make your life easier when extending it. You can't expect that the maintainers will discover every spot that can or might be overriden, so it's important to bring your experience on using it to the table and help others. You can extract a specific behavior to an isolated component, or improve some internal logic so it might be easier to extend it in the future. There's nothing but love for such kind of contribution.
69+
70+
A while ago [this pull request](https://github.com/rails/rails/pull/3636) changed how Rails added the associations proxies to a model that is using `belongs_to` and friends. While it didn't changes a single bit about the public API for the associations, it changed how you can extend them to add your specific behavior.
71+
72+
## Wrapping Up
73+
74+
These steps might not fit everyone’s workflow, but we need to keep in mind that dealing with external dependencies requires a thoughtful approach to avoid the results being harmful to your projects.
75+
76+
And what about you, my fellow developer: how do you approach the need for something more than a gem's default behavior? Jump on our comments thread to discuss more about it.
77+
78+
> This post was originally published at
79+
> http://blog.plataformatec.com.br/2013/02/extending-customizing-3rd-party-code/

0 commit comments

Comments
 (0)