-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfeed.xml
667 lines (501 loc) · 49.4 KB
/
feed.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
<rss xmlns:a10="http://www.w3.org/2005/Atom" version="2.0"><channel><title>devuxer</title><link>http://www.devuxer.com/feed.xml</link><description>devuxer</description><item><guid isPermaLink="true">http://www.devuxer.com/2014/12/19/delimited-column-selection/</guid><link>http://www.devuxer.com/2014/12/19/delimited-column-selection/</link><author>[email protected]</author><category>Code Editing</category><category>User Experience</category><title>Delimited column selection</title><description><p>It recently occurred to me that column selection is nice, but it could be awesome.</p>
<p>Here is what I mean by column selection:</p>
<p><img src="http://www.devuxer.com/images/2014-12-19/regular-column-selection.png" alt="Regular column selection" /></p>
<p>In most GUI editors, you perform this type of selection by alt-dragging the mouse down and to the right.</p>
<p>If all you wanted to do was add <code>virtual</code> after each <code>public</code>, this would be very useful.</p>
<p>But what if you wanted to strip away <code>public</code> plus the data type? For this, you would want the selection to go word-by-word instead of character-by-character as you alt-drag the mouse to the right.</p>
<p>To illustrate this concept, I created an animated GIF. (In case your curious how, I used PowerPoint to create the slides, saved them as PNG, imported them as layers into Paint .NET, and saved out the image as an AGIF using the <a href="http://forums.getpaint.net/index.php?/topic/13454-animated-image-24-agif-apng/">Animated Image plugin</a>.)</p>
<p><img src="http://www.devuxer.com/images/2014-12-19/delimited-column-selection.gif" alt="Delimited column selection - animated" /></p>
<p>I see this feature being useful for any situation where you have a bunch of similar declarations and you want to strip away something from each line or insert something new between the same two words of each line.</p>
<p>While writing this post, I began to wonder if delimited column selection already exists. I was thinking <a href="http://www.sublimetext.com/">Sublime Text</a> might have it, but I wasn't able to find it during my brief test drive. The default Visual Studio editors don't seem to have anything beyond standard column selection, but I did come across the <a href="https://visualstudiogallery.msdn.microsoft.com/2beb9705-b568-45d1-8550-751e181e3aef">MultiEditing extension</a>, which
Scott Hanselman <a href="http://www.hanselman.com/blog/SimultaneousEditingForVisualStudioWithTheFreeMultiEditExtension.aspx">blogged about</a> in 2013. While it sounds quite useful (I think I'll install it), it wouldn't be quite as easy for the use cases I have in mind.</p>
<p>Anyway, if you'd like to see delimited column selection in Visual Studio, I just posted the idea to <a href="https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/6863802-make-code-editors-more-awesome-with-delimited-colu">Visual Studio User Voice</a>.</p>
</description><pubDate>Fri, 19 Dec 2014 08:00:00 Z</pubDate><a10:updated>2014-12-19T08:00:00Z</a10:updated><a10:content type="html"><p>It recently occurred to me that column selection is nice, but it could be awesome.</p>
<p>Here is what I mean by column selection:</p>
<p><img src="http://www.devuxer.com/images/2014-12-19/regular-column-selection.png" alt="Regular column selection" /></p>
<p>In most GUI editors, you perform this type of selection by alt-dragging the mouse down and to the right.</p>
<p>If all you wanted to do was add <code>virtual</code> after each <code>public</code>, this would be very useful.</p>
<p>But what if you wanted to strip away <code>public</code> plus the data type? For this, you would want the selection to go word-by-word instead of character-by-character as you alt-drag the mouse to the right.</p>
<p>To illustrate this concept, I created an animated GIF. (In case your curious how, I used PowerPoint to create the slides, saved them as PNG, imported them as layers into Paint .NET, and saved out the image as an AGIF using the <a href="http://forums.getpaint.net/index.php?/topic/13454-animated-image-24-agif-apng/">Animated Image plugin</a>.)</p>
<p><img src="http://www.devuxer.com/images/2014-12-19/delimited-column-selection.gif" alt="Delimited column selection - animated" /></p>
<p>I see this feature being useful for any situation where you have a bunch of similar declarations and you want to strip away something from each line or insert something new between the same two words of each line.</p>
<p>While writing this post, I began to wonder if delimited column selection already exists. I was thinking <a href="http://www.sublimetext.com/">Sublime Text</a> might have it, but I wasn't able to find it during my brief test drive. The default Visual Studio editors don't seem to have anything beyond standard column selection, but I did come across the <a href="https://visualstudiogallery.msdn.microsoft.com/2beb9705-b568-45d1-8550-751e181e3aef">MultiEditing extension</a>, which
Scott Hanselman <a href="http://www.hanselman.com/blog/SimultaneousEditingForVisualStudioWithTheFreeMultiEditExtension.aspx">blogged about</a> in 2013. While it sounds quite useful (I think I'll install it), it wouldn't be quite as easy for the use cases I have in mind.</p>
<p>Anyway, if you'd like to see delimited column selection in Visual Studio, I just posted the idea to <a href="https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/6863802-make-code-editors-more-awesome-with-delimited-colu">Visual Studio User Voice</a>.</p>
</a10:content></item><item><guid isPermaLink="true">http://www.devuxer.com/2014/02/15/why-the-mercurial-zipdoc-extension-fails-for-excel-files/</guid><link>http://www.devuxer.com/2014/02/15/why-the-mercurial-zipdoc-extension-fails-for-excel-files/</link><author>[email protected]</author><category>Excel</category><category>Mercurial</category><category>TortoiseHg</category><category>ZipDoc</category><title>Why The Mercurial ZipDoc Extension Fails For Excel Files</title><description><h1>The problem</h1>
<p>I tend to work on small projects with small file-based databases (usually SQL Server Compact Edition). I find it very convenient to use Excel files to create the seed data for these small databases. I even have a little library that uses a combination of <a href="http://epplus.codeplex.com/">EPPlus</a>, Entity Framework Code First, and good ol' ADO.NET to basically convert any properly formatted Excel file into a SQL Server Compact database.</p>
<p>Given that these Excel files are part of a project and change over time, I like to keep them in source control (in my case, Mercurial). Unfortunately, given that Excel files are not simple text files, it's not easy for Mercurial to determine what has changed from version to version. This makes it basically impossible to visualize what has changed, and over time, it can bloat the repository because the deltas are not stored efficiently. I've always wondered if there was some way to do this better.</p>
<h1>The solution?</h1>
<p>After a little Googling, I came across the <a href="http://mercurial.selenic.com/wiki/ZipdocExtension">Mercurial ZipDoc extension</a> and downloaded it. After a little more Googling, I realized I didn't need to download it, since it was already included with TortoiseHg. ZipDoc is supposed to allow for more efficient delta compression when committing Open Office format files (such as docx and xlsx).</p>
<h1>The test</h1>
<p>After making the appropriate modifications to mercurial.ini file, I performed a small test with a sample Excel 2010 file. My file consisted of one worksheet with the following content:</p>
<pre><code> | A B C D E F G H I J
------------------------------------------------------------------
1 | 1 1 1 1 1 1 1 1 1 1
2 | 2 2 2 2 2 2 2 2 2 2
... |
10000 | 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000
</code></pre>
<p>In other words, columns A to J of rows 1 to 10,000 were filled sequentially with numbers.</p>
<p>When I saved this file, its size on disk was 318 KB.</p>
<p>My test was very simple:</p>
<ol>
<li>Create a repo with just the Excel file (Book1.xlsx) in it.</li>
<li>Commit.</li>
<li>Change the value of cell A1 to 10.</li>
<li>Commit changes.</li>
<li>Change the value of cell A1 back to 1.</li>
<li>Commit changes.</li>
</ol>
<p>After each commit, I noted the size of the .hg/store/data folder.</p>
<h1>The (dismal) results</h1>
<p>Here are the results:</p>
<pre><code> ZipDoc ZipDoc
Commit Message Enabled Disabled
-------------------------------------
Initial commit 247 KB 32 KB
Change A1 to 10 493 KB 59 KB
Revert A1 to 1 738 KB 87 KB
</code></pre>
<p>I was expecting ZipDoc to result in a larger initial data file size, which it certainly did, but I was not expecting it to increase so rapidly with only very minor changes to the Excel file. If fact, with ZipDoc enabled, the data file size grew at virtually the same percentage rate as with ZipDoc disabled (but starting at a much higher initial size).</p>
<p>This basically means that ZipDoc was not performing well at all, at least for my particular test case.</p>
<h1>The explanation</h1>
<p>For the Excel file in question, the structure of the zipped archive can be revealed by adding ".zip" to the name of the file and extracting the contents.</p>
<p>The result is this:</p>
<pre><code>_rels
.rels
docProps
app.xml
core.xml
xl
_rels
workbook.xml.rels
theme
theme1.xml
worksheets
sheet1.xml
styles.xml
workbook.xml
[Content_Types].xml
</code></pre>
<p>I used Mercurial to analyze what files actually changed between two different versions of the Excel file. The answer was just xl/worksheets/sheet1.xml.</p>
<p>Opening this file, the reason for the dismal performance of ZipDoc became instantly obvious: the entire file was contained on one line (it was essentially compressed or "minified", containing no unnecessary white space). Since Mercurial compares files based on which <em>lines</em> have changed, it will always conclude that the entire file has changed. Hence, ZipDoc will never be able to do its job properly under these conditions.</p>
<p>When I actually formatted (prettified) sheet1.xml using Visual Studio's XML editor before committing it, Mercurial was able to find the one small difference between the two versions of the file, and it was able to store the delta very efficiently.</p>
<h1>The conclusion</h1>
<p>As long as Excel saves the component XML files as one-liners, ZipDoc won't be of any use, and will actually do more harm than good.</p>
<p>I'm not sure whether ZipDoc is being actively developed (the last update was in 2011), but in the hopes that it is, I posted <a href="https://bitbucket.org/gobell/hg-zipdoc/issue/1/tidy-open-office-xml-files-before">an issue</a> to the project's Bitbucket repository.</p>
<p>I'll try to keep this post updated as I learn more.</p>
</description><pubDate>Sat, 15 Feb 2014 08:00:00 Z</pubDate><a10:updated>2014-02-15T08:00:00Z</a10:updated><a10:content type="html"><h1>The problem</h1>
<p>I tend to work on small projects with small file-based databases (usually SQL Server Compact Edition). I find it very convenient to use Excel files to create the seed data for these small databases. I even have a little library that uses a combination of <a href="http://epplus.codeplex.com/">EPPlus</a>, Entity Framework Code First, and good ol' ADO.NET to basically convert any properly formatted Excel file into a SQL Server Compact database.</p>
<p>Given that these Excel files are part of a project and change over time, I like to keep them in source control (in my case, Mercurial). Unfortunately, given that Excel files are not simple text files, it's not easy for Mercurial to determine what has changed from version to version. This makes it basically impossible to visualize what has changed, and over time, it can bloat the repository because the deltas are not stored efficiently. I've always wondered if there was some way to do this better.</p>
<h1>The solution?</h1>
<p>After a little Googling, I came across the <a href="http://mercurial.selenic.com/wiki/ZipdocExtension">Mercurial ZipDoc extension</a> and downloaded it. After a little more Googling, I realized I didn't need to download it, since it was already included with TortoiseHg. ZipDoc is supposed to allow for more efficient delta compression when committing Open Office format files (such as docx and xlsx).</p>
<h1>The test</h1>
<p>After making the appropriate modifications to mercurial.ini file, I performed a small test with a sample Excel 2010 file. My file consisted of one worksheet with the following content:</p>
<pre><code> | A B C D E F G H I J
------------------------------------------------------------------
1 | 1 1 1 1 1 1 1 1 1 1
2 | 2 2 2 2 2 2 2 2 2 2
... |
10000 | 10000 10000 10000 10000 10000 10000 10000 10000 10000 10000
</code></pre>
<p>In other words, columns A to J of rows 1 to 10,000 were filled sequentially with numbers.</p>
<p>When I saved this file, its size on disk was 318 KB.</p>
<p>My test was very simple:</p>
<ol>
<li>Create a repo with just the Excel file (Book1.xlsx) in it.</li>
<li>Commit.</li>
<li>Change the value of cell A1 to 10.</li>
<li>Commit changes.</li>
<li>Change the value of cell A1 back to 1.</li>
<li>Commit changes.</li>
</ol>
<p>After each commit, I noted the size of the .hg/store/data folder.</p>
<h1>The (dismal) results</h1>
<p>Here are the results:</p>
<pre><code> ZipDoc ZipDoc
Commit Message Enabled Disabled
-------------------------------------
Initial commit 247 KB 32 KB
Change A1 to 10 493 KB 59 KB
Revert A1 to 1 738 KB 87 KB
</code></pre>
<p>I was expecting ZipDoc to result in a larger initial data file size, which it certainly did, but I was not expecting it to increase so rapidly with only very minor changes to the Excel file. If fact, with ZipDoc enabled, the data file size grew at virtually the same percentage rate as with ZipDoc disabled (but starting at a much higher initial size).</p>
<p>This basically means that ZipDoc was not performing well at all, at least for my particular test case.</p>
<h1>The explanation</h1>
<p>For the Excel file in question, the structure of the zipped archive can be revealed by adding ".zip" to the name of the file and extracting the contents.</p>
<p>The result is this:</p>
<pre><code>_rels
.rels
docProps
app.xml
core.xml
xl
_rels
workbook.xml.rels
theme
theme1.xml
worksheets
sheet1.xml
styles.xml
workbook.xml
[Content_Types].xml
</code></pre>
<p>I used Mercurial to analyze what files actually changed between two different versions of the Excel file. The answer was just xl/worksheets/sheet1.xml.</p>
<p>Opening this file, the reason for the dismal performance of ZipDoc became instantly obvious: the entire file was contained on one line (it was essentially compressed or "minified", containing no unnecessary white space). Since Mercurial compares files based on which <em>lines</em> have changed, it will always conclude that the entire file has changed. Hence, ZipDoc will never be able to do its job properly under these conditions.</p>
<p>When I actually formatted (prettified) sheet1.xml using Visual Studio's XML editor before committing it, Mercurial was able to find the one small difference between the two versions of the file, and it was able to store the delta very efficiently.</p>
<h1>The conclusion</h1>
<p>As long as Excel saves the component XML files as one-liners, ZipDoc won't be of any use, and will actually do more harm than good.</p>
<p>I'm not sure whether ZipDoc is being actively developed (the last update was in 2011), but in the hopes that it is, I posted <a href="https://bitbucket.org/gobell/hg-zipdoc/issue/1/tidy-open-office-xml-files-before">an issue</a> to the project's Bitbucket repository.</p>
<p>I'll try to keep this post updated as I learn more.</p>
</a10:content></item><item><guid isPermaLink="true">http://www.devuxer.com/2014/01/13/self-hosting-a-web-app-with-nancy/</guid><link>http://www.devuxer.com/2014/01/13/self-hosting-a-web-app-with-nancy/</link><author>[email protected]</author><category>Nancy</category><category>Web Applications</category><title>Serving up a website from a console app using Nancy</title><description><p>Have you ever wanted to build a desktop application that runs in a browser? As this post explains, <a href="http://nancyfx.org/">Nancy</a> makes it pretty darn easy--as long as you follow the right approach.</p>
<h1>Use case</h1>
<p>My use case was simple. I wanted to build a web application, then I wanted to give it to coworkers at my company as well as some external clients to run on their own machine. I didn't want them to have to worry about starting up a web server or dealing with any configuration. I just wanted them to be able to copy over a few files and double-click an EXE. In other words, I wanted it to "just work".</p>
<h1>Self hosting Nancy</h1>
<p>When I mentioned what I was trying to accomplish on <a href="https://jabbr.net/">JabbR</a>, <a href="http://www.grumpydev.com/">GrumpyDev</a> suggested (in an entirely non-grumpy manner, I might add) that I try self hosting Nancy. All I really understood about self-hosting at that point was that it was an alternative to ASP.NET hosting. Reading the <a href="https://github.com/NancyFx/Nancy/wiki/Self-Hosting-Nancy">wiki page</a> (and peppering GrumpyDev with several questions) provided a bit more insight, so I decided to give it a try.</p>
<h1>This is almost awesome!</h1>
<p>The first thing I did was create a console app. Then I added the <a href="https://www.nuget.org/packages/Nancy.Hosting.Self">Nancy.Hosting.Self</a> NuGet package. Then I added a module. So far, so good. Then I went to add a view, style sheet, and JavaScript file. That's when I got my first inkling that I was going a little against the grain. This being a console app, not a web project, the Add menu looked like this:</p>
<p><img src="http://www.devuxer.com/images/2014-01-13/add-menu-console-app.png" alt="" /></p>
<p>Instead of like this:</p>
<p><img src="http://www.devuxer.com/images/2014-01-13/add-menu-web-app.png" alt="" /></p>
<p>Of course, all these files could still be added, I just had to go into the Add Dialog to conjure them up. So, that's what I did. Not a big deal.</p>
<p>After fiddling a bit with the configuration and realizing that, oh, all build settings for all content files (namely, views, images, style sheets, and scripts) need to be "Content-Copy Always", I was up and running.</p>
<p>It took a minute to sink in, but this was actually a big deal. I was viewing a web page in my browser, but there was no apparent web server running. No IIS, no IIS Express, no Cassini. Pretty sweet.</p>
<p>Then, I attempted to edit a view. After saving the file, I reloaded the browser. Nothing changed. I checked to make sure Visual Studio was in Debug mode, not Release (since Release mode causes Nancy to cache pages), but that wasn't the problem. Then it dawned on me, since content can't be picked up unless it is copied to the appropriate bin folder, I needed to re-run the app.</p>
<p>That worked, but it was, again, not quite the usual workflow. Still, I reasoned, "I can live with this."</p>
<p>Then, I started to notice some issues with ReSharper: it was being a little more picky than usual about how I wrote my relative paths, and a number of items seemed to have disappeared from the intellisense menu when using the JavaScript editor. It even threw some inspection warnings for using <code>window</code> methods (such as <code>alert()</code>), which prompted me to write a <a href="http://stackoverflow.com/questions/21054706/unexpected-resharper-warnings-when-editing-a-javascript-file-in-a-console-app">StackOverflow question</a> in frustration.</p>
<p>None of these problems were deal-breakers, but I started to think, there must be a better way.</p>
<h1>A better solution?</h1>
<p>After pondering a couple different ideas, I decided to try a dual-project approach. I knew that, when it came to actually writing HTML, CSS, and JavaScript, I wanted a good ol' web project, but when it came time to deliver the results to others, I wanted a nice, portable, self-hosted, console app. So, I created one "ASP.NET Empty Web Application" and one "Console Application", and added the appropriate Nancy NuGet packages to each. Next, I put all modules, views, and content files from the original project into the web app.</p>
<p>Then, I got to what I thought would be the tricky part. How do I get the files from the web project to the appropriate folders in the console app? It turned out, I needn't have worried. I just added a reference to the web project from the console app and made sure, as before, that all views and content files were set to "Content-Copy Always". As for the module, it turned out I didn't need to do a thing. Nancy is smart enough to scan both the primary project as well as referenced projects to find modules.</p>
<h1>Details</h1>
<p>A couple notes:</p>
<ol>
<li><p>After installing the Nancy.Hosting.Self NuGet package, I modified my Program class to look like this:</p>
<pre><code>internal class Program
{
private static void Main()
{
var configuration = new HostConfiguration
{
UrlReservations = { CreateAutomatically = true }
};
using (var host = new NancyHost(configuration, new Uri("http://localhost:1234")))
{
host.Start();
Process.Start("http://localhost:1234");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
</code></pre>
<ul>
<li>The <code>UrlReservations</code> bit was to prevent an <code>AutomaticUrlReservationCreationFailureException</code>, as described in the <a href="https://github.com/NancyFx/Nancy/wiki/Self-Hosting-Nancy">wiki</a>.</li>
<li><code>Process.Start()</code> simply opens the home page of the web app in the default browser.</li>
</ul></li>
<li><p>Just in case you were tempted to use the same port number for both apps, don't do this (I tried). It will fail, even if you never run both apps at the same time.</p></li>
</ol>
<h1>tl;dr;</h1>
<p>If you want to build a web application for individual use, and you want it to be portable and as easy to run as any desktop app, use a Nancy self hosted console app for deployment, but do your web development and debugging with an ASP.NET-hosted Nancy web app. It's barely any extra work to set up this way, and it will ensure all your web development tools work as designed.</p>
</description><pubDate>Mon, 13 Jan 2014 08:00:00 Z</pubDate><a10:updated>2014-01-13T08:00:00Z</a10:updated><a10:content type="html"><p>Have you ever wanted to build a desktop application that runs in a browser? As this post explains, <a href="http://nancyfx.org/">Nancy</a> makes it pretty darn easy--as long as you follow the right approach.</p>
<h1>Use case</h1>
<p>My use case was simple. I wanted to build a web application, then I wanted to give it to coworkers at my company as well as some external clients to run on their own machine. I didn't want them to have to worry about starting up a web server or dealing with any configuration. I just wanted them to be able to copy over a few files and double-click an EXE. In other words, I wanted it to "just work".</p>
<h1>Self hosting Nancy</h1>
<p>When I mentioned what I was trying to accomplish on <a href="https://jabbr.net/">JabbR</a>, <a href="http://www.grumpydev.com/">GrumpyDev</a> suggested (in an entirely non-grumpy manner, I might add) that I try self hosting Nancy. All I really understood about self-hosting at that point was that it was an alternative to ASP.NET hosting. Reading the <a href="https://github.com/NancyFx/Nancy/wiki/Self-Hosting-Nancy">wiki page</a> (and peppering GrumpyDev with several questions) provided a bit more insight, so I decided to give it a try.</p>
<h1>This is almost awesome!</h1>
<p>The first thing I did was create a console app. Then I added the <a href="https://www.nuget.org/packages/Nancy.Hosting.Self">Nancy.Hosting.Self</a> NuGet package. Then I added a module. So far, so good. Then I went to add a view, style sheet, and JavaScript file. That's when I got my first inkling that I was going a little against the grain. This being a console app, not a web project, the Add menu looked like this:</p>
<p><img src="http://www.devuxer.com/images/2014-01-13/add-menu-console-app.png" alt="" /></p>
<p>Instead of like this:</p>
<p><img src="http://www.devuxer.com/images/2014-01-13/add-menu-web-app.png" alt="" /></p>
<p>Of course, all these files could still be added, I just had to go into the Add Dialog to conjure them up. So, that's what I did. Not a big deal.</p>
<p>After fiddling a bit with the configuration and realizing that, oh, all build settings for all content files (namely, views, images, style sheets, and scripts) need to be "Content-Copy Always", I was up and running.</p>
<p>It took a minute to sink in, but this was actually a big deal. I was viewing a web page in my browser, but there was no apparent web server running. No IIS, no IIS Express, no Cassini. Pretty sweet.</p>
<p>Then, I attempted to edit a view. After saving the file, I reloaded the browser. Nothing changed. I checked to make sure Visual Studio was in Debug mode, not Release (since Release mode causes Nancy to cache pages), but that wasn't the problem. Then it dawned on me, since content can't be picked up unless it is copied to the appropriate bin folder, I needed to re-run the app.</p>
<p>That worked, but it was, again, not quite the usual workflow. Still, I reasoned, "I can live with this."</p>
<p>Then, I started to notice some issues with ReSharper: it was being a little more picky than usual about how I wrote my relative paths, and a number of items seemed to have disappeared from the intellisense menu when using the JavaScript editor. It even threw some inspection warnings for using <code>window</code> methods (such as <code>alert()</code>), which prompted me to write a <a href="http://stackoverflow.com/questions/21054706/unexpected-resharper-warnings-when-editing-a-javascript-file-in-a-console-app">StackOverflow question</a> in frustration.</p>
<p>None of these problems were deal-breakers, but I started to think, there must be a better way.</p>
<h1>A better solution?</h1>
<p>After pondering a couple different ideas, I decided to try a dual-project approach. I knew that, when it came to actually writing HTML, CSS, and JavaScript, I wanted a good ol' web project, but when it came time to deliver the results to others, I wanted a nice, portable, self-hosted, console app. So, I created one "ASP.NET Empty Web Application" and one "Console Application", and added the appropriate Nancy NuGet packages to each. Next, I put all modules, views, and content files from the original project into the web app.</p>
<p>Then, I got to what I thought would be the tricky part. How do I get the files from the web project to the appropriate folders in the console app? It turned out, I needn't have worried. I just added a reference to the web project from the console app and made sure, as before, that all views and content files were set to "Content-Copy Always". As for the module, it turned out I didn't need to do a thing. Nancy is smart enough to scan both the primary project as well as referenced projects to find modules.</p>
<h1>Details</h1>
<p>A couple notes:</p>
<ol>
<li><p>After installing the Nancy.Hosting.Self NuGet package, I modified my Program class to look like this:</p>
<pre><code>internal class Program
{
private static void Main()
{
var configuration = new HostConfiguration
{
UrlReservations = { CreateAutomatically = true }
};
using (var host = new NancyHost(configuration, new Uri("http://localhost:1234")))
{
host.Start();
Process.Start("http://localhost:1234");
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
}
</code></pre>
<ul>
<li>The <code>UrlReservations</code> bit was to prevent an <code>AutomaticUrlReservationCreationFailureException</code>, as described in the <a href="https://github.com/NancyFx/Nancy/wiki/Self-Hosting-Nancy">wiki</a>.</li>
<li><code>Process.Start()</code> simply opens the home page of the web app in the default browser.</li>
</ul></li>
<li><p>Just in case you were tempted to use the same port number for both apps, don't do this (I tried). It will fail, even if you never run both apps at the same time.</p></li>
</ol>
<h1>tl;dr;</h1>
<p>If you want to build a web application for individual use, and you want it to be portable and as easy to run as any desktop app, use a Nancy self hosted console app for deployment, but do your web development and debugging with an ASP.NET-hosted Nancy web app. It's barely any extra work to set up this way, and it will ensure all your web development tools work as designed.</p>
</a10:content></item><item><guid isPermaLink="true">http://www.devuxer.com/2013/12/15/starting-a-blog/</guid><link>http://www.devuxer.com/2013/12/15/starting-a-blog/</link><author>[email protected]</author><category>Blogging</category><category>Sandra Snow</category><title>Powered by Sandra Snow</title><description><p>Welcome to my new blog. I've wanted to have a blog for a while, but I hesitated because I thought it would take a lot of effort to get started.</p>
<p>Now that I've done it, I can say, yep, it really was a pain!</p>
<p>There are three reasons creating this blog was hard:</p>
<ol>
<li>I started from nothing.</li>
<li>I wanted a solution that would give me full control over my content.</li>
<li>I didn't want to pay for hosting.</li>
</ol>
<h1>Going from zero to blog in...many hours</h1>
<p>I had to make a number of tough decisions along the way. Here are some of them:</p>
<ol>
<li>What should my domain be? <a href="http://www.devuxer.com">devuxer.com</a> </li>
<li>Which domain registrar should I use? <a href="https://www.namecheap.com/">Namecheap</a></li>
<li>Who should be my web host? <a href="https://github.com/">GitHub</a></li>
<li>How will I generate my blog? <a href="https://github.com/Sandra/Sandra.Snow">Sandra Snow</a></li>
</ol>
<p>There were also decisions within decisions. For example, Namecheap offers <a href="http://www.whoisguard.com/">WhoisGuard</a> free for one year. The idea behind WhoisGuard is that it keeps your personal contact information hidden from anyone trying to find out who owns your domain. Apparently, some feel this type of thing makes it easier for <a href="http://www.hostingdiscussion.com/domain-name-issues/10374-why-should-we-pay-whois-guard.html">scammers to hide their identity</a>, however, not hiding it can result in spam. I left it deactivated for about three days. Then I got my first piece of spam relating to my domain. That was the end of my experiment with not using WhoisGuard.</p>
<h1>Sandra Snow</h1>
<p>Once I decided I wanted to host my blog on GitHub, I spent quite a bit of time reading about and fiddling with Github Pages, Jekyll, and Jekyll Bootstrap. I really liked the idea of writing my posts in markdown, then running some code that magically turns them into a blog, but I was getting bogged down in the details of how to actually set everything up. I also kept reading things like:</p>
<blockquote>
<p>GitHub cannot afford to run arbitrary code on their servers so they lock developers down via Liquid. <a href="http://jekyllbootstrap.com/lessons/jekyll-introduction.html">Liquid is not programmer-friendly</a>.</p>
</blockquote>
<p>At some point, not really expecting anything to come of it, I hopped on <a href="https://jabbr.net/">JabbR</a> and said:</p>
<blockquote>
<p>YU so confusing, Jekyll?</p>
</blockquote>
<p>Phillip Haydon responded:</p>
<blockquote>
<p>Use Snow </p>
</blockquote>
<p>That's when things started to get easier. (Not quite easy, but definitely easier.) Rather than a Ruby solution like Jekyll, Sandra.Snow is a .NET solution. If I needed to debug anything (I did), I already had all the tools and at least some of the know-how. And instead of the dreaded Liquid, I would get to use good ol' Razor templates.</p>
<h1>A Snow step-by-step</h1>
<ol>
<li>Pretend you are going to use GitHub Pages:
<ul>
<li>Create a new repository in GitHub called your-domain (e.g., devuxer.com).
<ul>
<li>Enter a description (e.g., My blog).</li>
<li>Don't worry about a README (I didn't bother with it and nothing bad happened to me).</li>
</ul></li>
<li>Go into the settings for the repository:
<ul>
<li>Click "Automatic Page Generator".</li>
<li>Click "Continue to Layouts" (don't bother editing the page).</li>
<li>Choose the MINIMAL layout (actually, it doesn't matter).</li>
<li>Click PUBLISH.</li>
</ul></li>
<li>You should now have a gh-pages branch.</li>
</ul></li>
<li>"Haha, I was just kidding":
<ul>
<li>Install <a href="http://windows.github.com/">GitHub for Windows</a>, if necessary.</li>
<li>Go back to your browser and click "Clone In Desktop".</li>
<li>In Windows Explorer, delete everything except the .git folder from your working directory.</li>
<li>Commit changes.</li>
</ul></li>
<li>Replace all that stuff with the Sandra Snow Template:
<ul>
<li>Browse to the <a href="https://github.com/Sandra/Sandra.Snow.SnowTemplate">Sandra Snow Template</a>.</li>
<li>Click "Clone in Desktop".</li>
<li>In Windows Explorer, copy everything (except the .git folder) from the working directory of the template to the working directory of your blog.</li>
<li>Run compile.snow.bat to generate all the folders and files.</li>
<li>Commit changes.</li>
</ul></li>
<li>Replace anything that begins with "phill" with your own info:
<ul>
<li>Files you will almost certainly want to edit:
<ul>
<li>Root directory: CNAME</li>
<li>Snow directory: about.cshtml, rss.xml, snow.config</li>
<li>Snow/_layouts directory: default.cshtml</li>
</ul></li>
<li>Run compile.snow.bat again to generate the site.</li>
<li>Commit changes.</li>
</ul></li>
<li>Tell your domain registrar to redirect all web traffic to GitHub:
<ul>
<li>Log in to Namecheap (or whoever sold you your domain).</li>
<li>Navigate to the management screen for your domain.</li>
<li>Click URL Forwarding (or whatever your registrar calls it).</li>
<li>Set up your redirect to go from your domain to:
<ul>
<li>Record Type = A (Address)</li>
<li>IP Address/URL = 204.232.175.78</li>
<li>TTL = 3259</li>
</ul></li>
</ul></li>
<li>Set up <a href="http://disqus.com/">Disqus</a> to handle your comments:
<ul>
<li>Create a Disqus account, if necessary.</li>
<li>Click "Add Disqus to Your Site".</li>
<li>Follow the prompts until you get to a "Choose your platform" page, then stop.</li>
<li>Locate post.cshtml in Snow/_layouts and replace <code>*disqus id*</code> with your site's Disqus shortname (e.g., devuxer).</li>
<li>Commit changes.</li>
</ul></li>
<li>Set up Google Analytics and AddThis so you can obtain some some nice statistics on your blog:
<ul>
<li>Browse to <a href="http://www.google.com/analytics/">Google Analytics</a>.</li>
<li>Create a new account pointing to your domain.</li>
<li>Open default.cshtml in Snow/_layouts.</li>
<li>Replace the <code>****</code> in <code>_gaq.push(['_setAccount', '****']);</code> with your Tracking ID.</li>
<li>Add <code>@Html.RenderGoogleAnalytics("[your-tracking-id]")</code> below the <code>prettify</code> script element.</li>
<li>Browse to <a href="http://www.addthis.com/">AddThis</a>.</li>
<li>Create a new account.</li>
<li>Open post.cshtml in Snow/_layouts.</li>
<li>Replace the <code>****</code> in <code>#pubid=ra-****</code> with the code provided under "Add to your site".</li>
</ul></li>
<li>Replace all the sample posts with what will become your first post:
<ul>
<li>Download <a href="http://markdownpad.com/">MarkdownPad</a>, if necessary.</li>
<li>Delete all but one of the posts in Snow/_posts.</li>
<li>Rename the remaining file with the correct date and title.</li>
<li>Open the file in MarkdownPad and commence blogging!</li>
<li>Run compile.snow.bat again to generate the site.</li>
<li>Commit and sync to GitHub.</li>
<li>Look for your updated blog to appear in 10 minutes or less.</li>
</ul></li>
<li>Do some things I haven't done yet:
<ul>
<li>Edit the theme to give your blog a unique look and feel.</li>
<li>Make sure people are actually able to leave a comment.</li>
</ul></li>
</ol>
<h1>Conclusion</h1>
<p>If you want a blog that's truly your own, it's going to take some work to set up. If your situation is similar to mine, hopefully, I've at least spared you some of the struggle. Regardless, once you get over the hump of setting things up, it should be smooth sailing. At least, that's the idea.</p>
</description><pubDate>Sun, 15 Dec 2013 08:00:00 Z</pubDate><a10:updated>2013-12-15T08:00:00Z</a10:updated><a10:content type="html"><p>Welcome to my new blog. I've wanted to have a blog for a while, but I hesitated because I thought it would take a lot of effort to get started.</p>
<p>Now that I've done it, I can say, yep, it really was a pain!</p>
<p>There are three reasons creating this blog was hard:</p>
<ol>
<li>I started from nothing.</li>
<li>I wanted a solution that would give me full control over my content.</li>
<li>I didn't want to pay for hosting.</li>
</ol>
<h1>Going from zero to blog in...many hours</h1>
<p>I had to make a number of tough decisions along the way. Here are some of them:</p>
<ol>
<li>What should my domain be? <a href="http://www.devuxer.com">devuxer.com</a> </li>
<li>Which domain registrar should I use? <a href="https://www.namecheap.com/">Namecheap</a></li>
<li>Who should be my web host? <a href="https://github.com/">GitHub</a></li>
<li>How will I generate my blog? <a href="https://github.com/Sandra/Sandra.Snow">Sandra Snow</a></li>
</ol>
<p>There were also decisions within decisions. For example, Namecheap offers <a href="http://www.whoisguard.com/">WhoisGuard</a> free for one year. The idea behind WhoisGuard is that it keeps your personal contact information hidden from anyone trying to find out who owns your domain. Apparently, some feel this type of thing makes it easier for <a href="http://www.hostingdiscussion.com/domain-name-issues/10374-why-should-we-pay-whois-guard.html">scammers to hide their identity</a>, however, not hiding it can result in spam. I left it deactivated for about three days. Then I got my first piece of spam relating to my domain. That was the end of my experiment with not using WhoisGuard.</p>
<h1>Sandra Snow</h1>
<p>Once I decided I wanted to host my blog on GitHub, I spent quite a bit of time reading about and fiddling with Github Pages, Jekyll, and Jekyll Bootstrap. I really liked the idea of writing my posts in markdown, then running some code that magically turns them into a blog, but I was getting bogged down in the details of how to actually set everything up. I also kept reading things like:</p>
<blockquote>
<p>GitHub cannot afford to run arbitrary code on their servers so they lock developers down via Liquid. <a href="http://jekyllbootstrap.com/lessons/jekyll-introduction.html">Liquid is not programmer-friendly</a>.</p>
</blockquote>
<p>At some point, not really expecting anything to come of it, I hopped on <a href="https://jabbr.net/">JabbR</a> and said:</p>
<blockquote>
<p>YU so confusing, Jekyll?</p>
</blockquote>
<p>Phillip Haydon responded:</p>
<blockquote>
<p>Use Snow </p>
</blockquote>
<p>That's when things started to get easier. (Not quite easy, but definitely easier.) Rather than a Ruby solution like Jekyll, Sandra.Snow is a .NET solution. If I needed to debug anything (I did), I already had all the tools and at least some of the know-how. And instead of the dreaded Liquid, I would get to use good ol' Razor templates.</p>
<h1>A Snow step-by-step</h1>
<ol>
<li>Pretend you are going to use GitHub Pages:
<ul>
<li>Create a new repository in GitHub called your-domain (e.g., devuxer.com).
<ul>
<li>Enter a description (e.g., My blog).</li>
<li>Don't worry about a README (I didn't bother with it and nothing bad happened to me).</li>
</ul></li>
<li>Go into the settings for the repository:
<ul>
<li>Click "Automatic Page Generator".</li>
<li>Click "Continue to Layouts" (don't bother editing the page).</li>
<li>Choose the MINIMAL layout (actually, it doesn't matter).</li>
<li>Click PUBLISH.</li>
</ul></li>
<li>You should now have a gh-pages branch.</li>
</ul></li>
<li>"Haha, I was just kidding":
<ul>
<li>Install <a href="http://windows.github.com/">GitHub for Windows</a>, if necessary.</li>
<li>Go back to your browser and click "Clone In Desktop".</li>
<li>In Windows Explorer, delete everything except the .git folder from your working directory.</li>
<li>Commit changes.</li>
</ul></li>
<li>Replace all that stuff with the Sandra Snow Template:
<ul>
<li>Browse to the <a href="https://github.com/Sandra/Sandra.Snow.SnowTemplate">Sandra Snow Template</a>.</li>
<li>Click "Clone in Desktop".</li>
<li>In Windows Explorer, copy everything (except the .git folder) from the working directory of the template to the working directory of your blog.</li>
<li>Run compile.snow.bat to generate all the folders and files.</li>
<li>Commit changes.</li>
</ul></li>
<li>Replace anything that begins with "phill" with your own info:
<ul>
<li>Files you will almost certainly want to edit:
<ul>
<li>Root directory: CNAME</li>
<li>Snow directory: about.cshtml, rss.xml, snow.config</li>
<li>Snow/_layouts directory: default.cshtml</li>
</ul></li>
<li>Run compile.snow.bat again to generate the site.</li>
<li>Commit changes.</li>
</ul></li>
<li>Tell your domain registrar to redirect all web traffic to GitHub:
<ul>
<li>Log in to Namecheap (or whoever sold you your domain).</li>
<li>Navigate to the management screen for your domain.</li>
<li>Click URL Forwarding (or whatever your registrar calls it).</li>
<li>Set up your redirect to go from your domain to:
<ul>
<li>Record Type = A (Address)</li>
<li>IP Address/URL = 204.232.175.78</li>
<li>TTL = 3259</li>
</ul></li>
</ul></li>
<li>Set up <a href="http://disqus.com/">Disqus</a> to handle your comments:
<ul>
<li>Create a Disqus account, if necessary.</li>
<li>Click "Add Disqus to Your Site".</li>
<li>Follow the prompts until you get to a "Choose your platform" page, then stop.</li>
<li>Locate post.cshtml in Snow/_layouts and replace <code>*disqus id*</code> with your site's Disqus shortname (e.g., devuxer).</li>
<li>Commit changes.</li>
</ul></li>
<li>Set up Google Analytics and AddThis so you can obtain some some nice statistics on your blog:
<ul>
<li>Browse to <a href="http://www.google.com/analytics/">Google Analytics</a>.</li>
<li>Create a new account pointing to your domain.</li>
<li>Open default.cshtml in Snow/_layouts.</li>
<li>Replace the <code>****</code> in <code>_gaq.push(['_setAccount', '****']);</code> with your Tracking ID.</li>
<li>Add <code>@Html.RenderGoogleAnalytics("[your-tracking-id]")</code> below the <code>prettify</code> script element.</li>
<li>Browse to <a href="http://www.addthis.com/">AddThis</a>.</li>
<li>Create a new account.</li>
<li>Open post.cshtml in Snow/_layouts.</li>
<li>Replace the <code>****</code> in <code>#pubid=ra-****</code> with the code provided under "Add to your site".</li>
</ul></li>
<li>Replace all the sample posts with what will become your first post:
<ul>
<li>Download <a href="http://markdownpad.com/">MarkdownPad</a>, if necessary.</li>
<li>Delete all but one of the posts in Snow/_posts.</li>
<li>Rename the remaining file with the correct date and title.</li>
<li>Open the file in MarkdownPad and commence blogging!</li>
<li>Run compile.snow.bat again to generate the site.</li>
<li>Commit and sync to GitHub.</li>
<li>Look for your updated blog to appear in 10 minutes or less.</li>
</ul></li>
<li>Do some things I haven't done yet:
<ul>
<li>Edit the theme to give your blog a unique look and feel.</li>
<li>Make sure people are actually able to leave a comment.</li>
</ul></li>
</ol>
<h1>Conclusion</h1>
<p>If you want a blog that's truly your own, it's going to take some work to set up. If your situation is similar to mine, hopefully, I've at least spared you some of the struggle. Regardless, once you get over the hump of setting things up, it should be smooth sailing. At least, that's the idea.</p>
</a10:content></item></channel></rss>