Akkie
Akkie

Reputation: 39

Yii2 + AngularJS PrettyURL enable to work

I'm using Yii2 with AngularJS. I have to call different pages like about us, contact us etc. But my Pretty URL not working Properly. I need PrettyUrl like this:

localhost/angularjsyii/frontend/web/site/#/login

Current Url which is not working: localhost/angularjsyii/frontend/web/site#!/#%2Flogin

.htaccess

RewriteEngine on
# If a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward it to index.php
RewriteRule . index.php

main.php(<navbar>)

   <?php
use frontend\assets\AppAsset;

/* @var $this \yii\web\View */

AppAsset::register($this);
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="<?= Yii::$app->language ?>" ng-app="app">
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Angular Yii Application</title>
<?php $this->head() ?>

<script>paceOptions = {ajax: {trackMethods: ['GET', 'POST']}};</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/pace.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/themes/red/pace-theme-minimal.css" rel="stylesheet" />
<a base href="/angularjsyii/frontend/web/"></a>
</head>
<body>
<?php $this->beginBody() ?>
<div class="wrap">
    <nav class="navbar-inverse navbar-fixed-top navbar" role="navigation" bs-navbar>
        <div class="container">
            <div class="navbar-header">
                <button ng-init="navCollapsed = true" ng-click="navCollapsed = !navCollapsed" type="button" class="navbar-toggle">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span></button>
                <a class="navbar-brand" href="/angularjsyii/frontend/web/site/index">My Company</a>
            </div>
            <div ng-class="!navCollapsed && 'in'" ng-click="navCollapsed=true" class="collapse navbar-collapse" >
                <ul class="navbar-nav navbar-right nav">
                    <li data-match-route="/">
                        <a href="/">Home</a>
                    </li>
                    <li data-match-route="/about">
                        <a href="/about">About</a>
                    </li>
                    <li data-match-route="/contact">
                        <a href="/contact">Contact</a>
                    </li>
                    <li data-match-route="/login">
                        <a href="/login">Login</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

    <div class="container">
        <div ng-view>
        </div>
    </div>

</div>

<footer class="footer">
    <div class="container">

        <p class="pull-right"><?= Yii::powered() ?> <?= Yii::getVersion() ?></p>
    </div>
</footer>

<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>

app.js (For routing)

    'use strict';

    var app = angular.module('app', [
        'ngRoute',      //$routeProvider
        'mgcrea.ngStrap'//bs-navbar, data-match-route directives
    ]);

    app.config(['$routeProvider',
        function($routeProvider) {
            $routeProvider.
                when('/', {
                    templateUrl: 'partials/index.html'
                }).
                when('/about', {
                    templateUrl: 'partials/about.html'
                }).
                when('/contact', {
                    templateUrl: 'partials/contact.html'
                }).
                when('/login', {
                    templateUrl: 'partials/login.html'
                }).
                otherwise({
                    templateUrl: 'partials/404.html'
                });
        }
    ])

;

config/main.php

'urlManager' => [
    'class' => 'yii\web\UrlManager',
    // Disable index.php
    'showScriptName' => false,
    // Disable r= routes
    'enablePrettyUrl' => true,
],

Upvotes: 3

Views: 126

Answers (1)

lin
lin

Reputation: 18392

You should enable HTML5 mode in AngularJS to disable hashPrefix ! in your route.

app.config(['$routeProvider', '$locationProvider',
    function($routeProvider, $locationProvider) {
        $locationProvider.html5Mode(true);
        $routeProvider.
        when('/', {
            templateUrl: 'partials/index.html'
        }).
        when('/about', {
            templateUrl: 'partials/about.html'
        }).
        when('/contact', {
            templateUrl: 'partials/contact.html'
        }).
        when('/login', {
            templateUrl: 'partials/login.html'
        }).
        otherwise({
            templateUrl: 'partials/404.html'
        });
    }
]);

From reading the $location documentation of AngularJS:

Relative links

Be sure to check all relative links, images, scripts etc. You must either specify the url base in the head of your main html file (<base href="/my-base">) or you must use absolute urls (starting with /) everywhere because relative urls will be resolved to absolute urls using the initial absolute url of the document, which is often different from the root of the application.

In your case the base href should be something like this <a base href="/angularjsyii/frontend/web/site">. Now you dont need # on your URL anymore. Change your routes like:

<li data-match-route="/login">
    <a href="/login">Login</a>
</li>

The URL should finaly look like: localhost/angularjsyii/frontend/web/site/login which is more pretty.

Upvotes: 1

Related Questions