Use Hexo Asset Folder to manage resource used by post

Hexo asset folder is a folder that with the same name as you post file, the content in which will be copied to the folder where the rendered post html file located. It is a great way to keep the relationship between the post and its referenced resources. Personally, I prefers to put all the images or other downloadable files that referenced by the post into its asset folder.

Although asset folder is a great idea, but in practice, there are some common pitfall might disappoint you badly.

Relative Path Pitfall

The idea of asset folder is actually based on an assumption, that the asset resources will be placed under the same folder with the html. The html can reference these files with relative path.

Suppose we have following files as post file:

1
2
3
4
/2014-08-19-awesome-post.md
/2014-08-19-awesome-post/
screenshot.png
document.pdf

The compiled file structure will be like this:

1
2
3
4
/2014/08/19/awesome-post/
index.html
screenshot.png
document.pdf

The asset files are located in the same folder as the html file. So in the post file, you can reference the resource files as

1
2
3
![ScreenShot](screenshot.png)
[Document](document.pdf)

Then this will be compiled as following Html:

1
2
3
4
5
6
<p>
<img src="screenshot.png">
</p>
<p>
<a href="document.pdf">Document</a>
</p>

So far it looks great. But if you open your home page of you site, you find the image isn’t displayed, and the link to document.pdf is also broken.

The problem here is that the the relative path assumption only works in /2014/08/19/awesome-post/index.html. But the content compiled from 2014-08-19-awesome-post.md might also be used by HomePage(/index.html), Archive Page(/archive/index.html), and tag pages and category pages. For these html pages, the relative path relationship doesn’t exist. So the relative link causes 404 error.

To solve the issue, someone use absolute url in the post. So they write markdown in this way:

1
2
3
![ScreenShot](/2014/08/19/awesome-post/screenshot.png)
[Document](/2014/08/19/awesome-post/document.pdf)

This approach fix the link issue, but makes you lost the benefits of using relative path.

So you need hexo-tag-asset-res, which allow you to reference asset resources with relative path. It will convert them into absolute path during compilation. Easy and efficient.

Empty asset folders

For convenience, I turned on the post_asset_folder to true in my _config.yml. So the asset folder will be created along with post when I execute hexo new. It is great because create asset folder manually is boring and error-proning. If you introduced a typo carelessly, the link will be broken immediately.

But by ask Hexo to create asset folder automatically causes another problem. I don’t really have asset resources for each post, then there must be a number of empty asset folders. So I wish these folders can be removed if it is empty.

For this purpose, you might need hexo-console-clean-asset-folder. This plugin helps you to remove all the empty asset folders automatically.

Rename the post

Well, renaming a post already published is that common. But it is very likely to rename a draft. When renaming the post file, you have to remember also rename the asset folder too, or the link will broken.

To help you on this issue, you might need hexo-console-rename. The plugin helps you to rename the asset folder along with post. And it also helps you on migration once you updated your new_post_name pattern.

So this is the common pitfalls in using asset folder in Hexo, and the plug-ins that help you to mitigate the pain.

Asset path in Android Stuidio

According to Android guideline document, the assets folder is created automatically and is positioned under the root of the project folder.

So the assets folder should be located at <project root>/assets

But according to my experience, I found it is not true, or is partially true.

The path to assets folder varies according to the build system being used. So it could be very confusing and sometimes make things too complicated.

ADT

For the very traditional ADT build system, then the assets folder is located at <project root>/assets

Gradle

For new Gradle build system, it changed the project structure definition, which is slightly different to the ADT one.

Gradle build system requires the assets folder is part of the “source code” so the asset folder should located at <project root>/src/main/assets/.

For more detailed information, check out this document.

Android Studio

In Android Studio (also apply to IntelliJ IDEA), things get a little bit more complicated. The assets path could be configured in project.

Android Studio store this path in project file (*.iml), which is an xml file. In the project file, under the XPath /module/component@name="FacetManager"/facet@type="android"/configuration, there could be a <option> node with name ASSETS_FOLDER_RELATIVE_PATH to descript the path.

1
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/assets" />

If the option element with specific name doesn’t exist, please manully create it.

Conclusion

  • Using Eclipse + ADT, place the assets at <project root>/assets

  • Using Android Studio (or IntelliJ) with Ant or Maven, place the assets at <project root>/assets. And set ASSETS_FOLDER_RELATIVE_PATH to /assets

  • Using Android Studio with Gradle, place the assets at <project root>/src/main/assets/. And set ASSETS_FOLDER_RELATIVE_PATH to /src/main/assets. And invoke mergeAssets during build.

Self Registration Pattern for Singleton View Models in WPF

Where to store the Singleton View Model in WPF application, there are 2 common options:

Store in Resource Dictionary.

UI Designers prefers to store the WPF View Model into the Resource Dictionary because the objects in Resource Dictionary can be easily referenced in XAML.
But Developers must hate that way very much!
To fetch the object in Resource Dictionary from code behind must call the “FindResource” method of DependencyObject. And codes with tons of calls to “FindResource” method are ugly and very low efficient. The situation is worse since the accessibility to object in resource dictionary is also constrained by the Resource Scope, which means it is almost impossible to fetch the object from business logic.

Store in the Static Class.

I preferred to store the View Model in static class which is available globally. Developer can fetch the object by calling the static method, and designer also can fetch the object by using {x:Static} psudo-tag.
But it is still inconvenient somehow for designer, and it is somehow hard to provide design-time mockup data in this way.

For the previous 2 solutions, the pros and cons are obvious. But is it possible to combine these 2 approaches together to gains all the advantages but all the disadvantages.
The answer is Self-Registration Pattern.

The basic idea for Self-Registration Pattern is simple. It is obvious that we prefers to store the view models in Resource Dictionary, but we also want to access that object from Code Behind by calling static method.

So I designed the ViewModel class as following:

Self-Register View-Model
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ViewModel
{
#region Self Registration
public static ViewModel Default { get; private set; }
public ViewModel()
{
Default = this;
}
#endregion
}
View-Model Declaration
1
<vm:ViewModel x:Key="ViewModel"/>

You can see, the ViewModel has a globally visible static property named Default, and the class set the Default property to itself in its constructor.
Which means once the View Model is initialized in Resource Dictionary, it also set the instance reference to Default,
So designer can reference the view model easily with StaticResource Tag

Reference View-Model from XAML
1
<Control Property="{StaticResource ViewModel}"/>

And Developer also can access the view model by calling Static Property

Reference View-Model from C#
1
ViewModel.Default