Pickles 2

kflowファイルの形式

ビジュアルエディタ "Kaleflower" が取り扱うデータ形式について説明します。

概要

Kaleflowerで編集したデータは、拡張子 .kflow というファイルに保存されます。

.kflow ファイルは、XMLのサブセットで、独自に定義されたタグによって構成されます。

エレメント

<kflow>

.kflow ファイルのルートエレメントです。

<configs> セクション

ドキュメント全体にかかる設定項目を定義します。各設定は、それぞれ <config> 要素によって定義します。

<config>

設定項目を定義します。name属性に設定名、value属性に設定値を格納します。

<?xml version="1.0" encoding="UTF-8"?>
<kflow>
    <configs>
        <config name="id" value="kf1928bb222858994f"/>
        <config name="module-name-prefix" value="cont-"/>
        <config name="module-name" value="test"/>
        <config name="break-point-query-type" value="container-query"/>
        <config name="break-points">
            <value name="lg" max-width="1400"/>
            <value name="md" max-width="800"/>
            <value name="sm" max-width="480"/>
        </config>
        <config name="color-palettes">
            <value name="key" color="#fff"/>
            <value name="sub" color="#ddd"/>
            <value name="text" color="#333"/>
            <value name="text-background" color="#eee"/>
        </config>
    </configs>

    <!-- ・・・省略・・・ -->
</kflow>

設定項目は次の通りです。

  • id: ドキュメントのIDです。
  • module-name-prefix: モジュール名の接頭辞を設定します。ここに設定がある場合、出力時にすべてのクラス名にこの接頭辞が自動的に与えられます。
  • module-name: モジュール名です。ここに設定がある場合、ルートエレメントをこのクラス名とし、その他のすべてのクラスを子要素として、出力時に自動的に命名されます。
  • break-point-query-type: container-query または media-query のいずれかを選択します。省略時は media-query と同じになります。
  • break-points: ブレイクポイントを設定します。 <value>要素をネストして複数設定できます。
  • color-palettes: カラーパレットを設定します。 <value>要素をネストして複数設定できます。

<value>

設定項目 break-pointscolor-palettes では、複数の値を定義するために、<value> 要素をネストして定義します。

  • break-points では name属性 と max-width属性 の組み合わせで定義します。
  • color-palettes では name属性 と color属性 の組み合わせで定義します。

<styles> セクション

コンテンツ内で クラス名 が与えられた要素のスタイルシートを格納します。

<contents> セクション

コンテンツを格納します。

<assets> セクション

コンテンツに登録されたアセットデータを格納します。主に、imageフィールドに登録された画像データなどがこれに当たります。

<fields> セクション

カスタムフィールドを定義します。

<components> セクション

カスタムコンポーネントを定義します。

データサンプル

<?xml version="1.0" encoding="UTF-8"?>
<kflow>
    <configs>
        <config name="id" value="kf1928bb222858994f"/>
        <config name="module-name-prefix" value="cont-"/>
        <config name="module-name" value="test"/>
        <config name="break-point-query-type" value="container-query"/>
        <config name="break-points">
            <value name="lg" max-width="1400"/>
            <value name="md" max-width="800"/>
            <value name="sm" max-width="480"/>
        </config>
        <config name="color-palettes">
            <value name="key" color="#fff"/>
            <value name="sub" color="#ddd"/>
            <value name="text" color="#333"/>
            <value name="text-background" color="#eee"/>
        </config>
    </configs>
    <styles>
        <style>
            html, body {
                background-color: #f7f7f7;
                color: #333;
            }
            a {
                color: #00d;
            }
            a:hover {
                color: #33f;
            }
        </style>
        <style class="test-image-sample">
            width: 80%; height: auto; border: 1px solid #000;
            border-radius: 5px;
            overflow: hidden;
            display: inline-block;
            line-height: 1;
            <media break-point="lg"/>
            <media break-point="md"></media>
            <media break-point="sm"/>
        </style>
        <style class="paragraph">
            margin: 1em 0;
            <media break-point="lg"/>
            <media break-point="md"/>
            <media break-point="sm"/>
        </style>
        <style class="test-div-class-001">
            width: 110px;
            height: 280px;
            color: #000;
            <media break-point="lg">
                color: #00f;
                width: 60%;
            </media>
            <media break-point="md">color: #0f0; width: 80%;</media>
            <media break-point="sm">color: #f00; width: 100%;</media>
        </style>
        <style class="flex-sample">
            display: flex;
            flex-direction: row;
            gap: 20px;
            padding: 20px;
            <media break-point="lg">
                gap: 15px;
                padding: 15px;
            </media>
            <media break-point="md">
                display: flex;
                flex-direction: column;
                gap: 10px;
                padding: 10px;
            </media>
            <media break-point="sm">
                gap: 5px;
                padding: 5px;
            </media>
        </style>
        <style class="heading"><media break-point="lg"/><media break-point="md"/><media break-point="sm"/></style>
    </styles>
    <contents>
        <content><div>
    <h1 class="heading">This is a test page of Kaleflow</h1><p style--sm="width: 100%;" style--md="width: 80%;&#xA;" style--lg="width: 60%;&#xA;" style="width: 50%;&#xA;color: kf-color-palette(&quot;text-background&quot;);&#xA;background-color: kf-color-palette(&quot;text&quot;);&#xA;">&amp;lt;kflow&amp;gt; &amp;apos;main&amp;apos; "contents" &amp;quot;sample&amp;quot;
&amp;copy;&amp;nbsp;&amp;reg;&amp;trade;&amp;yen;</p>
    <p style--md="width: 50%;&#xA;" style--sm="width: 100%;">&amp;lt;kflow&amp;gt; main contents sample ©®™</p>
    <p style="color: blue;&#xA;" style--lg="color: red;" style--sm="color: green;">kflow main contents sample</p>
    <custom-component-001 image="{&quot;assetId&quot;:&quot;e6fc4809-2ea8-4278-b1af-e6f67ca75d10&quot;,&quot;upload-file&quot;:&quot;C:\\fakepath\\photo001_thumb.jpg&quot;,&quot;resourceType&quot;:&quot;none&quot;,&quot;webUrl&quot;:&quot;https://pickles2.com/&quot;}" style="width: 100%;">
        <div>inner contents.</div>
        <custom-component-002/>
    </custom-component-001>
    <div class="flex-sample">
        <div>Flex item 001</div>
        <div>Flex item 002</div>
        <div>Flex item <unknown-element>(unknown)</unknown-element><a href="javascript:alert(&quot;clicked!&quot;);" target="_slef" onclick="alert('test');&#xA;return false;">Link: 003</a></div>
    </div>
    <div style="position: relative;">
        <div>This is a div item 01.</div>
        <div>This is a div item 02.</div>
        <div style="position: absolute;&#xA;right: 10px;&#xA;top: 0px;&#xA;">
            This is a absolute layer sample.
            <div>div inside layer.</div>
        </div>
    </div>
    <custom-component-002/>
</div>
<div style="overflow: auto;&#xA;height: auto;&#xA;width: auto;&#xA;">
    <div style="width: 50%;&#xA;" style--lg="width: 60%;&#xA;" style--md="width: 80%;&#xA;" style--sm="width: 100%;&#xA;"><img class="test-image-sample" alt="1つめのaltテキスト &amp;amp; &amp;nbsp; &amp;quot; &amp;copy; &amp;trade; &amp;reg;" image="{&quot;assetId&quot;:&quot;95a0cd90-0468-4f12-806f-4a13a9327a8b&quot;,&quot;upload-file&quot;:&quot;C:\\fakepath\\photo009_thumb.jpg&quot;}"/><div class="test-div-class-001"/><img alt="2つめのaltテキスト &quot;escape HTML&quot;" image="{&quot;assetId&quot;:&quot;1e7b6006-3fb3-4eef-9762-31938013db64&quot;,&quot;upload-file&quot;:&quot;C:\\fakepath\\photo010_thumb.jpg&quot;}" style="width: auto; height: auto;"/><hr/><p>テスト文字列</p><form action="javascript:alert(&quot;submited&quot;);" onsubmit="alert(&quot;submit&quot;);"><div><button type="button">submit</button></div></form><div>
        <p class="paragraph">kflow</p>
    </div></div>
</div></content>
        <content name="sidebar"><div>
    <p>Sidebar Contents.</p>
</div></content>
    </contents>
    <assets>
        <asset id="95a0cd90-0468-4f12-806f-4a13a9327a8b" ext="jpg" size="2937" width="120" height="90" is-private-material="false" public-filename="95a0cd90-0468-4f12-806f-4a13a9327a8b.jpg" field="" field-note="" base64="/9j/4QAYRXhpZgAASUkqAAgAAAAAAA......DL+bKpTi7+5//Z" />
        <asset id="1e7b6006-3fb3-4eef-9762-31938013db64" ext="jpg" size="3300" width="120" height="90" is-private-material="false" public-filename="1e7b6006-3fb3-4eef-9762-31938013db64.jpg" field="" field-note="" base64="/9j/4QAYRXhpZgAASUkqAAgAAAAAAA......+XxqVGslqQf/2Q==" />
        <asset id="e6fc4809-2ea8-4278-b1af-e6f67ca75d10" ext="jpg" size="2308" width="120" height="90" is-private-material="false" public-filename="e6fc4809-2ea8-4278-b1af-e6f67ca75d10.jpg" field="" field-note="" base64="/9j/4QAYRXhpZgAASUkqAAgAAAAAAA......x+1y+SS3wzy//9k=" />
    </assets>
    <fields>
        <field type="custom-field" format="plain">
            <editor><![CDATA[<div class="test-field-text-editor">
                    <div class="test-field-text-editor__inner">
                        <textarea name="_" class="px2-input">{{ _ }}</textarea>
                        <div class="test-field-text-editor__color-sample"></div>
                    </div>
                </div>]]></editor>
            <style><![CDATA[
            .test-field-text-editor {
                &__color-sample {
                    height: 5px;
                }
                textarea {
                    width: 100%;
                }
            }
            ]]></style>
            <style appearance="light"><![CDATA[
            .test-field-text-editor {
                &__color-sample {
                    background-color: #666666;
                }
            }
            ]]></style>
            <style appearance="dark"><![CDATA[
            .test-field-text-editor {
                &__color-sample {
                    background-color: #f0f0f0;
                }
            }
            ]]></style>
            <script function="onload"><![CDATA[function(dom, fieldHelper){
                    console.log('custom-field: onload function:', dom, fieldHelper);
                    return;
                }]]></script>
        </field>
    </fields>
    <components>
        <component name="custom-component-001" is-void-element="false" can-set-css="true" can-set-class="true" can-set-width="true" can-set-height="true" can-set-contents-direction="false" can-set-scrollable="false" can-be-layer="false" can-set-onclick-event="false" can-set-onsubmit-event="false">
            <fields>
                <field type="image" name="image" label="Image"/>
                <field type="custom-field" name="custom-field" label="custom-field"/>
            </fields>
            <style>
            .custom-component-001 {
                background-color: #e9e9e9;
                padding: 20px;
                margin: 1em 0;
                box-sizing: border-box;
            }
            </style>
            <template><![CDATA[
{% set image = json_decode(attributes.image) %}
<div class="custom-component-001 {{ attributes.class }}">
    <div class="custom-component-001__content">
        <p>custom component 001</p>
        <p>({{_ENV.mode}}, {{_ENV.lang}}, {{_ENV.extra.sample}}, {% verbatim %}{{sample}}{% endverbatim %})</p>
        <img src="{{ assets[image.assetId].path }}" width="{{ assets[image.assetId].width }}" height="{{ assets[image.assetId].height }}" alt="" />
        <div class="custom-component-001__content-inner">
            {{ innerHTML | raw }}
        </div>
    </div>
</div>]]></template>
</component>
        <component name="custom-component-002" label="custom-component-002" is-void-element="true" can-set-css="false" can-set-class="false" can-set-width="false" can-set-height="false" can-set-contents-direction="false" can-set-scrollable="false" can-be-layer="false" can-set-onclick-event="false" can-set-onsubmit-event="false">
            <style>
            .custom-component-002 {
                background-color: #ddd;
                padding: 20px;
                margin: 1em 0;
                box-sizing: border-box;
            }
            </style>

            <template><![CDATA[<div class="custom-component-002">
    <div class="custom-component-002__content">
        <div class="custom-component-002__content-inner">
            <p>custom-component-002 ({{_ENV.mode}}, {{_ENV.lang}}, {{_ENV.extra.sample}}, {% verbatim %}{{sample}}{% endverbatim %})</p>
        </div>
    </div>
</div>]]></template>
</component>
    </components>
</kflow>