Environment variables in symbolic links
Even though the symbolic links are resolved by the kernel, you could still do a LD_PRELOAD trick, wrapping all libc functions that take pathnames and expand any $XYZ components in the string returned by 'readlink' (parameter expansion). Then feed the expanded path to the wrapped function. You have to escape the target path from shell expansion when creating the link, as jaztik suggests.
As the injected library has full access to the users' environment, this will fulfill all expectations of the OP.
yes. no problem. actually you won't actually be using the $HOME variable in your link, so it won't work with smart solutions for groups of users for example. The variable is translated by the shell when executing the command, and the content of the variable is used in the link.
ln -s ~/test /tmp/test
is expaned to
/<path>/<to>/home/test -> /tmp/test
Ah. and only the environment variables of the person calling ln will work. You can't store other peoples environment variables in the link. The variables are expanded before calling the command.
If you don't want to expand the variable in the link you can put single quotes around it,
ln -s '$HOME/file/or/folder' newname
This would give,
newname -> $HOME/file/or/folder
rather than have it expand to your locally set $HOME. As described in other answers it will not expand it at all. So you can e.g. use it to symlink to a file inside the literal $HOME
folder.
[Note this is system dependent - not all systems support variant symlinks]
Symbolic links are handled by the kernel, and the kernel does not care about environment variables. So, no.