Loading javascript files from the vendors in CakePHP 3

前端 未结 3 1221
不知归路
不知归路 2021-01-18 10:04

My problem is how to load .js files from the vendors folder in CakePHP 3.0. I have included twitter bootstrap via composer. The .js file is located in /vendor/twbs/bootstrap

相关标签:
3条回答
  • 2021-01-18 10:39

    I don't like to copy files so based on previous answers i have created function which create links to bootstrap files. Note, that for Bootstrap4, which distributed without fonts now.

    /**
     * Create Bootstrap4 assets links
     *
     * @param string $dir The application's root directory.
     * @param \Composer\IO\IOInterface $io IO interface to write to console.
     * @return void
     */
    
    public static function createBootstrapLinks($dir, $io) {
        $ds = DIRECTORY_SEPARATOR;
        if (!file_exists($dir . $ds . 'vendor' . $ds . 'twbs' . $ds . 'bootstrap'))
        {
            $io->write('Bootstrap is not installed. Include Bootstrap into project: composer require twbs/bootstrap');
            return;
        }
        $bootstrapAssetsDir = realpath($dir . $ds . 'vendor' . $ds . 'twbs' . $ds . 'bootstrap' . $ds . 'dist');
        $bootstrapAssets = [
            'css' => $bootstrapAssetsDir . $ds . 'css' . $ds,
            'js' => $bootstrapAssetsDir . $ds . 'js' . $ds
        ];
        $webrootDir = realpath($dir . $ds . 'webroot');
    
        $webrootPathes = [
            'css' => $webrootDir . $ds . 'css' . $ds . 'bootstrap',
            'js' => $webrootDir . $ds . 'js' . $ds . 'bootstrap'
        ];
    
        foreach ($bootstrapAssets as $type => $asset)
        {
            if (!file_exists($asset))
            {
                $io->write('Asset `' . $asset . '` does not exists. Unable to create link.');
                continue;
            }
            $name = isset($webrootPathes[$type]) ? $webrootPathes[$type] : ($webrootDir . $type . $ds . 'bootstrap');
            if (file_exists($name))
            {
                switch(filetype($name))
                {
                    case 'link':
                        $link_target = readlink($name);
                        if ($link_target == $asset)
                        {
                            $io->write('Correct link to `' . $asset . '` already exists. Fine.');
                        }
                        else
                        {
                            $io->write('Link `' . $name . '` already exists and points to `'. $link_target .'`. Unable to create link.');
                        }
                        break;
                    case 'dir':
                        $io->write('Dir `' . $name . '` already exists. Unable to create link.');
                        break;
                    default:
                        $io->write(filetype($name).' `' . $name . '` already exists. Unable to create link.');
                        break;
                }
            }
            else
            {
                $io->write('Link `' . $name . '` to `' . $asset . '` created. Fine.');
                symlink($asset, $name);
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-18 10:40

    Same with mutdsu's answer but with more details.

    In composer.json, under scripts, add the line:

    "post-update-cmd": "App\\Console\\Installer::postUpdate",
    

    it should show something like this:

    "scripts": {
        ...
        "post-update-cmd": "App\\Console\\Installer::postUpdate",
        ...
    },
    

    In src/Console/Installer.php, add these two static functions:

    public static function postUpdate(Event $event) {
        $io = $event->getIO();
        $rootDir = dirname(dirname(__DIR__));
        static::copyBootstrapAssets($rootDir, $io);
    }
    
    public static function copyBootstrapAssets($dir, $io) {
        $ds = DIRECTORY_SEPARATOR;
        $bootstrapAssetsDir = $dir . $ds . 'vendor' . $ds . 'twbs' . $ds . 'bootstrap' . $ds . 'dist' . $ds;
        $bootstrapCssAssetsDir = $bootstrapAssetsDir . 'css' . $ds;
        $bootstrapJsAssetsDir = $bootstrapAssetsDir . 'js' . $ds;
        $bootstrapFontAssetsDir = $bootstrapAssetsDir . 'fonts' . $ds;
        $webrootDir = $dir . $ds . 'webroot' . $ds;
        $cssDir = $webrootDir . 'css' . $ds;
        $jsDir = $webrootDir . 'js' . $ds;
        $fontDir = $webrootDir . 'fonts' . $ds;
        if (!file_exists($cssDir) && !is_dir($cssDir)) {
            mkdir($cssDir);
        }
        if (!file_exists($jsDir) && !is_dir($jsDir)) {
            mkdir($jsDir);
        }
        if (!file_exists($fontDir) && !is_dir($fontDir)) {
            mkdir($fontDir);
        }
        $cssAssets = [
            'bootstrap.min.css',
            'bootstrap-theme.min.css',
        ];
        $jsAssets = [
            'bootstrap.min.js',
        ];
        $fontAssets = [
            'glyphicons-halflings-regular.eot',
            'glyphicons-halflings-regular.svg',
            'glyphicons-halflings-regular.ttf',
            'glyphicons-halflings-regular.woff',
            'glyphicons-halflings-regular.woff2',
        ];
        foreach ($cssAssets as $asset) {
            if (file_exists($bootstrapCssAssetsDir . $asset)) {
                copy($bootstrapCssAssetsDir . $asset, $cssDir . $asset);
                $io->write('Copied `' . $asset . '` file');
            } else {
                if (file_exists($cssDir . $asset)) {
                    unlink($cssDir . $asset);
                }
            }
        }
        foreach ($jsAssets as $asset) {
            if (file_exists($bootstrapJsAssetsDir . $asset)) {
                copy($bootstrapJsAssetsDir . $asset, $jsDir . $asset);
                $io->write('Copied `' . $asset . '` file');
            } else {
                if (file_exists($jsDir . $asset)) {
                    unlink($jsDir . $asset);
                }
            }
        }
        foreach ($fontAssets as $asset) {
            if (file_exists($bootstrapFontAssetsDir . $asset)) {
                copy($bootstrapFontAssetsDir . $asset, $fontDir . $asset);
                $io->write('Copied `' . $asset . '` file');
            } else {
                if (file_exists($fontDir . $asset)) {
                    unlink($fontDir . $asset);
                }
            }
        }
    }
    

    If you are using git, please make sure to add these lines to your .gitignore file:

    /webroot/css/bootstrap.min.css
    /webroot/css/bootstrap-theme.min.css
    /webroot/js/bootstrap.min.js
    /webroot/fonts/glyphicons-halflings-regular.eot
    /webroot/fonts/glyphicons-halflings-regular
    /webroot/fonts/glyphicons-halflings-regular.ttf
    /webroot/fonts/glyphicons-halflings-regular.woff
    /webroot/fonts/glyphicons-halflings-regular.woff2
    /webroot/fonts/glyphicons-halflings-regular.woff2
    
    0 讨论(0)
  • 2021-01-18 10:46

    I've found a solution! If I'm using composer why not to use it for this too, right? :)

    In composer.json:

    "scripts": {
        "post-install-cmd": "App\\Console\\Installer::postInstall",
        "post-update-cmd": "App\\Console\\Installer::postUpdate"
    }
    

    In src/Console/Installer.php:

    public static function postUpdate(Event $event) {
        $io = $event->getIO();
    
        $rootDir = dirname(dirname(__DIR__));
    
        static::copyTwitterBootstrapFiles($rootDir, $io);
    }
    
    public static function copyTwitterBootstrapFiles($dir, $io) {
    
        $bootstrapJsSource = $dir . '/vendor/twbs/bootstrap-sass/assets/javascripts/bootstrap.js';
        $bootstrapJsDestination = $dir . '/webroot/js/bootstrap.js';
    
        if (file_exists($bootstrapJsSource)) {
            copy($bootstrapJsSource, $bootstrapJsDestination);
            $io->write('Copied `bootstrap.js` file');
        }
    
    }
    

    And finally if you are using git add webroot/bootstrap.js to .gitignore. The postUpdate runs after every composer update command, so if you want to run the script after every actual package update just use post-package-update instead of post-update-cmd.

    0 讨论(0)
提交回复
热议问题