Skip to content

Commit

Permalink
fix subform slot, add vue_prop twigFunction and vue twigFilter
Browse files Browse the repository at this point in the history
  • Loading branch information
k3ssen committed Apr 6, 2021
1 parent e1a1cca commit 0b213ac
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 6 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# SymfonyVuetifiedBundle

Integrate Vuetify into your Symfony application, making it easy to pass serverside data through
twig-file.
Integrate Vuetify into your Symfony application, making it easy to pass serverside data to Vue through Twig.

# Getting started

Expand Down
2 changes: 1 addition & 1 deletion Resources/assets/components/Form/SvForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<sv-form-widget v-bind="form.vars.row_attr" :form="form"></sv-form-widget>
</div>
<div v-else v-for="(child, key) in form.children" :key="key">
<slot :name="'subform_' + child.vars.name" v-bind="{ subform: child }" >
<slot :name="'subform_' + child.vars.name.toLowerCase()" v-bind="{ subform: child }" >
<sv-form-widget v-bind="child.vars.row_attr" :form="child"></sv-form-widget>
</slot>
</div>
Expand Down
2 changes: 1 addition & 1 deletion Resources/assets/components/Form/SvFormWidget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<div class="form-widget" :class="{ 'use-flex': row }">
<v-input v-bind="Object.assign(attributes, $attrs)">
<slot name="default" v-bind="{ children: form.children, ...form.children }">
<slot v-for="(child, key) in form.children" :name="'subform_' + child.vars.name" v-bind="{ subform: child }" >
<slot v-for="(child, key) in form.children" :name="'subform_' + child.vars.name.toLowerCase()" v-bind="{ subform: child }" >
<sv-form-widget
:key="key"
:class="{ col: row }"
Expand Down
3 changes: 1 addition & 2 deletions Resources/views/generator/crud/templates/_form.tpl.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
{{ vue_data('form', form) }}
<sv-form :form="form" label-submit="{{ button_label|default('Save') }}"></sv-form>
<sv-form :form="{{ form | vue('form') }}" label-submit="{{ button_label|default('Save') }}"></sv-form>

<v-divider class="my-5"></v-divider>
41 changes: 41 additions & 0 deletions Vue/VueExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

class VueExtension extends AbstractExtension
Expand All @@ -24,13 +25,21 @@ public function getFunctions(): array
{
return [
new TwigFunction('vue_data', [$this, 'addVueData']),
new TwigFunction('vue_prop', [$this, 'addVueDataProp']),
new TwigFunction('get_vue_data', [$this, 'getVueData']),
new TwigFunction('vue_store', [$this, 'addVueStore']),
new TwigFunction('get_vue_store', [$this, 'getVueStore']),
new TwigFunction('vue_form', [$this, 'getVueForm']),
];
}

public function getFilters(): array
{
return [
new TwigFilter('vue', [$this, 'addVueDataPropFilter'], ['needs_context' => true]),
];
}

/**
* Add data to vue-instance.
* Effectively this would be similar to using <script>vue.data = Object.assign(vue.data, {key: value})</script>
Expand All @@ -45,6 +54,38 @@ public function addVueData(String $key, $value): void
$this->vueDataStorage->addData($key, $value);
}

/**
* Same as addVueData, but returns the key
*/
public function addVueDataProp(String $key, $value): string
{
$this->vueDataStorage->addData($key, $value);
return $key;
}

public function addVueDataPropFilter($context, $value, ?string $key = null): string
{
// Default behaviour would be same as using {{ vue_prop(key, value) }}
if ($key) {
return $this->addVueDataProp($key, $value);
}
// If there's no key and the value is a string, then treat the value as a key and use null as value.
if (is_string($value)) {
return $this->addVueDataProp($value, null);
}
// if there's no key and the value is an object, then use the key found in context.
if (is_object($value)) {
foreach ($context as $contextKey => $contextValue) {
if ($value === $contextValue) {
return $this->addVueDataProp($contextKey, $value);
}
}
}
// If so far no key could be determined, then generate a random key.
$key = 'vue_prop_' . bin2hex(random_bytes(5));
return $this->addVueDataProp($key, $value);
}

public function getVueData(): string
{
return $this->vueDataStorage->getJson();
Expand Down

0 comments on commit 0b213ac

Please sign in to comment.