Using Assets in non-Yii legacy code


(Cshehadi) #1

Hi,

Ive followed the instructions here:

http://www.yiiframework.com/doc-2.0/guide-tutorial-yii-integration.html#using-yii-in-others

for using Yii2 with my legacy web site.

Yii2 features like Active Record work beautifully.

But I can’t figure out how to use Assets within my application.

In a normal Yii2 web application you simply write:




AppAsset::register($this);



and you’ll be able to use the functionality in whichever css or js files are defined in AppAsset.

But the register method requires a Yii2 view as its parameter - and I’m operating outside the MVC Yii2 environment - there’s no controller or view.

there’s no “$this” to register to.

I guess what I’m looking for is this:

The assets are already published into the root of the legacy application (because the legacy application sits on a server with another Yii2 application, and I’ve symlinked the Yii2 application’s assets directory).

So all I need is some reliable way to figure out the appropriate files to load, and output the appropriate link and script tags in my head tag.

Is there a way to get all the appropriate urls for a given Asset bundle without registering it?

Maybe the only solution is to just explicitly write the html to load the scripts and stylesheets from the existing symlinked Yii2 asset directories like so:




<script src="/assets/1a59b07c/yii.js" type="text/javascript"></script>

<script src="/assets/1a59b07c/yii.validation.js" type="text/javascript"></script>

<script src="/assets/1a59b07c/yii.activeForm.js" type="text/javascript"></script>

<script src="/assets/b224a1b/js/activeform.min.js" type="text/javascript"></script>

<link href="/assets/b224a1b/css/activeform.min.css" rel=stylesheet type=text/css>



if I do that is there any chance the automatically generated directory names will change - will they change each time assets get re-published in the other Yii2 application?

e.g. will /assets/1a59b07c always be named /assets/1a59b07c - after future publishes have happened, can I count on that?

The legacy app is getting completely rewritten in the next year, so I’m ok if the code is a little kludgy. I just need to install features now, and would like to do it using Yii2, so I can easily port the code to the rewritten Yii2 app at a later date. All that’s missing is the appropriate assets.

-Charlie


(Cshehadi) #2

I was able to get something to work. Client-side ActiveForm validation is not working - there maybe an issue with widgets registering asset, I’m not sure, but I’m on a time-schedule, and I can live with it as is.

My solution for the benefit of others is not for the faint of heart. There’s potential for js and conflicts with the legacy application. This only makes sense for the narrow case where someone is porting a large application to Yii, needs to add a feature to legacy code, and wants to do it with Yii, so they don’t have to recode it later when the application is rewritten.

here’s how I got it to work… in your entry script, after:




$yiiConfig = require(__DIR__ . '/../config/yii/web.php');

new yii\web\Application($yiiConfig); // Do NOT call run() here



add these lines:




Yii::$app->controller = new \yii\web\Controller('legacy-app', null);

Yii::$app->controller->setView(new \yii\web\View());

$yii_view = Yii::$app->controller->view;



this will create a dummy controller and view variable "$yii_view", which you can now use in your script to register AssetBundles, scripts and stylesheets.

you’ll need to symlink the assets, js and css directories from your existing Yii2 application’s web directory, so Yii can find the files you register.

To make sure Yii knows where to place these assets, in your html you’ll need to add this before your <!DOCTYPE> declaration:


<?php $yii_view->beginPage(); ?>

this after the closing </html> tag:


<?php $yii_view->endPage(); ?>

this right after the opening <head> tag:


<?php $yii_view->head() ?>

this after the opening <body> tag:


<?php $yii_view->beginBody() ?>

and this before the closing </body> tag:


<?php $yii_view->endBody() ?>

After you’ve done that Yii will faithfully manage assets for you:




use app\assets\AppAsset;


AppAsset::register($yii_view);



and you can register js or css files and it’ll work just fine:


<?php $yii_view->registerJsFile('/jquery/gotham_classes/options_panel_jquery.js', ['depends' => 'app\assets\AppAsset']) ?>

just watch out for conflicts with whatever js and css your your legacy application is already spitting out.

cool, huh?