Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/ctxcode/vue-pre

VuePre is a package to prerender vue templates using only PHP
https://github.com/ctxcode/vue-pre

Last synced: about 2 months ago
JSON representation

VuePre is a package to prerender vue templates using only PHP

Awesome Lists containing this project

README

        

# VuePre
VuePre is a package to prerender vue templates. This is useful for SEO and avoiding blank pages on page load. What VuePre does, is translating the Vue template to a PHP template, then replaces the javascript expressions with PHP expressions and caches it. Once cached, you can render thousands of templates per second depending on your hardware.

## PROS
```
- Very fast
- No dependencies
```

## CONS
```
- Some javascript expressions are not supported (yet).
```

## Installation
```
composer require ctxkiwi/vue-pre
```

## Basic usage

```php
$vue = new \VuePre\Engine();
$vue->setCacheDirectory(__DIR__ . '/cache');

// Method 1
$data = ["name" => "world"];
$html = $vue->renderHtml('

Hello {{ name }}!
', $data);

// Method 2 - Using component directory (required if you use sub-components)
$vue->setComponentDirectory(__DIR__ . '/components');
$html = $vue->renderComponent('my-page', $data);
```

## Component directory

```php
// If you set your directory like this
$vue->setComponentDirectory(__DIR__ . '/components');
// It's going to look for any .php file and register the filename as a component
// So, if you have components/pages/homepage.php
// It will use this file for the component
```

## Component example

```php
function (&$data) {
$data['counter'] = 0;
},
];
?>


-
{{ counter }}
+

Vue.component('homepage', {
template: '#vue-template-homepage',
data: function () {
return {
counter: 0,
};
},
methods: {
plus: function(){ this.counter++; },
min: function(){ this.counter--; },
}
});

```

## Real world example

```php
class View{
public static function render($view, $data = []){
// Normal PHP template engine
...
return $html;
}
public static function renderComponent($name, $data = []){
$vue = new \VuePre\Engine();
$vue->setCacheDirectory(Path::get('tmp'). '/cache');
$vue->setComponentDirectory(Path::get('views') . '/components');

$html = $vue->renderComponent($name, $data);
$templates = $vue->getTemplateScripts();
$js = $vue->getJsScripts();
$vueInstance = $vue->getVueInstanceScript('#app', $name, $data);

$html = '

'.$html.'
'.$templates.$js.$vueInstance;

return static::render('layouts/main.html', ['CONTENT' => $html];
}
}

class ViewController{
public function homepage(){
$data = [
// Dont put private data in here, because it's shared with javascript
'layoutData' => [
'authUser' => \AuthUser::getUser()->getPublicData(),
],
'featureProducts' => Product::where('featured', true)->limit(10)->get();
];
// Render component
echo View::renderComponent('homepage', $data);
}
}
```

```html





{!! $CONTENT !!}

```

```php
function (&$data) {
$data = $data['layout-data'];
},
];
?>


...



...

Vue.component('layout', {
props: ['layoutData'],
template: '#vue-template-layout',
data: function () {
return this.layoutData;
},
});

```

```php



Welcome


...


Featured products


{{ product.name }}



Vue.component('homepage', {
props: ['layoutData', 'featuredProducts'],
template: '#vue-template-homepage',
data: function () {
return {};
},
});

```

## Generating \

You can generate scripts for your component templates and your component.js files.

```php
// Based on your last render
$vue->getScripts();
$vue->getTemplateScripts(); // only template scripts
$vue->getJsScripts(); // only js scripts

// By component name
$vue->getTemplateScript('my-page');
$vue->getJsScript('my-page');

// Usefull
$vue->getRenderedComponentNames();
```

## API

```php
->setCacheDirectory(String $path)
->setComponentDirectory(String $path)
->setGlobals(Array $globalVariables) // e.g. ['loggedIn' => true, 'user' => ['id'=>123, 'username'=>'TerryDavis']]
->renderHtml(String $html, Array $data)
->renderComponent(String $componentName, Array $data)

// Optional settings
->ignoreAttributes(Array $attributeNames)
->unignoreAttributes(Array $attributeNames)
->getIgnoredAttributes() : Array $attributeNames

// Generating scripts
->getScripts($idPrefix = 'vue-template-');
->getTemplateScripts($idPrefix = 'vue-template-');
->getTemplateScript(String $componentName, $default = null, $idPrefix = 'vue-template-');
->getJsScripts();
->getJsScript(String $componentName, $default = null);

// Others
->getComponentAlias(String $componentName, $default = null)
->getRenderedComponentNames();
```

## JS expressions | Supported

```
# Prototype functions
.indexOf()
.length

# JS Functions
typeof()

# Values: variables, strings, numbers, booleans, null, objects, arrays, functions

# Comparisons
myVar === 'Hello'
something ? 'yes' : false

# Nested expressions
(((5 + 5) > 2) ? true : false) ? (myBool ? 'Yes' : 'Yez') : 'No'

# Objects
product.active ? product.name : product.category.name

# Methods using $vuePre->setMethods(['myFunc'=> function(){ ... }])
product.active ? myFunc(product.name) : null
```

## Todos

Note: Feel free to make an issue for these, so i can make them a prority. The only reason these are not implemented yet is because of low priority.

- Custom error handlers
- Options:
- `ignoreVariableNotFound`
- `ignoreVariableNames` `ignoreMethodNames`
- `ignoreSubComponents` `ignoreSubComponentNames`

## Contributors

The DOM iterator code was partially copied from [wmde/php-vuejs-templating](https://github.com/wmde/php-vuejs-templating)