Design of path alias

In Yii 1.x, a path alias is in the format of "path.to.xyz". For example, system.web.CController

In Yii 2.0, we plan to use a new format (the old format will no longer be supported). This is based on our 1.x experience and some feature requests.

A general format of Yii 2.0 path alias is: "@rootAlias/path/to/xyz"

For example, @yii/base/Component.php

By calling Yii::setPathOfAlias(), one can register a root alias.

And by calling Yii::getPathOfAlias(), one can convert a path alias into a path with the root alias part replaced with the registered path.

Both of these are similar to Yii 1.x.

The reason we introduce the ‘@’ prefix is because it will allow us to more easily detect if a path is an alias or not.

And by using ‘/’ instead of ‘.’, our path aliases have more freedom to represent a path (previously, one cannot have ‘.’ as a normal char in a path alias).

Moreover, the new path alias format can allow us to represent not only file path, but also URLs.

For example, if we define ‘@yiiframework’ => ‘http://yiiframework.com’, then ‘@yiiframework/doc’ can be turned into ‘http://yiiframework.com/doc’. This should be very useful, I believe.

Your comments and opinions are welcome. Thanks!

I had some situations when I wanted to import files containing dots in their names, but obviously couldn’t do that. That’s why I surely support this new format.

The possibility to define URLs as aliases is certainly interesting. Also what I missed with the current alias specification was the possibility to write:




// with clientside.js being the script file

$cs->registerScriptFile( Yii::getPathOfAlias('ext.myExt.clientside.js') );



which should be possible with new spec, shouldn’t it?




$cs->registerScriptFile( Yii::getPathOfAlias('@ext/myExt/clientside.js') );



Somehow, I don’t like the ‘@’-prefix yet, but maybe I’ll get used to it. After all, it’s also a visual indication to the programmer, that an alias is being used, which might be a good thing.

Thumbs up for the change, so @ symbol will be kind of “system” alias… hmm… It makes me to remember an old operating system that used the $ symbol for system directory :P

Regards,

Ricardo

@robregonm: The @ char alone doesn’t represent a path. It is something like “@yii” that would represent a root alias. The reason for using @ char is because it stands for alias.

Yes, it takes some time for us to get used to this new format. This new format is purely out of practical needs, while the old one was mainly trying to emulate java.

In fact, as you will find later, we will make Yii 2.0 more practical and convenient to use. In Yii 1.x, we still have many places which were emulating some other projects without obvious advantages.

+1

nothing to add

I like it very much

I truly like this approach… nevertheless, i have a question, what is the difference between setting a URL in a path of alias or using an application parameter?

What is the case when i want to use the url in a path instead than in an application parameter -where i can easily setup my application url paths.

Cheers

Edit:

The only case where I would use this approach is if by using Yii::import(’@url/class.php’); I could actually include a component from an external repository.

I’m not thrilled about this proposal.

It seems to me, the reason you ran into problems/limitations with the original syntax, is because it was too simple and based on various assumptions about needs. Now you’ve extended the assumptions to include support for URLs, but it doesn’t feel like a great solution to me, because it’s still based on assumptions about a limited number of uses.

I like the approach taken by the stream handlers in PHP. Of course, we’re not dealing with streams here, but we are dealing with resources, and the Uniform Resource Identifier is the de-facto standard for identifying resources.

You’re trying to expand your custom resource-identification scheme to include URLs, which are just one type of URI - this to me is an indication that you’re working backwards; from a limited, non-standard scheme, to a single kind of URI, just one of a broad spectrum of resource-types supported by the URI scheme.

It doesn’t look to me like you can even fully support URL with this syntax? For instance, ‘@yiiframework/doc/api/1.1/CAttributeCollection#properties’ works for a URL, but won’t work for a file path - so you’re mixing two different types of “resources” (using one “alias”) that are incompatible.

The benefit of URI, is that type of resource is explicit rather than implied - “http://” clearly means it’s a web-address, while “mailto:” clearly identifies an email address, and “yii:” clearly defines an entirely different kind of resource.

The interpretation of each kind of URI is well-defined, yet fully flexible.

For example:




echo Yii::getPathOfAlias('yii:base/Component'); // => '/webroot/yii/base/Component.php'

echo Yii::getUrlOfAlias('doc:api/1.1/CAttributeCollection'); // => 'http://www.yiiframework.com/doc/api/...'

echo Yii::getPathOfAlias('components/MyClass'); // => '/webroot/app/protected/components/MyClass.php'



The last example (with no resource-type at the start) would imply a default resource-type, which might be called ‘alias’, so it would be the equivalent of, say ‘alias:components/MyClass’ - which would be interpreted at run-time the way aliases are interpreted now, searching for a root-alias, then a module, etc.

Each type of resource would need a handler of some sort - some handlers may implement an interface that Yii::getPathOfAlias() can use to obtain a path, some may implement an interface that enables Yii::getUrlOfAlias() to obtain a URL, and others might implement who-knows-what.

Providing a lower-level interface like Yii::getResource($uri) would enable you to identify a type of resource at run-time, and enable you to interact with that resource in different ways.

Other example of candidates for resources:

Images - for example, given a URI like ‘image:cat.jpg?320x200’, Yii::getUrlOfAlias() might give you ‘http://site.com/images/resized/cat_320x200.jpg’, while Yii::getPathOfAlias() might give you ‘/webroot/protected/files/images/resized/cat_320x200.jpg’.

Controllers and actions - for example, given a URI like ‘app:posts/show/4’, Yii::getUrlOfAlias() might give you ‘http://site.com/post/4-article-title’, while Yii::getPathOfAlias() might give you ‘/webroot/protected/controllers/PostController.php’.

Just throwing that out there for debate :slight_smile:

@Antonio Ramirez: you’re right. Using app params has the same effect. This new syntax is just an alternative way to prefix a URL.

@mindplay: the main reason for this new syntax is not about supporting URL (even though it does so). The idea is very simple: replace the root alias in a path with a predefined prefix. The path can be anything, file path, URL, or anything else, as long as ‘/’ is used as separator and there is a valid root alias. We can find this need in many places. The reason for the ‘@’ character is to differentiate it from non-aliased path.

What you proposed is something different and may probably cause confusion: alias and protocol are two different things. Maybe I don’t fully understand you, but I’m a bit confused at what problem you are trying to solve.

Well, I do believe we should not complicate things up, the idea behind is that you replace an alias with whatever you wish.

Maybe it could be a good thing to include validation within and allow multiple insertions with one call :




// throws an error in case is not a valid URL

Yii::setPathOfAlias( array('@yiiframework'=>'http://www.yiiframework.com','validator'=>CUrlValidator) );



This way, we could make sure dynamic aliases are valid ones…

Another requirement surfaces, demonstrating that you are dealing with a type of resource.

@qiang: what I’m suggesting is that your paths and/or aliases are in fact just resource identifiers - some users wish to expand that concept to include URLs, and Antonio here even wishes to validate URLs as an extra means of achieving early failure, something I strongly prefer over late failure, which is much harder to debug.

What I’m suggesting, is that adding support for “@” to disambiguate aliases may be too short-sighted. Next, you’ll be adding “#” to disambiguate URLs, and so forth.

Rather than adding one particular, very specific resource-type discriminator in the form of an "@" character, why not take the full plunge and use a standardized resource-identifier format, such as URI?

Instead of “@”, use “alias:” which is more concise - and make the alias scheme-interpreter it’s own separate entity, so we can expand on the concept as needed, extending or replacing scheme-interpreters and adding new ones if required.

I could write up some stub code if this still doesn’t make sense to you.

The idea that "everything is a resource" is the driving force behind REST, and certain interesting frameworks (such as OpenRasta and InfoGrid) build on the concept of resource-identifiers backed by resource-handlers. Everything begins with the URL, which is just another resource.

You may be right to think that this kind of thinking is overly complicated for Yii’s needs - I’m not trying to lead a revolution or completely change the idea of Yii, I’m just throwing this thought on the table for discussion… It may have certain useful aspects, or it may not :slight_smile:

mindplay, how often do you need resource identifiers for paths in your applications?

The KISS and Occam’s razor principles tell that we should not code something unless we know the reason for it.

Can you provide a few real-life use cases?

qiang, will there be an way to define custom set of aliases in config?

Maybe there should be a callback API, so that mindplay could implement his resource mappng?

You’re probably right - this is most likely overkill.

I’m just not a fan of overloading methods at run-time - especially with behavior that parses out strings and changes behavior based on some custom string-syntax. It feels dirty. It always makes me think I’m doing something wrong, and I should have solved the problem by designing an API that supports what I’m trying to do, instead of trying to roll it into some existing function by parsing strings. You know what I mean?

On the one hand, we’re replacing the alias resolution system with an ‘@’ prefix and ‘/’ instead of ‘.’. I see mindplay’s point though, although it adds a potential for a load of complexity. One option would be to simple implement as planned but use “alias:” as the opening token, which would give the option of adding that flexibility without changing the API later.

That said I can’t think of any examples of use as it stands.

i will miss elegant dot "." syntax:-(

let’s hope people will not get confused with forward - backward slash like windows - unix - namespaces - URL imply this differently.

will this work (using custom defined alias inside path)?




getPathOfAlias('@appRoot/modules/@myDirectoryRoot/lib/generator.class.php');



Perhaps this is good place also to sum up predefined aliases:




From 1.X

-----------

@system: refers to the Yii framework directory;

@zii: refers to the Zii library directory;

@application: refers to the application base directory;

@webroot: refers to the directory containing the entry script file.

@ext: refers to the directory containing all third-party extensions.



I suggest adding:




New in 2.X

-----------

@writable: refers to private writable area with cache, logs, etc.., currently corresponding to the "runtime"



Lubos