├── .gitignore ├── LICENSE ├── composer.json ├── readme.md ├── src ├── Compiler │ ├── BladeCompiler.php │ └── IlluminateBladeCompiler.php ├── Factory │ └── Factory.php ├── Providers │ └── ViewServiceProvider.php ├── View.php └── config │ └── view.php └── tests └── .gitignore /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /storage/*.key 5 | /vendor 6 | /.idea 7 | /.vscode 8 | /.vagrant 9 | Homestead.json 10 | Homestead.yaml 11 | npm-debug.log 12 | yarn-error.log 13 | .env 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 John Turingan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "johnturingan/laravel-fly-view", 3 | "version": "1.2.0", 4 | "description": "Render Blade templates from string mark-up.", 5 | "keywords": [ 6 | "laravel", 7 | "lumen", 8 | "blade", 9 | "view", 10 | "template", 11 | "render string mark-up", 12 | "view on the fly", 13 | "view caching" 14 | ], 15 | "authors": [ 16 | { 17 | "name": "John Turingan", 18 | "email": "john.turingan@gmail.com", 19 | "homepage": "http://scriptsandpixels.com/" 20 | } 21 | ], 22 | "license": "MIT", 23 | "type": "project", 24 | "require": { }, 25 | "require-dev": { }, 26 | "autoload": { 27 | "psr-4": { 28 | "Snp\\FlyView\\": "src/" 29 | } 30 | }, 31 | "autoload-dev": { 32 | "psr-4": { 33 | "Snp\\FlyView\\Test\\": "tests" 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # [Laravel](https://laravel.com)-fly-view 2 | 3 | >Is an Extension of Laravel View Class which compiles String Template on the fly. It automatically detects changes on your string template and recompiles it if needed. 4 | 5 | > This is useful if you want to render your template which came from other sources like CMS or third party API 6 | 7 | > Since its an Extension of laravel View class. It will not interfere on the usual flow of your application. You can still use laravel view as per normal but with the capability of passing string template. 8 | 9 | >It supports all directives of Blade Template. 10 | 11 | >Supports Laravel 5.2+ 12 | 13 | 14 | 15 | Installation :traffic_light: 16 | ------- 17 | Add the package to your composer.json 18 | 19 | ``` 20 | "require": { 21 | ... 22 | "johnturingan/laravel-fly-view": "{version}" 23 | }, 24 | ``` 25 | 26 | Or just run composer require 27 | 28 | ```bash 29 | $ composer require johnturingan/laravel-fly-view 30 | ``` 31 | 32 | In config/app.php replace 33 | 34 | ###### Illuminate\View\ViewServiceProvider::class 35 | 36 | with 37 | 38 | ###### Snp\FlyView\Providers\ViewServiceProvider::class 39 | 40 | 41 | ## Usage :white_check_mark: 42 | 43 | ###### View normal usage: 44 | Pass path to blade file using dot notation on the first parameter 45 | 46 | ``` 47 | return view('path.to.view', []); 48 | ``` 49 | 50 | ###### Flyview usage: 51 | Pass array of strings on the first parameter 52 | 53 | ``` 54 | return view([ 'String Template with {{$blade}} syntax and @directives' ], []); 55 | ``` 56 | or you can do 57 | 58 | ``` 59 | return view([ 60 | '{{ $token }}', 61 | '{{ $me }}' 62 | ], [ 63 | 'token' => Str::uuid(), 64 | 'me' => 'Laravel Fly View' 65 | ]); 66 | 67 | ``` 68 | 69 | Flyview will merge all strings inside the array before compile. Useful if you have multiple template sources. 70 | 71 | You can also use if from response helper like this. 72 | 73 | ``` 74 | return response()->view([ 75 | '{{ $token }}', 76 | '{{ $me }}' 77 | ], [ 78 | 'token' => Str::uuid(), 79 | 'me' => 'Laravel Fly View on Response Helper' 80 | ]); 81 | ``` 82 | 83 | Like I said before, it will not interfere the usual flow of Laravel View. Meaning you can do something like this. 84 | 85 | ``` 86 | $bag = [ 87 | 'include' => [ 88 | '{{ $token }} - This is FlyView Include', 89 | '@include("includes.nativeInclude")
Above is Include Inception' 90 | ], 91 | 'data' => [ 'token' => Str::uuid() ] 92 | ]; 93 | 94 | return view('includeTest', $bag); 95 | ``` 96 | 97 | Inside your includeTest.blade.php file is this: 98 | 99 | ``` 100 | @include('includes.nativeInclude', $data) 101 | 102 | @include($include, $data) 103 | ``` 104 | Including string template to blade template file is possible. 105 | 106 | ## Config :page_facing_up: 107 | 108 | All configuration is same as the default view config in your config folder with an additional settings to minimize view contents. Default is false. 109 | 110 | ``` 111 | /* 112 | |-------------------------------------------------------------------------- 113 | | Minify View Content 114 | |-------------------------------------------------------------------------- 115 | | 116 | | This option determines whether or not you want to minify view contents. 117 | | It removes unnecessary whitespace 118 | | 119 | */ 120 | 'minify' => false 121 | ``` 122 | 123 | **`NOTE:`** 124 | 125 | If you find any bugs or you have some ideas in mind that would make this better. Please don't hesitate to send comment on github. 126 | 127 | If you find this package helpful, a simple star is very much appreciated. 128 | 129 | ---- 130 | **[MIT](LICENSE) LICENSE**
131 | copyright © 2018 Scripts and Pixels. 132 | -------------------------------------------------------------------------------- /src/Compiler/BladeCompiler.php: -------------------------------------------------------------------------------- 1 | cachePath)) { 33 | $contents = $this->compileString($stringTemplate); 34 | 35 | $this->files->put($this->getCompiledPath($stringTemplate), $this->minify($contents)); 36 | } 37 | } 38 | 39 | /** 40 | * Determine if the view at the given path is expired. 41 | * 42 | * @param string $path 43 | * @return bool 44 | */ 45 | public function isExpired($path) 46 | { 47 | $compiled = $this->getCompiledPath($path); 48 | 49 | // If the compiled file doesn't exist we will indicate that the view is expired 50 | // so that it can be re-compiled. Else, we will verify the last modification 51 | // of the views is less than the modification times of the compiled views. 52 | if (! $this->files->exists($compiled)) { 53 | return true; 54 | } 55 | 56 | return false; 57 | } 58 | 59 | /** 60 | * minify string content before save 61 | * @param $contents 62 | * @return string 63 | */ 64 | private function minify ($contents) 65 | { 66 | 67 | $replace = [ 68 | '//s' => '', 69 | "/<\?php/" => ' ' $1', 71 | "/\r/" => '', 72 | "/\n/" => '', 73 | "/\t/" => ' ', 74 | '/ +/' => ' ', 75 | ]; 76 | 77 | return preg_replace(array_keys($replace), array_values($replace), $contents); 78 | 79 | } 80 | 81 | } -------------------------------------------------------------------------------- /src/Compiler/IlluminateBladeCompiler.php: -------------------------------------------------------------------------------- 1 | setPath($path); 32 | } 33 | 34 | if (! is_null($this->cachePath)) { 35 | $contents = $this->compileString($this->files->get($this->getPath())); 36 | 37 | $this->files->put($this->getCompiledPath($this->getPath()), $this->minify($contents)); 38 | } 39 | } 40 | 41 | /** 42 | * minify string content before save 43 | * @param $contents 44 | * @return string 45 | */ 46 | private function minify ($contents) 47 | { 48 | 49 | if (! config('view.minify')) return $contents; 50 | 51 | $replace = [ 52 | '//s' => '', 53 | "/<\?php/" => ' ' $1', 55 | "/\r/" => '', 56 | "/\n/" => '', 57 | "/\t/" => ' ', 58 | '/ +/' => ' ', 59 | ]; 60 | 61 | return preg_replace(array_keys($replace), array_values($replace), $contents); 62 | 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /src/Factory/Factory.php: -------------------------------------------------------------------------------- 1 | parseData($data)); 36 | 37 | //Render String Template 38 | 39 | if (is_array($view)) { 40 | 41 | return tap($this->flyViewInstance($view, $data), function ($view) { 42 | $this->callCreator($view); 43 | }); 44 | 45 | } 46 | 47 | $path = $this->finder->find( 48 | $view = $this->normalizeName($view) 49 | ); 50 | 51 | // Next, we will create the view instance and call the view creator for the view 52 | // which can set any data, etc. Then we will return the view instance back to 53 | // the caller for rendering or performing other view manipulations on this. 54 | 55 | return tap($this->viewInstance($view, $path, $data), function ($view) { 56 | $this->callCreator($view); 57 | }); 58 | 59 | } 60 | 61 | /** 62 | * @param $view 63 | * @param $data 64 | * @return FlyView 65 | */ 66 | protected function flyViewInstance ($view, $data) 67 | { 68 | 69 | return new FlyView($this, $this->engines->resolve('flyView.blade'), $view, $data); 70 | } 71 | 72 | } -------------------------------------------------------------------------------- /src/Providers/ViewServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 31 | __DIR__.'/../config/view.php' => config_path('view.php'), 32 | ], 'config'); 33 | } 34 | 35 | /** 36 | * Register the service provider. 37 | * 38 | * @return void 39 | */ 40 | public function register() 41 | { 42 | 43 | $this->mergeConfigFrom( 44 | __DIR__.'/../config/view.php', 'view' 45 | ); 46 | 47 | $this->registerFlyViewBladeCompiler(); 48 | 49 | parent::register(); 50 | 51 | } 52 | 53 | /** 54 | * Register the view environment. 55 | * 56 | * @return void 57 | */ 58 | public function registerFactory() 59 | { 60 | $this->app->singleton('view', function ($app) { 61 | // Next we need to grab the engine resolver instance that will be used by the 62 | // environment. The resolver will be used by an environment to get each of 63 | // the various engine implementations such as plain PHP or Blade engine. 64 | $resolver = $app['view.engine.resolver']; 65 | 66 | $finder = $app['view.finder']; 67 | 68 | $factory = new Factory($resolver, $finder, $app['events']); 69 | 70 | // We will also set the container instance on this view environment since the 71 | // view composers may be classes registered in the container, which allows 72 | // for great testable, flexible composers for the application developer. 73 | $factory->setContainer($app); 74 | 75 | $factory->share('app', $app); 76 | 77 | return $factory; 78 | }); 79 | } 80 | 81 | /** 82 | * Register the engine resolver instance. 83 | * 84 | * @return void 85 | */ 86 | public function registerEngineResolver() 87 | { 88 | $this->app->singleton('view.engine.resolver', function () { 89 | $resolver = new EngineResolver; 90 | 91 | // Next, we will register the various view engines with the resolver so that the 92 | // environment will resolve the engines needed for various views based on the 93 | // extension of view file. We call a method for each of the view's engines. 94 | foreach (['file', 'php', 'blade', 'flyView'] as $engine) { 95 | $this->{'register'.ucfirst($engine).'Engine'}($resolver); 96 | } 97 | 98 | return $resolver; 99 | }); 100 | 101 | } 102 | 103 | /** 104 | * Register the Fly View Blade compiler implementation. 105 | * 106 | * @return void 107 | */ 108 | public function registerFlyViewBladeCompiler () 109 | { 110 | 111 | $this->app->singleton('flyView.blade.compiler', function ($app) { 112 | return new BladeCompiler($app['files'], $app['config']['view.compiled']); 113 | }); 114 | } 115 | 116 | /** 117 | * Register the Blade engine implementation. 118 | * 119 | * @param \Illuminate\View\Engines\EngineResolver $resolver 120 | * @return void 121 | */ 122 | public function registerFlyViewEngine ($resolver) 123 | { 124 | 125 | $resolver->register('flyView.blade', function () { 126 | return new CompilerEngine($this->app['flyView.blade.compiler']); 127 | }); 128 | } 129 | 130 | /** 131 | * Register the Blade compiler implementation. 132 | * 133 | * @return void 134 | */ 135 | public function registerBladeCompiler() 136 | { 137 | $this->app->singleton('blade.compiler', function ($app) { 138 | return new IlluminateBladeCompiler($app['files'], $app['config']['view.compiled']); 139 | }); 140 | } 141 | 142 | /** 143 | * Register the Blade engine implementation. 144 | * 145 | * @param \Illuminate\View\Engines\EngineResolver $resolver 146 | * @return void 147 | */ 148 | public function registerBladeEngine($resolver) 149 | { 150 | 151 | $resolver->register('blade', function () { 152 | return new CompilerEngine($this->app['blade.compiler']); 153 | }); 154 | } 155 | 156 | } -------------------------------------------------------------------------------- /src/View.php: -------------------------------------------------------------------------------- 1 | view = implode(' ', $view); 68 | $this->engine = $engine; 69 | $this->factory = $factory; 70 | 71 | $this->data = $data instanceof Arrayable ? $data->toArray() : (array) $data; 72 | 73 | } 74 | 75 | /** 76 | * Get the name of the view. 77 | * 78 | * @return string 79 | */ 80 | public function getName() 81 | { 82 | return sha1($this->view ?? '') ; 83 | } 84 | 85 | /** 86 | * Get the evaluated contents of the view. 87 | * 88 | * @return string 89 | */ 90 | protected function getContents() 91 | { 92 | return $this->engine->get($this->view, $this->gatherData()); 93 | } 94 | 95 | } -------------------------------------------------------------------------------- /src/config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | realpath(base_path('resources/views')) 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => realpath(storage_path().'/framework/views'), 32 | 33 | 34 | /* 35 | |-------------------------------------------------------------------------- 36 | | Minify View Content 37 | |-------------------------------------------------------------------------- 38 | | 39 | | This option determines whether or not you want to minify view contents. 40 | | It removes unnecessary whitespace 41 | | 42 | */ 43 | 'minify' => false 44 | 45 | ]; 46 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | --------------------------------------------------------------------------------