I started to use Atom with the Markdown-Writer plug-in for writing my Jekyll blog posts. I had previously been using MarkdownPad2 but found I was missing some Jekyll specific features:
Generating Posts with Jekyll Front Matter auto populated
Managing Categories
Managing Tags
I still use MarkdownPad2 as a general purpose markdown editor but for Jekyll blogging the Markdown-Writer plug-in is a big improvement in my work flow.
To set up the front matter you need to open the atom configuration (ctrl+shift+p type config) and add in:
'markdown-writer':
/*may have other markdown-writer configuration here */
'frontmatter': '---\nlayout: post\ntitle: "<title>"\ndate: "<date>"\ncategories:\n---'
Tags and Categories
To set up category and tag lookups you have to add a few files to your Jekyll project. These files will create JSON files with all the tags and categories from your blog which will be referenced by the plug-in.
Drop the following scripts into the same place you store your css files. When the site is compiled the categories and tags will be generated.
After you republish you can open the markdown-writer configuration page (ctrl-, and search for markdown-writer) and point the setting URL to Categories/Tags JSON definition to the Url of the respective JSON files. For example:
www.yoursite.com/content/categories.json
The Markdown-Writer Workflow
Using Atom and Markdown Writer greatly improved my workflow. Before I would fumble while manually creating a file with the correct naming convention, manually create the front matter, guess at the correct naming for my categories/tags, and then finally start writing.
My new workflow looks like this:
Open Atom
Ctrl-shift-p type new post to create new markdown writer post
Ctrl-shift-p type categories to add categories from a list directly from my blog.
Start writing.
Hope that helps improve your workflow. Happy Blogging!
What do you think this piece of code would do? Remove the claim that is specified? It might. It might not. If you start to dig a little deeper you might be surprised…
Reasonable Assumptions
I read a great article by Scott Wlaschin about language design choices which make the language easy to reason about. He leaves us with a simple definition:
“reasoning about the code” means that you can draw conclusions using only the information that you have right in front of you, rather than having to delve into other parts of the codebase.
If we look at the UserManager.RemoveClaimAsync() call above, we might reason that the code should simply remove the claim. In most cases it does but not always and leaves us wondering we couldn’t reason about such a simple piece of code and delving deeper into the codebase.
The problem
Everything was working fine, until one day I ran the UserManager.RemoveClaimAsync() function and found the claim was not being removed from the database.
I was immediately confused by result and began looking everywhere for the error. Not finding any answers, I finally opened SQL Server Profiler to see the database calls that were being made. I was in for a surprise.
I found that the SQL DELETE statement for removing the claim was never being called but that the one call to the UserManager was makingfour database calls.
It was then that I realized the call to UserManager.RemoveClaimAsync() was actually failing and I was not checking the result that is returned. I should have been doing the following:
IdentityResultresult=awaitUserManager.RemoveClaimAsync(userId,claimToDelete);if(!result.Succeeded){foreach(varerrorinresult.Errors){// do something with the errorsTrace.WriteLine(error);}}
If I had handled the error correctly I would have immediately found the problem (someone updated a user to have the same email address as another user outside the application). But what about the four database calls that resulted in the failed removal of the claim?
Unintended Consequences
If you have the default MVC 5 template configuration you will find the following code in the IdentityConfig.cs file:
publicstaticApplicationUserManagerCreate(IdentityFactoryOptions<ApplicationUserManager>options,IOwinContextcontext){varmanager=newApplicationUserManager(newUserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));// Configure validation logic for usernamesmanager.UserValidator=newUserValidator<ApplicationUser>(manager){AllowOnlyAlphanumericUserNames=false,RequireUniqueEmail=true};// more configuration...}
The line RequireUniqueEmail = true looks innocuous but in reality is causing the error and failed claim deletion we uncovered above.
That single line tells the UserManager to validate the user on almost every call. So for our simple call to the UserManager we are actually validating the user then removing the claim.
In the case of a failure, the result is 4 database calls and a failed removal of the claims. When successful, the claim is removed but it results in 6 database calls including anUPDATE statement to the AspNetUsers table. Why an update statement to the AspNetUserstable when removing a claim? Your guess is as good as mine.
You can see all of the database calls by either by using SQL Server Profiler or adding a trace statement to your ApplicationDbContext. Be forewarned you might not like what you find:
publicclassApplicationDbContext:IdentityDbContext<ApplicationUser>{publicApplicationDbContext():base("DefaultConnection",throwIfV1Schema:false){// Log all the database calls when in Debug.this.Database.Log=(message)=>Debug.Write(message);}}
Conclusion
There is a lot more happening behind the scene with the UserManger than can be reasoned about at first glance. When making a simple call to delete a claim we find that there is user validation and user update calls being made.
The immediate lesson I learned was that I need to check the return result from all the calls of the UserManager. It adds a lot of noise to the code but can be factored out into a helper class.
This experience has started to make me ponder if a language should help a programmer by make sure they use the return result from a function. I will be paying attention to any times where I might have over looked the return result of a function. Any thoughts?
I must also call to question the efficiency of the UserManager. There is a lot of chatter happening with the database to do even the simplest database calls. For now, I think it is providing enough value by making it easy to generate email code, do user authentication, and generate second factor codes that I will have to deal with it.
It was from the forward by Alan J. Perlis that I found one of the best explanations of why I have always been enchanted by software:
The source of the exhilaration associated with computer programming is the continual unfolding within the mind and on the computer of mechanisms expressed as programs and the explosion of perception they generate. If art interprets our dreams, the computer executes them in the guise of programs!
I am excited to start my adventure with SICP and would love hear about your experiences with it. Please leave a comment below.
And for anyone out there that has started (or will be starting) their own SICP Adventure I created a Vargant script on github that will get you up and running quickly with a linux vm, MIT Scheme and Emacs.
Setting up Jekyll for Windows is painful. To set it up you need to follow a multiple step setup process and cross your fingers. Julian Thilo has done a great job outlining all the steps and pitfalls on his Run Jekyll on Windows site. This is how I initially setup Jekyll but the trouble with this process is it takes several steps and potentially requires a bit of debugging to figure out.
I recently switch development machines, which meant I needed to setup Jekyll again and didn’t want to repeat the error prone process. At the same time I happened to learn how use Vagrant at the user group I organize.
Make sure Vagrant and your favorite virtual machine are installed. I use Virtual Box and when setting up a new machine I already have these dependencies installed using Chocolately and BoxStarter.
Open command prompt to location of the vagrantfile in the new cloned repository and run vagrant up
Jekyll and all it’s dependencies are installed!
Existing Jekyll Projects
Copy the projects folder to the folder that contains the vagrantfile.
Login to the VM using vagrant ssh
New Jekyll Projects
Open a command prompt to location of the vagrantfile and run vagrant ssh
Once in the VM prompt cd /vagrant
Create a new site with jekyll new <sitename>
Start the Site
In the VM prompt cd /vagrant/<YourProjectFolder>
Start the Jekyll server jekyll serve --force_polling (force polling is required with vagrant because of share)
On your host machine you can open any browser and navigate to localhost:4000
Work on you project on your host machine and see updates as they happen on localhost:4000!
Conclusion
Jekyll is a fun blogging platform but the support for Windows is limited. There are ways to install Jekyll directly on the host machine but they are tedious and error prone. By leveraging Vagrant we can have a fast, repeatable Jekyll setup that is in sync with GitHub Pages environment.
It is the time of year when many reflect back on the previous year and take stock of their successes and failures. Reflection is an important skill that often gets over looked. Without reflection we always move onwards without ever taking the time to learn from the expereinces we have had.
2014 was the first year that I set goals at the beginning of the year and followed through with them. It has been a fun experience. I can attribute the successful experience to my mastermind group. Without their support I would have likely never gotten started or had the motivation to follow through.
Accomplishments
A few of the highlights (in no particular order) from the past year:
Augusta Polyglot Programming Group - I co-founded and organize the
group with my friend Floyd Hilton. It has turned out to be a huge success. We have met alot of amazing poeple and learned about some really interesting topics.
Lessons Learned
Community
Community is important. Whether it is small group of friends or a a larger group, community will help provide motivation and support for any activity you try to accomplish. If you are not a member of a local community, join one or start one, it will change your life.
Entrepenureship
There are many different types of entrepreneurs. I have struggled with my entrepreneurial spririt over the last year and half. It was while listening to a podcast this year, Startups for the Rest of Us, I realized that there are different motivations and options for feeding that spirit.
Diversity
Diverisity is important. It is easy to overlook ideas becuase they are different. The more diverse ideas you are presented with the better chance you have of finding the right one.
Consistency
Consistency is a rare trait because it is hard. But if you can stick with your idea/project/work then you will eventually have success. I saw this over the past few months with my blog going from zero readers the first few months to over 700 pages views this last month. If I had given up or stopped writing I would not have seen increase and would have called the blog expirement a failure. It was hard to put out a post a week… there were many late nights and early mornings.
Conculsion
2014 was a great year for me. When looking back there were some common themes and lessons that showed up time and time again. Learning from them has helped me plan to make the next year even better.