如何在Laravel中从XML构建表单

6

更新:
我知道如何解析XML,但不确定在架构中的具体位置,请参见下面定义的问题。
欢迎任何建议!


在进入Laravel时,我尝试从XML文件构建表单。

问题:

  1. 如何将XML中的数据传递到视图中?
  2. 在哪里构建该表单-在重复性方面,我更喜欢创建一次表单,并在创建、编辑和查看时使用它
  3. 验证-我希望尽可能多地重用它

XML:foods_form.xml(简化):

<form>
    <field id="1" name="cheese" label="favorite cheese?" type="radio" req="1" filter="int">
        <option id="1" value="1">Camembert</option>
        <option id="2" value="3">Gouda</option>
    </field>
    <field id="2" name="beer" label="favorite beer?" type="text" req="1" filter="str" />
</form>

视图:app/views/create.blade.php:

@extends('layout')
@section('content')

<form action="{{ action('FormsController@handleCreate') }}" method="post" role="form">

    @foreach ($fields as $field)
        <label for="{{ $field->name }}">{{ $field->label }}</label>

        @if ($field->type == 'text')
            <input type="text" name="{{ $field->name }}" />
        @else
            @foreach ($field->option as $option)
                <input type="radio" name="{{ $field->name }}" value="{{ $option }}" />
            @endforeach
        @endif
    @endforeach    

    <input type="submit" value="Create" />
    <a href="{{ action('FormsController@index') }}">Cancel</a>
</form>
@stop

控制器: app/controllers/FormsController.php:

class TestsController extends BaseController {

    public function index() {
        // return some view
    }

    public function create() {
        return View::make('create');
    }

    public function handleCreate() {
        // validation according to XML
        // save to database if valid || return to form if not valid
    }
}
3个回答

5

Laravel无法通过XML创建表单。

您需要使用像SimpleXML这样的库来解析您的XML:在php.net上找到一些文档这里

从创建一个SimpleXMLElement开始:

$xml = new SimpleXMLElement('../path/to/your/file/foods_form.xml', 0, true);

现在您可以使用$xml对象生成表单,遵循XML格式(转储$xml对象以了解结构)。
只需将您的对象放入视图中即可直接使用。
要验证您的表单,可以使用Laravel的Validation链接到文档

好的,我可以解析这个文件。但是将这个逻辑编码到视图中似乎不太符合MVC的风格。你有什么想法吗? - michi
创建一个类来解析 $xml 为 HTML 表单,并通过构造函数将其注入到您的控制器中?然后您的控制器可以执行以下操作:$xml = new SimpleXMLElement('../path/to/forms.xml'); $html = $this->xml_form_parser->parseToHtml($xml); - patricksayshi

1

我还没有找到一个友好的XSL MVC。

我的做法(非常喜欢在视图中使用XSL)

最终页面将有3个模块,比如说:

我的视图只包含

// I don't know how you simply echo a variable from "yet another framework"
// but this is the only thing you need to do from the view
echo $someModule;
echo $otherModule;
echo $lastModule;

我的控制器将有3个额外的依赖项注入来包含我需要执行的任何逻辑。并使用最简单的类来应用我的xsl。
<?php
class SomeController extends SomeMvcController {

    private $someModuleLogic;
    private $otherModuleLogic;
    private $lastModuleLogic;
    private $xslTransformer;


    public function __construct( XslTransformer $xslTransformer, $someModuleLogic, $otherModuleLogic, $lastModuleLogic ) {
        $this->someModuleLogic  = $someModuleLogic;
        $this->otherModuleLogic = $otherModuleLogic;
        $this->lastModuleLogic  = $lastModuleLogic;

        parent::__construct();
        $this->xslTransformer = $xslTransformer;
    }


    public function someAction() {

        /**
         * doStuff functions will take your parameters like get, post etc and return a DomDocument object
         * which can be programmatically calculated via PHP or generated by reading an XML file (or xml from any buffer)
         */
        $someModule  = $this->xslTransformer->transform(
            'myViews/modules/someModule.xsl',
            $this->someModeuleLogic->doStuff()
    );
        $otherModule = $this->xslTransformer->transform(
            'myViews/modules/otherModule.xsl',
            $this->otherModeuleLogic->doStuff()
    );
        $lastModule  = $this->xslTransformer->transform(
            'myViews/modules/lastModule.xsl',
            $this->lastModeuleLogic->doStuff()
    );        }
}



class XslTransformer {

    public function transform( $xslLocation, DOMDocument $domDocument ) {
        $xslDocument = new DOMDocument();
        $xslDocument->load( $xslLocation );

        $xsltProcessor = new XSLTProcessor();
        $xsltProcessor->importStylesheet( $xslDocument );

        $document                     = $xsltProcessor->transformToDoc( $domDocument );
        $document->encoding           = 'UTF-8';
        $document->formatOutput       = true;
        $document->preserveWhiteSpace = false;

        return $document;
    }
}

这样可以使我的视图/控制器非常小且简单,没有任何逻辑。一切都在注入的类中完成,我可以将其分成小而简单的部分。

谢谢,我对XSL还很陌生,一定会去了解的。 - michi

0
以下是一个开始,你可以构建这样的类来处理XML到HTML表单转换。
<?php

class XmlToHtmlFormConverter {


    public function buildFormContent($filename)
    {
        $xml_fields = new SimpleXmlElement($filename, 0, true);
        $html = '';

        foreach ($xml_fields as $field) {
            $attributes = $field->attributes();
            $html .= '<label for="'.$attributes['name'].'">'.$attributes['label'].'</label>'.PHP_EOL;

            if ('text' == $attributes['type']) {
                $html .= '<input type="text" name="'.$attributes['name'].'" />'.PHP_EOL;
            } else {
                $html .= $this->buildOptionInputs($field);
            }
        }

        return $html;
    }


    protected function buildOptionInputs($field)
    {
        $html = '';
        $attributes = $field->attributes();
        foreach ($field->option as $option) {
            $html .= '<input type="radio" name="'.$attributes['name'].'" value="'.$option.'" />'.PHP_EOL;
        }
        return $html;
    }
}

// Uncomment below to actually see the output, this works with your xml file.
// $converter = new XmlToHtmlFormConverter;
// echo $converter->buildFormContent('form.xml');

正如之前的答案所述,您可以将此类注入到控制器构造函数中。如果您想要更高级一些,可以创建一个接口并注入它,然后使用App::bind('SomeInterface', 'SomeImplementation')将您的实现绑定到该接口,但为了保持简单,您可以直接注入该类。
控制器:
class TestsController extends BaseController {

    protected $xml_to_html_form_converter;


    public function __construct(XmlToHtmlFormConverter $xml_to_html_form_converter)
    {
        $this->xml_to_html_form_converter = $xml_to_html_form_converter;
    }


    public function index() {
        // return some view
    }


    public function create() {
        $xml_file_path = 'some/path/xmlfile.xml';
        return View::make('create')->with(array(
            'form_content' => $this->xml_to_html_form_converter->buildFormContent($xml_file_path);
        ));
    }


    public function handleCreate() {
        // do your validations like you would with any html form
    }
}

然后你的视图将会是这样...

@extends('layout')
@section('content')

<form action="{{ action('FormsController@handleCreate') }}" method="post" role="form">

    {{ $form_content }}

    <input type="submit" value="Create" />
    <a href="{{ action('FormsController@index') }}">Cancel</a>
</form>
@stop

谢谢,这非常有帮助! - michi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接