ビジュアルエディタ "Kaleflower" が取り扱うデータ形式について説明します。
Kaleflowerで編集したデータは、拡張子 .kflow というファイルに保存されます。
.kflow ファイルは、XMLのサブセットで、独自に定義されたタグによって構成されます。
.kflow ファイルのルートエレメントです。
ドキュメント全体にかかる設定項目を定義します。各設定は、それぞれ <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>
設定項目は次の通りです。
container-query または media-query のいずれかを選択します。省略時は media-query と同じになります。<value>要素をネストして複数設定できます。<value>要素をネストして複数設定できます。設定項目 break-points と color-palettes では、複数の値を定義するために、<value> 要素をネストして定義します。
break-points では name属性 と max-width属性 の組み合わせで定義します。color-palettes では name属性 と color属性 の組み合わせで定義します。コンテンツ内で クラス名 が与えられた要素のスタイルシートを格納します。
コンテンツを格納します。
コンテンツに登録されたアセットデータを格納します。主に、imageフィールドに登録された画像データなどがこれに当たります。
カスタムフィールドを定義します。
カスタムコンポーネントを定義します。
<?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%;
" style--lg="width: 60%;
" style="width: 50%;
color: kf-color-palette("text-background");
background-color: kf-color-palette("text");
">&lt;kflow&gt; &apos;main&apos; "contents" &quot;sample&quot;
&copy;&nbsp;&reg;&trade;&yen;</p>
<p style--md="width: 50%;
" style--sm="width: 100%;">&lt;kflow&gt; main contents sample ©®™</p>
<p style="color: blue;
" style--lg="color: red;" style--sm="color: green;">kflow main contents sample</p>
<custom-component-001 image="{"assetId":"e6fc4809-2ea8-4278-b1af-e6f67ca75d10","upload-file":"C:\\fakepath\\photo001_thumb.jpg","resourceType":"none","webUrl":"https://pickles2.com/"}" 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("clicked!");" target="_slef" onclick="alert('test');
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;
right: 10px;
top: 0px;
">
This is a absolute layer sample.
<div>div inside layer.</div>
</div>
</div>
<custom-component-002/>
</div>
<div style="overflow: auto;
height: auto;
width: auto;
">
<div style="width: 50%;
" style--lg="width: 60%;
" style--md="width: 80%;
" style--sm="width: 100%;
"><img class="test-image-sample" alt="1つめのaltテキスト &amp; &nbsp; &quot; &copy; &trade; &reg;" image="{"assetId":"95a0cd90-0468-4f12-806f-4a13a9327a8b","upload-file":"C:\\fakepath\\photo009_thumb.jpg"}"/><div class="test-div-class-001"/><img alt="2つめのaltテキスト "escape HTML"" image="{"assetId":"1e7b6006-3fb3-4eef-9762-31938013db64","upload-file":"C:\\fakepath\\photo010_thumb.jpg"}" style="width: auto; height: auto;"/><hr/><p>テスト文字列</p><form action="javascript:alert("submited");" onsubmit="alert("submit");"><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>