Today I spent some time on customizing the share-box used in this blog.
Here is the effect
The cover effect for the social network icons are simulate the icon is floating from the background by animating the shadow. In the implementation, I used some shadow described in Material Design Shadow in HTML. For the texts, I use the text-shadow effect that used on the same text shadow used on tht title of the article.
I’m working on reorganize posts today, and found some filename issue with Hexo.
Speical symbols are not escaped properly
Just found this issue today.
To ensure filename generate from title is legal as either file name or url path, Hexo uses hexo.util.escape.filename to escape the illegal symbols. filename does escape some symbols, but it doesn’t cover all illegal symbols, such as +, =, &, etc. If these symbols are not escaped properly, which generates illegal url link. As a result, your post will never be acessible.
I found this issue is because, I have a post with +3 trainer in its title, since + is not escaped, and + will be treated as space by http. As a consequence, my post will never be able to open, unless I escape + as %2B. To avoid this kind of problem, I wish all the symbols in post name are escaped as -.
Besides this issue, Hexo has another issue with name escaping that the escaped file name might contains continues -. For example, your post title is “A great introduction - part 1”, you will get escaped name a-great-introduction---part-1.md. I wish the continues - in the file name should be replaced with single -, name a-great-introduction-part-1.md is more readable than previous one.
To fix the 2 issues, I just created a pull request, hope it will be merged soon.
I cared about this issue so much is because I uses hexo-consle-rename plug-in, which also uses util.escape to handle file name. To keep naming consistency when between different version of Hexo, I addd a kind of evil monkey patch in the v0.1.2. So make sure the plug in can work properly even with old Hexo.
File name case issue
Besides the Hexo naming issue, I also met the case of the filename today. Although it depends on the blog hosting, but it might cause 404 if the file name case changed.
To avoid this kind of issue, I strongly recommend to set filename_case: 1 in _config.yml, which will make sure all file name are in lower case.
There is common pitfall here for Windows or Mac with case-insensitive file system. If you have deploy the website once with wrong filename casing. Regenerate after updated filename_case won’t help, because file system won’t treat case change in filename as “change”. So you cannot really commit the “change” to fix the 404 issue.
To fix this issue, there is easy and efficient trick. Go to .deploy folder, execute following commands:
1
2
3
4
$ git rm -rf *
$ git ci -m "Clean all file"
$ hexo clean
$ hexo d -g
To force clean the repo once enforce git to treat 2 files with same name but different casing as different ones. So the name casing issue can be fixed.
Hexoasset 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>
<imgsrc="screenshot.png">
</p>
<p>
<ahref="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:
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.
When writing blog with [Hexo], I uses hexo new command to create new post file. If the title of the post is provided, then the file is named according to the tile. This is super convinient, and I’m really loving it.
But there is problem! If I changed my mind when during the writing, so I changed the title of the post. As a consequence, the post file name doesn’t match to the post title any longer.
In the past, I have to rename the post file manually. If there is asset folder, I also have to remember rename it accordingly. And I have to becareful to avoid introduce typo, or it either break the reference or cause other problems.
Besides, if you have special name pattern for your post, such as have time-stamp in your post name. The problem is more complicated. You have to reserve the time-stamp carefully, and replace all the space or any other improper characters with -.
At least for me, it is a complicated, error-proning and unpleasant work to do.
I’m a lazy guy, I don’t want to repeat this pain time and time again. To save myself from such pain, I create the plug-in hexo-console-rename.
The plug-in reads the front-matter of the post, then figure out the proper name. It is smart enough to know what is the proper name for the post, when you changed your configuration, it changes its behavior also.
To use the plug-in is super easy. I usually use it in this way:
1
$ hexo r source/**/*.md
Then it scans all the posts for me, and fix the filename when necessary. Easy and efficient.
Advanced Usages
Actually after I created the plugin, I figured out sevearl advance usages of this plug-in. Sometimes, it could become your life savor!
new_post_name updated
If you change the new_post_name in your _config.yml. You new post will follow a different name pattern than old ones. At this time, you might really want to rename all the old posts to keep consistency! But do it manually is a painful job to do!
Then all the old files will be renamed under your new naming rule! Aesome!
date in your post changed
It isn’t a common case, but if you have changed the date field in the front-matter of your post. And you have time-stamp in your file name. You can also use hexo-console-rename to rename the file for you.
Hexo has a scripts folder, and the files under which are loaded by Hexo when start. I usually uses this folder as the development folder for my plug-in scripts. And extract them into independent package after polished it into package-ready quality.
Usually, the files under scripts should be javascripts. But as I’m a fan of Coffee Script, so I wish to use coffee-script to write the plug-ins. For the formal package, I compile the coffee scripts into javascripts before release. But for development, I wish to use coffee script directly.
In node.js, it is possible to require coffee-script directly, if you registered the coffee-script runtime compiler:
1
require('coffee-script/register');
And as how node.js require function is implemented, you cannot register coffee-script runtime compiler in .coffee file. Or the compiler will complain:
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at /usr/local/lib/node_modules/hexo/lib/loaders/scripts.js:17:11
at Array.forEach (native)
at /usr/local/lib/node_modules/hexo/lib/loaders/scripts.js:15:13
at /usr/local/lib/node_modules/hexo/lib/util/file2.js:339:7
at done (/usr/local/lib/node_modules/hexo/node_modules/async/lib/async.js:135:19)
at /usr/local/lib/node_modules/hexo/node_modules/async/lib/async.js:32:16
at /usr/local/lib/node_modules/hexo/lib/util/file2.js:335:11
at Object.oncomplete (evalmachine.<anonymous>:107:15)
Theoretically, it is possible to put the coffee-script registration code in a javascript file and also put it under /scripts folder. SO Hexo will load it when start-up.
Well, this approach doesn’t really work. If you try it, it is very likely to get the exactly same error as before. The reason is related to Hexo implementation. Hexo uses Scripts Loader to require files under /scripts. The loader doesn’t really provide an explicit way to specify which file is loaded before another. So the registration file is guaranteed to be loaded before any .coffee.
So far, it seems that there is no cure to this problem! But actually it does. There is undocumented feature will help to solve this issue.
Hexo uses [Script Loader] to load the scripts. In Scripts Loader use hexo.util.file2 to populate the source files under /scripts. And hexo.util.file2 use fs.readdir to actully populate the file system entries. For fs.readdir, there is a undocumented feature, that the populated entries are actually sorted alphabetically, which means a.js is loaded before b.coffee.
With this feature, we can put our coffee-script registration in a file with lower alphabetic-order name. Personally, I’d like called ___register_coffeescript.js, since _ is smaller than any letter or number.
⚠️WARNING: fs.readdir yielding sorted files is an undocumented behavior, which means it is not guaranteed either to work across platforms or not get changed in the future. So for, it works on Mac, and I expect it behaves similar on Linux. But not sure about Windows, since fs uses a different native binding on Windows.
To ㊗️ my wife passed driver license theory course, I created a new log for my blog 😝
Here is what I got:
Gear
Gear is the hint of workshop. Because this blog is named as TimNew's ThoughtWorkshop
In the beginning, I was intend to create the gear in Steampunk style. I like such old-fashioned style, but later I found such style is not distinguishable in small icon, so I simplified it to the dark-metel gear.
D
Letter D is from the pronunciation of my Chinese name, which might not be well-known. It is a personal logo, so I wish to have something personal in it.
Favicon is the little icon that displayed on the title bar or tab bar when you browsing a web site. At very beginning, it is used to be the little icon displayed in favoriate bar when user add the website to favorites. Then later, it becomes the the standard way to specify custom icon for a website.
Most web site provides favico, developer add one line description in the <head>:
This simple piece of code works, but there are a lot of issues with this declaration. Actually specify the favico isn’t as simple as you might expect!
For this piece of code, according to W3C document how to favicon, there are 2 issues with it:
First, shortcut isn’t a standard value for rel, it is only for IE.
Second, ico format is a Microsoft oriented file type, not all platform likes it. Linux, Mac, iOS, Android, do not really appreciate this format.
Beides the 2 issues described above, the size of the favicon also matters.
Someone says it should be 16x16. Yes, 16x16 icon is used in tab or tree view. Some other says it should be 32x32. Well, this is also true. 32x32 icon is displayed in toolbar.
16x16 and 32x32 are the most used sizes for favico, but that’s not all. The reality is a lot complicated, I’ll explain this issue later. Let focus on this 2 size first.
To provide the image with 2 different sizes. For ico it is not an issue, since ico is a image container file format, which can encapsulate several images with different sizes and color in a single file. It is convenient for developer, but not for users. Because it means the users need to download a big file, most of the data in which is not used at all.
For the recommended png, it is no way to provide multiple images in a single file. So we have to provide 2 different separate files, and specify them with 2 different <link> tags with sizes attribute. This is a more efficient way, but unfortunately, you’re living in the world has something called Internet Explorer. The favico in png is not supported by IE until IE 11. What a hell!
Actually, there is a lot of issue with IE in this case. There is an great article by Mathias Bynen that discussed this issue in detail, which provides a lot of interesting information related to favico.
Microsoft Windows 8
Besides typical browser usage, Favicon is also used to create Metro Tile by IE 10 and IE 11 on Windows 8. It requires something quite different. Here is a MSDN document that described how to create custom tiles for IE11 websites. For these tile icon, Windows 8 also asks for a background color other than the icon itself.
Android
In the age of mobile internet, favicon is not just used by the desktop browser, but also mobile devices. On mobile devices, there are some more specific requirements.
On android, the screen size and resolution varies between devices. So the visual elements on Android are measured in dp. According to the screen resolution, there are different conversion ratios between dp and px. And to have pixel perfect image on Android, developer should provide several images for different dp-px-ratios.
Google have a well written document that described how to create icon for the web app that added to homescreen.
iOS
For iOS, it is simliar to Android, but seems to be much more complicated. On iOS, it is also possible to create a shortcut for the web apps. Apple named such icon as apple touch icon, which is used by Safari and other browsers on iOS.
For the iOS devices, iPhone and iPad have different screen sizes, so they have different size requirements for touch icon.
Furthermore, there are device with retina display and with normal one. To have pixel perfect image on retina display, it requires the resolution of the image to be doubled.
And since iOS 7, iOS changed its UI style, the icon size used by iOS 7 is also slightly changed. So you should provide new icons for iOS 7 devices!
To make the icon fit iOS visual style best, Apple recommend web application to provide precomposed icon, which is a icon that added rounded corner and background by itself.
To have the pixel perfect icon on iOS, you might need to provide around 10 different images files as apple touch icon.
What a hell!!!! The touch icon on iOS is totally a mess!!!!
Besides all cases that describe above, favicon is also used in some special cases, such as Google TV, Opera Speed Dial, Chrome Web App. They all requires different size of favico.
Conclusion
In a short description, favico isn’t as simple as it looks. And it actually used wrongly by most websites. To provide proper favico for all platforms and devices is not a simple work to do. Here is the favico declaration that used this blog:
And these files are served on this blog as favico:
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
favicon.ico
favicon-16x16.png
favicon-32x32.png
favicon-96x96.png
favicon-160x160.png
favicon-196x196.png
apple-touch-icon.png
apple-touch-icon-precomposed.png
apple-touch-icon-57x57.png
apple-touch-icon-60x60.png
apple-touch-icon-72x72.png
apple-touch-icon-76x76.png
apple-touch-icon-114x114.png
apple-touch-icon-120x120.png
apple-touch-icon-144x144.png
apple-touch-icon-152x152.png
browserconfig.xml
mstile-70x70.png
mstile-144x144.png
mstile-150x150.png
mstile-310x150.png
mstile-310x310.png
As you can see, to prepare all these configurations and files is not an easy job to do. It really consumes you a lot effort.
Fortunately, we have the awesome Real Favicon Generator brought by Philippe Bernard, which will save your tons of time to have the proper fav icon configuration.
Real Favicon Generator also comes with a favicon checker, which check the favorite configuration for your website, and generates beautiful report.
At last the FAQ of the site also provides a good explanation of the issue described above in details. Hope it helps.
CodePen is a service that provide Html, JavaScript and Css live show-case. It is another clone of Js Fiddle, but with cooler UI and support.
Both CodePen and Js Fiddle provides embedded widget that allow user to embedded their code into blog or articles.
Here is the example, code from CodePen:
This is from Js Fiddle:
Hexo has built-in the Js Fiddle Plug-in to allow writer to embed code from Js Fiddle, which is probably ported from Octopress. But for CodePen, there is not such thing.
So I created hexo-tag-codepen, its provides similar syntax as built-in ‘Js Fiddle’ plug in:
Stylus is an awesome CSS pre-processor, which provides much more concise syntax and more powerful feature than its competitors, such as LESS or SCSS.
But now, with more and more features added into Stylus, it seems its syntax become over-weighted. Pitfall come up.
I wish to declare an array of values for box-shadow property. And I can reference them with index:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
drop-shadows = [
02px10px0 rgba(0, 0, 0, 0.16),
06px20px0 rgba(0, 0, 0, 0.19),
017px50px0 rgba(0, 0, 0, 0.19),
025px55px0 rgba(0, 0, 0, 0.21),
040px77px0 rgba(0, 0, 0, 0.22)
]
drop-shadow(n)
box-shadow shadows[n]
foriin (1..5)
.drop-shadow-{i}
drop-shadow(i)
And expect it generates
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.drop-shadow-1 {
box-shadow: 02px10px0rgba(0, 0, 0, 0.16);
}
.drop-shadow-2 {
box-shadow: 06px20px0rgba(0, 0, 0, 0.19);
}
.drop-shadow-3 {
box-shadow: 017px50px0rgba(0, 0, 0, 0.19);
}
.drop-shadow-4 {
box-shadow: 025px55px0rgba(0, 0, 0, 0.21);
}
.drop-shadow-5 {
box-shadow: 040px77px0rgba(0, 0, 0, 0.22;
}
But I found there is not such thing called Array in Stylus!!!! There is only Hash, and Hash doesn’t accept number as key! So finally, I come up something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
drop-shadows = {
'1': 02px10px0 rgba(0, 0, 0, 0.16),
'2': 06px20px0 rgba(0, 0, 0, 0.19),
'3': 017px50px0 rgba(0, 0, 0, 0.19),
'4': 025px55px0 rgba(0, 0, 0, 0.21),
'5': 040px77px0 rgba(0, 0, 0, 0.22)
}
drop-shadow(n)
box-shadow shadows[n+'']
foriin (1..5)
.drop-shadow-{i}
drop-shadow(i)
In this piece of code, there are a bunch of pitfalls:
Hash doesn’t accept number as key. So 1: 0 2px 10px 0 rgba(0, 0, 0, 0.16) cause compile error.
'1' != 1, so drop-shadows[1] returns null
There is no type conversion function in Stylus, use the same trick as JavaScript. ''+n convert n into string.
Just found Stylus provides something called List, which is pretty much similar to what array in other languages, except the syntax.
Working on Hexo theme customization in past few days. And wish to borrow some concepts from Google’s Material Design.
The concept that I’m interested most in Material Design is the Dimensionality. It identify visual area on the page with Shadow. By defining multiple shadow configuration, it creates layers in a 2-D space! Simple and efficient. What a graceful solution!
By referencing the Shadow Definition in the spec, I recreate the effect with plain CSS.
Clicking the div will shift the shadow depth.
Mobile Support
Test it on Mobile, and found the top-shadow is not displayed properly. The reason is that I used multiple-shadow to apply Top Shadow and Bottom Shadow to the same div. But according to Box-Shadow MDN Document, Multiple shadows is only supported by iOS Safari with -webkit- prefix. So it doesn’t work properly.
Polymer and Angular-Js official implementations
Before recreate it, I also checked the Polymer and Angular JS, and the result is disappointing. Ploymer version has better quality than Angular Js version, Angular JS one is still very buggy.
Even they’re functioning, either Polymer or Angular-JS is too intrusive or too heavy for simple page to use, such as blog. If you don’t really need these transition animations, to implement these basic effects, CSS3 should be enough.