창작마당

그누보드7 마크업 레이아웃 (Markup Layout)

나인셀즈 2026.08.05 02:23 조회수:342
#팁

그누보드7의 JSON 레이아웃을 마크업으로 작성할 수 있게 해주는 개발자용 모듈입니다.

Markup Layout

수동설치: https://github.com/ninecells/g7-module-markup-layout

그누보드7의 JSON 레이아웃을 HTML, Vue와 비슷한 마크업 문법으로 작성할 수 있게 해주는 개발자용 모듈입니다.

컴포넌트, 상태, 액션, 조건, 반복, Partial, 슬롯, Injection 기능을 그대로 사용하면서 복잡한 JSON 중첩을 줄이고 가독성을 높일 수 있습니다.

그누보드 코어를 직접 수정하지 않고 서비스 컨테이너 바인딩을 통해 기존 레이아웃 관련 서비스와 매니저를 확장하는 방식으로 동작합니다. 레이아웃을 탐색할 때 .g7 파일이 발견되면 기존 JSON 레이아웃 형식으로 컴파일해 등록하며, 기존 .json 레이아웃도 그대로 지원하므로 두 형식을 한 프로젝트에서 함께 사용할 수 있습니다. 이를 통해 코어 업데이트 시 직접 수정한 파일에서 발생할 수 있는 충돌 부담을 줄이면서 레이아웃 작성 방식을 확장할 수 있습니다.

그누보드7의 표준은 아니기에 다른 프로젝트에 권장하기보다는, 그누보드 코어를 직접 수정하지 않고 기능을 확장하는 방법을 살펴볼 수 있는 참고 자료로 봐주시면 좋겠습니다.

<script type="application/json">
{
  "layout_name": "user_todo_index",
  "initLocal": {
    "saving": false,
    "todos": []
  }
}
</script>

<layout>
  <Section class="space-y-4">
    <H2>할 일 목록</H2>

    <Button :disabled="_local.saving" @click="saveTodo({ title: _local.title })">
      저장
    </Button>

    <Div g7-for="(todo, index) in _local.todos" :key="todo.id">
      <Span>{{index + 1}}. {{todo.title}}</Span>
    </Div>

    <P g7-if="_local.todos.length === 0">
      등록된 할 일이 없습니다.
    </P>
  </Section>
</layout>

파일과 레이아웃 최상위

G7 JSON 레이아웃 Markup Layout 0.3.1
레이아웃 JSON 객체 전체 첫 블록의 <script type="application/json">{...}</script> 안에 그대로 작성
"version": "1.0.0" <script> JSON에 그대로 작성
"layout_name": "layout_name" <script> JSON에 그대로 작성
"extends": "parent_layout" <script> JSON에 그대로 작성
"meta": {...} <script> JSON에 그대로 작성
"permissions": [...] <script> JSON에 그대로 작성
"data_sources": [...] <script> JSON에 그대로 작성
"modals": {...} <script> JSON에 그대로 작성하거나 <layout target="modals.name" mode="single" merge="replace"> 사용
"initActions": [...] <script> JSON에 그대로 작성
"init_actions": [...] <script> JSON에 그대로 작성
"defines": {...} <script> JSON에 그대로 작성
"computed": {...} <script> JSON에 그대로 작성
"initLocal": {...} <script> JSON에 그대로 작성
"state": {...} <script> JSON에 그대로 작성
"initGlobal": {...} <script> JSON에 그대로 작성
"initIsolated": {...} <script> JSON에 그대로 작성
"scripts": [...] <script> JSON에 그대로 작성
"warnings": [...] <script> JSON에 그대로 작성
"transition_overlay": true 또는 객체 <script> JSON에 그대로 작성
"errorHandling": {...} <script> JSON에 그대로 작성
"globalHeaders": [...] <script> JSON에 그대로 작성
"named_actions": {...} <script> JSON에 그대로 작성
"components": [...] 속성 없는 <layout>...</layout>
"slots": {"content":[...]} <layout slot="content">...</layout> 또는 <layout name="content">...</layout>
"injections": [...] <layout injection="target_id" position="append_child">...</layout>
"extension_point": "point_name" <script> JSON에 그대로 작성하고 확장 컴포넌트는 <layout>...</layout>에 작성
"target_layout": "layout_name" <script> JSON에 그대로 작성하고 주입 컴포넌트는 <layout injection="target_id">...</layout>에 작성
그 밖의 G7 최상위 필드 <script> JSON에 정확한 필드명으로 그대로 작성
빈 최상위 객체 {} <script type="application/json">{}</script>
레이아웃 파일 하나에 여러 대상 배열·객체 하나의 <script> 뒤에 <layout> 블록을 여러 개 작성

<layout> 대상 지정

G7 JSON 레이아웃 Markup Layout 0.3.1
"components": [...] <layout>...</layout>
"slots": {"name":[...]} <layout slot="name">...</layout>
"slots": {"name":[...]} <layout name="name">...</layout>
최상위 "sectionName": [...] <layout section="sectionName">...</layout>
중첩 경로 "modals":{"help":...} <layout target="modals.help">...</layout>
임의의 점 경로 "a":{"b":{"c":...}} <layout target="a.b.c">...</layout>
대상 값을 컴포넌트 배열로 저장 mode="array" 또는 생략
대상 값을 단일 컴포넌트로 저장 mode="single"
기존 배열 뒤에 추가 merge="append" 또는 생략
기존 값을 교체 merge="replace"
대상이 이미 있으면 오류 merge="error"
단일 대상 교체 <layout target="modals.help" mode="single" merge="replace">...</layout>
{"target_id":"x","position":"append_child","components":[...]} <layout injection="x" position="append_child">...</layout>
injection 기본 위치 "append_child" position 생략
injection "prepend" position="prepend"
injection "append" position="append"
injection "prepend_child" position="prepend_child"
injection "append_child" position="append_child"
injection "replace" position="replace"
injection "inject_props""props": {...} <script> JSON의 injections에 그대로 작성
slot, section, target, injection 중 하나 <layout> 하나에는 네 속성 중 하나만 사용
Partial 레이아웃의 단일 루트 meta.is_partial: true를 작성하고 대상 속성 없는 <layout> 하나에 루트 컴포넌트 하나 작성

컴포넌트 타입과 트리

G7 JSON 레이아웃 Markup Layout 0.3.1
{"type":"basic","name":"A"} <A>
{"type":"basic","name":"Button"} <Button>
{"type":"basic","name":"Checkbox"} <Checkbox>
{"type":"basic","name":"Code"} <Code>
{"type":"basic","name":"Div"} <Div>
{"type":"basic","name":"FileInput"} <FileInput>
{"type":"basic","name":"Form"} <Form>
{"type":"basic","name":"Fragment"} <Fragment>
{"type":"basic","name":"H1"} <H1>
{"type":"basic","name":"H2"} <H2>
{"type":"basic","name":"H3"} <H3>
{"type":"basic","name":"H4"} <H4>
{"type":"basic","name":"Hr"} <Hr>
{"type":"basic","name":"I"} <I>
{"type":"basic","name":"Icon"} <Icon>
{"type":"basic","name":"Img"} <Img>
{"type":"basic","name":"Input"} <Input>
{"type":"basic","name":"Label"} <Label>
{"type":"basic","name":"Li"} <Li>
{"type":"basic","name":"Nav"} <Nav>
{"type":"basic","name":"Ol"} <Ol>
{"type":"basic","name":"Optgroup"} <Optgroup>
{"type":"basic","name":"Option"} <Option>
{"type":"basic","name":"P"} <P>
{"type":"basic","name":"PasswordInput"} <PasswordInput>
{"type":"basic","name":"Pre"} <Pre>
{"type":"basic","name":"Section"} <Section>
{"type":"basic","name":"Select"} <Select>
{"type":"basic","name":"Span"} <Span>
{"type":"basic","name":"Svg"} <Svg>
{"type":"basic","name":"Table"} <Table>
{"type":"basic","name":"Tbody"} <Tbody>
{"type":"basic","name":"Td"} <Td>
{"type":"basic","name":"Textarea"} <Textarea>
{"type":"basic","name":"Tfoot"} <Tfoot>
{"type":"basic","name":"Th"} <Th>
{"type":"basic","name":"Thead"} <Thead>
{"type":"basic","name":"Tr"} <Tr>
{"type":"basic","name":"Ul"} <Ul>
{"type":"basic","name":"UnifiedIcon"} <UnifiedIcon>
{"type":"layout","name":"Container"} <Container>
{"type":"layout","name":"Flex"} <Flex>
{"type":"layout","name":"Grid"} <Grid>
{"type":"layout","name":"SectionLayout"} <SectionLayout>
{"type":"layout","name":"ThreeColumnLayout"} <ThreeColumnLayout>
등록된 그 밖의 대문자 시작 컴포넌트 <ComponentName> — 기본적으로 type:"composite"
명시적 "type":"basic" <ComponentName g7-type="basic">
명시적 "type":"composite" <ComponentName g7-type="composite">
명시적 "type":"layout" <ComponentName g7-type="layout">
명시적 "type":"extension_point" <PointName g7-type="extension_point">
"name":"ComponentName" 태그명 <ComponentName>
"children":[...] 태그 안에 자식 컴포넌트를 중첩
자식이 없는 컴포넌트 <ComponentName />
대문자로 시작하지 않는 컴포넌트명 지원하지 않음
레이아웃 루트의 일반 문자열 지원하지 않음. 컴포넌트 안에 작성
컴포넌트 사이의 XML 주석 <!-- 주석 --> — 컴파일 결과에서 제거
XML 엔티티 문자열 &amp;, &lt;, &gt;, &quot;, &apos; — 디코딩 후 저장
CDATA 텍스트 <![CDATA[...]]> — 컴포넌트 텍스트로 처리
처리 명령 <?...?> — 무시

ID·Key·조건·반복·텍스트

G7 JSON 레이아웃 Markup Layout 0.3.1
"id":"fixed_id" id="fixed_id"
"id":"row_{{item.id}}" id="row_{{item.id}}"
"id":"{{expr}}" :id="expr" 또는 g7-bind:id="expr"
"key":"fixed" g7-key="fixed"
"key":"{{item.id}}" g7-key="{{item.id}}"
"key":"{{item.id}}" :key="item.id" 또는 g7-bind:key="item.id"
"if":"{{expr}}" g7-if="expr" 또는 g7-if="{{expr}}"
"condition":"{{expr}}" g7-condition="expr" 또는 g7-condition="{{expr}}"
"conditions":"{{expr}}" g7-conditions="expr"
"conditions":{"and":[...]} g7-conditions='{"and":[...]}'
"conditions":{"or":[...]} g7-conditions='{"or":[...]}'
"conditions":[{"if":"..."},...] g7-conditions='[{"if":"..."},...]'
"iteration":{"source":"items","item_var":"item"} g7-for="item in items"
"iteration":{"source":"items","item_var":"item"} g7-for="item of items"
"iteration":{"source":"items","item_var":"item","index_var":"index"} g7-for="(item, index) in items"
"iteration":{"source":"items","item_var":"item","index_var":"index"} g7-for="(item, index) of items"
"text":"고정 문구" <P>고정 문구</P>
"text":"{{expr}}" <P>{{expr}}</P>
"text":"고정 문구" <P g7-text="고정 문구" />
"text":"{{expr}}" <P g7-text="{{expr}}" />
텍스트만 있는 컴포넌트 본문 전체가 text로 컴파일
텍스트와 자식 컴포넌트가 섞인 경우 텍스트 부분을 {"type":"basic","name":"Span","text":"..."} 자식으로 컴파일
<Pre> 또는 <Code>의 여러 줄 텍스트 줄바꿈을 유지해 text로 컴파일
"comment":"설명" g7-comment="설명"
G7에 show 필드 없음 g7-show 지원하지 않음. g7-if 사용

정적 Props

G7 JSON 레이아웃 Markup Layout 0.3.1
"props":{"propName":"value"} prop-name="value"
"props":{"disabled":true} disabled 또는 disabled="true"
"props":{"disabled":false} disabled="false"
"props":{"value":null} value="null"
"props":{"count":10} count="10"
"props":{"ratio":1.5} ratio="1.5"
"props":{"options":[1,2,3]} options="[1,2,3]"
"props":{"config":{"a":1}} config='{"a":1}'
"props":{"className":"card"} class="card"
"props":{"htmlFor":"field_id"} for="field_id"
"props":{"data-id":"x"} data-id="x"
"props":{"aria-label":"설명"} aria-label="설명"
"props":{"someProp":"value"} some-prop="value"
정적 prop을 명시적으로 지정 g7-prop:prop-name="value"
"props":{"className":"card"} 명시형 g7-prop:class="card"
"props":{"htmlFor":"field"} 명시형 g7-prop:for="field"
"props":{...} 전체 객체 g7-props='{...}'
"props":{...} 전체 객체 <g7-props>{...}</g7-props>
일반 속성 이름의 kebab-case G7 prop의 camelCase로 변환
aria-*, data-* 속성명 하이픈을 유지
같은 속성의 중복 선언 지원하지 않음

동적 Props 바인딩

G7 JSON 레이아웃 Markup Layout 0.3.1
"props":{"propName":"{{expr}}"} :prop-name="expr" 또는 g7-bind:prop-name="expr"
"props":{"disabled":"{{expr}}"} :disabled="expr" 또는 g7-bind:disabled="expr"
"props":{"loading":"{{expr}}"} :loading="expr" 또는 g7-bind:loading="expr"
"props":{"visible":"{{expr}}"} :visible="expr" 또는 g7-bind:visible="expr"
"props":{"value":"{{expr}}"} :value="expr" 또는 g7-bind:value="expr"
"props":{"checked":"{{expr}}"} :checked="expr" 또는 g7-bind:checked="expr"
"props":{"className":"{{expr}}"} :class="expr" 또는 g7-bind:class="expr"
"props":{"htmlFor":"{{expr}}"} :for="expr" 또는 g7-bind:for="expr"
"props":{"someProp":"{{expr}}"} :some-prop="expr" 또는 g7-bind:some-prop="expr"
이미 감싼 "{{expr}}" :prop="{{expr}}" 또는 g7-bind:prop="{{expr}}"도 동일하게 처리
동적 id :id="expr" 또는 g7-bind:id="expr"props가 아니라 컴포넌트 최상위 id
동적 key :key="expr" 또는 g7-bind:key="expr"props가 아니라 컴포넌트 최상위 key

컴포넌트 최상위 필드

G7 JSON 레이아웃 Markup Layout 0.3.1
임의의 "fieldName": value g7-field:fieldName="value"
최상위 필드 여러 개 g7-fields='{...}'
최상위 필드 여러 개 <g7-fields>{...}</g7-fields>
"data_binding": {...} g7-field:data_binding='{...}' 또는 <g7-fields>{"data_binding":{...}}</g7-fields>
"style": {...} g7-field:style='{...}' 또는 <g7-fields>{"style":{...}}</g7-fields>
"permissions": [...] g7-field:permissions='[...]'
"blur_until_loaded": true g7-field:blur_until_loaded="true"
"blur_until_loaded":"{{expr}}" g7-field:blur_until_loaded="{{expr}}"
"blur_until_loaded":{"enabled":true,"data_sources":[...]} g7-field:blur_until_loaded='{...}'
"dataKey":"form" g7-field:dataKey="form"
"trackChanges":true g7-field:trackChanges="true"
"debounce":300 g7-field:debounce="300"
"autoBinding":false g7-field:autoBinding="false"
"lifecycle":{"onMount":[...],"onUnmount":[...]} g7-field:lifecycle='{...}' 또는 <g7-fields>{"lifecycle":{...}}</g7-fields>
"onComponentEvent":[...] g7-field:onComponentEvent='[...]' 또는 <g7-fields>
"responsive": {...} g7-field:responsive='{...}' 또는 <g7-fields>
"slot":"slot_name" g7-field:slot="slot_name"
"slot":"{{expr}}" g7-field:slot="{{expr}}"
"slotOrder":1 g7-field:slotOrder="1"
"component_layout": {...} g7-field:component_layout='{...}' 또는 <g7-fields>
"expandChildren":[...] g7-field:expandChildren='[...]' 또는 <g7-fields>
"classMap": {...} g7-field:classMap='{...}' 또는 <g7-fields>
"isolatedState": {...} g7-field:isolatedState='{...}' 또는 <g7-fields>
"isolatedScopeId":"scope" g7-field:isolatedScopeId="scope"
"sortable": {...} g7-field:sortable='{...}' 또는 <g7-fields>
"itemTemplate": {...} g7-field:itemTemplate='{...}' 또는 <g7-fields>
"extensionPointProps": {...} g7-field:extensionPointProps='{...}' 또는 <g7-fields>
"extensionPointCallbacks": {...} g7-field:extensionPointCallbacks='{...}' 또는 <g7-fields>
"data_sources":[...] 컴포넌트 필드 g7-field:data_sources='[...]'
"fallback": {...} g7-field:fallback='{...}'
"actions":[...] 직접 지정 <g7-actions>[...]</g7-actions> 또는 <g7-fields>{"actions":[...]}</g7-fields>
"children":[...] 직접 지정 <g7-fields>{"children":[...]}</g7-fields>
G7이 지원하는 그 밖의 컴포넌트 필드 g7-field:정확한필드명="값" 또는 g7-fields / <g7-fields>

표준 이벤트와 액션

G7 JSON 레이아웃 Markup Layout 0.3.1
{"type":"click","handler":"save"} @click="save" 또는 g7-on:click="save"
{"type":"change","handler":"update"} @change="update" 또는 g7-on:change="update"
{"type":"submit","handler":"submitForm"} @submit="submitForm" 또는 g7-on:submit="submitForm"
{"type":"load","handler":"loaded"} @load="loaded" 또는 g7-on:load="loaded"
{"type":"eventName","handler":"handlerName"} @event-name="handlerName" 또는 g7-on:event-name="handlerName"
동적으로 결정되는 "handler":"{{expr}}" @click="{{expr}}" 또는 g7-on:click="{{expr}}"
{"type":"click","actionRef":"actionName"} @click="actionName" 또는 g7-on:click="actionName"named_actions에 같은 이름이 있을 때
{"type":"click","handler":"handlerName"} @click="handlerName" 또는 g7-on:click="handlerName"named_actions에 같은 이름이 없을 때
{"type":"click","handler":"save"} @click="save()" 또는 g7-on:click="save()"
{"type":"click","handler":"save","params":{...}} @click="save({...})" 또는 g7-on:click="save({...})"
{"type":"click","handler":"setState","params":{...}} @click="setState({...})" 또는 g7-on:click="setState({...})"
액션 JSON 객체 @click='{"handler":"save","params":{...}}' 또는 g7-on:click='{...}'
액션 JSON 배열 @click='[{"handler":"first"},{"handler":"second"}]' 또는 g7-on:click='[...]'
액션 JSON에 type·event가 없음 사용한 @event 이름을 type으로 자동 추가
액션 JSON에 자체 "type"이 있음 자체 type을 유지
액션 JSON에 자체 "event"가 있음 자체 event를 유지
"if":"{{expr}}"가 있는 액션 이벤트 JSON 객체의 "if"에 작성
"confirm":"확인 문구"가 있는 액션 이벤트 JSON 객체의 "confirm"에 작성
"params": {...} 핸들러 호출 객체 인자 또는 이벤트 JSON 객체에 작성
"onSuccess": {...} 또는 배열 이벤트 JSON 객체·액션 블록에 그대로 작성
"onError": {...} 또는 배열 이벤트 JSON 객체·액션 블록에 그대로 작성
"resultTo": {...} 이벤트 JSON 객체·액션 블록에 그대로 작성
"conditions": [...] 이벤트 JSON 객체·액션 블록에 그대로 작성
액션의 그 밖의 필드 이벤트 JSON 객체·액션 블록에 그대로 작성

커스텀 콜백과 액션 블록

G7 JSON 레이아웃 Markup Layout 0.3.1
{"type":"click","handler":"save"} <g7-action type="click">{"handler":"save"}</g7-action>
{"event":"onChange","handler":"update"} <g7-action event="onChange">{"handler":"update"}</g7-action>
{"event":"onRowAction",...} <g7-action event="onRowAction">{...}</g7-action>
동일 type의 액션 객체 여러 개 <g7-action type="click">[{...},{...}]</g7-action>
동일 event의 액션 객체 여러 개 <g7-action event="onChange">[{...},{...}]</g7-action>
각 액션에 이미 "type"이 있는 객체·배열 <g7-action>{...}</g7-action> 또는 <g7-action>[...]</g7-action>
"actions":[...] 전체 배열 <g7-actions>[...]</g7-actions>
typeevent를 동시에 가진 <g7-action> 지원하지 않음
표준 이벤트 type="click"처럼 type 사용
컴포넌트 커스텀 콜백 event="onChange"처럼 event 사용

핸들러 호출 인자

G7 JSON 레이아웃 Markup Layout 0.3.1
문자열 param handler({ value: 'text' }) 또는 handler({ value: "text" })
boolean param handler({ enabled: true })
null param handler({ value: null })
정수 param handler({ count: 10 })
실수·지수 param handler({ ratio: 1.5, value: 1e3 })
배열 param handler({ items: [1, 'two', item.id] })
중첩 객체 param handler({ options: { quiet: true, limit: 3 } })
동적 표현식 param "{{item.id}}" handler({ id: item.id })
이미 감싼 동적 표현식 handler({ id: "{{item.id}}" })
복합 표현식 handler({ total: items.reduce((sum, item) => sum + item.price, 0) })
객체·배열의 spread를 포함한 중첩 표현식 해당 객체·배열 전체를 G7 바인딩 표현식으로 보존
params가 없는 핸들러 handler()
params가 있는 핸들러 객체 인자 하나만 허용: handler({...})
숫자·문자열 등 객체가 아닌 단일 인자 지원하지 않음
open = true, count++ 같은 임의 JavaScript 문장 지원하지 않음

Named Actions

G7 JSON 레이아웃 Markup Layout 0.3.1
"named_actions":{"save":{...}} <script> JSON에 그대로 작성
{"type":"click","actionRef":"save"} @click="save" 또는 g7-on:click="save"
{"type":"click","actionRef":"toggleDetails"} @click="toggleDetails" 또는 g7-on:click="toggleDetails"
임의의 named action 이름 개발자가 정한 이름을 그대로 사용
named action 내부의 "handler":"setState" <script> JSON에 그대로 작성
named action 내부의 params, if, confirm, onSuccess, onError <script> JSON에 그대로 작성

Partial

G7 JSON 레이아웃 Markup Layout 0.3.1
{"partial":"partials/card"} <Partial src="partials/card" />
{"partial":"partials/card"} <Partial path="partials/card" />
{"partial":"partials/card"} <Partial ref="partials/card" />
{"partial":"partials/card"} <g7-partial src="partials/card" />
Partial 참조에 추가 최상위 필드 <Partial src="..." g7-field:fieldName="value" />
Partial 참조의 "merge":"replace" <Partial src="..." g7-field:merge="replace" />
Partial 소스의 "meta":{"is_partial":true} <script> JSON에 meta.is_partial: true 작성
Partial 소스의 루트 컴포넌트 대상 속성 없는 <layout> 안에 루트 컴포넌트 하나 작성
Partial 소스에 여러 <layout> 블록 지원하지 않음
Partial 소스에 여러 루트 컴포넌트 지원하지 않음
Partial 참조에 자식 컴포넌트 지원하지 않음
확장자 없는 "partial":"partials/card" .g7, .json 후보를 탐색
명시적 .g7 Partial <Partial src="partials/card.g7" />
명시적 .json Partial <Partial src="partials/card.json" />

속성값 변환

G7 JSON 레이아웃 Markup Layout 0.3.1
true 값 없는 속성 또는 "true"
false "false"
null "null"
정수 숫자 문자열
실수·지수 숫자 문자열
JSON 객체 유효한 JSON 객체 문자열
JSON 배열 유효한 JSON 배열 문자열
"{{expr}}" 그대로 유지
그 밖의 값 문자열로 유지
동적 바인딩의 expr 자동으로 "{{expr}}"로 변환
동적 바인딩의 "{{expr}}" 중복으로 감싸지 않고 그대로 유지
g7-if, g7-conditionexpr 자동으로 "{{expr}}"로 변환
g7-conditions의 객체·배열 JSON으로 디코딩해 그대로 저장
g7-conditions의 일반 표현식 "{{expr}}"로 변환
g7-for source의 "{{expr}}" 바깥 {{ }}를 제거해 iteration.source에 저장
g7-fields, g7-props, 액션 블록 엄격한 JSON 문법 사용
이벤트의 handler({...}) 작은 JavaScript 유사 객체 문법 사용 가능

0.3.1 호환 표기

G7 JSON 레이아웃 Markup Layout 0.3.1
{"type":"click","handler":"save"} 또는 actionRef g7-on-click="save"
{"type":"click","handler":"save","params":{...}} g7-on-click-handler="save" + g7-on-click-params='{...}'
액션 "if":"{{expr}}" g7-on-click-if="expr"
액션 "confirm":"문구" g7-on-click-confirm="문구"
{"type":"click","actionRef":"save"} g7-action-ref-click="save"
"props":{"disabled":"{{expr}}"} g7-bind-disabled="expr"
"props":{"propName":"{{expr}}"} g7-bind-prop-name="expr"
"props":{"propName":"value"} g7-prop-prop-name="value"
컴포넌트 최상위 "field_name": value g7-field-field-name="value"
컴포넌트 최상위 필드 객체 g7-config='{...}'
컴포넌트 최상위 필드 객체 g7-json='{...}'
컴포넌트 최상위 필드 객체 <g7-config>{...}</g7-config>
<g7-action event="click"> event 값이 onXxx 형식이 아니면 표준 type:"click"로 처리
6개 댓글
0 / 2,000자
정정홍
앗, 안 그래도 HTML 문법 도입을 개발 중이었는데 한발 먼저 내주셨네요 ㅎㅎ 코어 쪽에서도 같은 방향으로 진행 중이고 7.1.0 포함을 목표로 하고 있습니다. 먼저 만들어 공개해 주신 덕에 생각해 볼 지점이 많았습니다. 감사합니다.
나인셀즈
처음에는 모듈 공부로 시작했는데 만들다 보니 내가 지금 뭘 하고 있지? 싶은 순간도 잠깐 있었습니다. ㅎㅎ 그누보드7이 Laravel 기반이라 개발하는 재미가 크고, 코드를 살펴볼수록 인상적인 부분도 자주 발견하게 됩니다. 앞으로 그누보드7이 모던 PHP에 대한 인식을 바꾸는 대표적인 사례가 되면 좋겠습니다.
Glitter Gim
분류 태그가 #모듈에서 #팁으로 변경된 것이 확인되었습니다. 제 문제 제기는 여기서 마무리하겠습니다.
나인셀즈
오잉.. 변경하지 않았고 애당초 팁으로 올리기는 했습니다. 문제제기는 환영합니다.
Glitter Gim
직접 설치해 보았지만, 아직은 일반 G7 템플릿 개발자가 바로 사용할 수 있는 단계는 아니라는 인상을 받았습니다. 새로운 문법인 만큼 처음부터 따라 할 수 있는 튜토리얼과 실전 예제가 보강되면 좋겠습니다. 현재 문서만으로는 기존 JSON 대신 이 문법을 선택해야 할 이유나 장점이 명확하게 전달되지 않는군요. 그래서 현재로서는 일반적인 기능(모듈/플러그인/테마)이라기 보다는 연구 또는 실험 성격의 결과물에 더 가깝다는 생각이 듭니다.
나인셀즈
"JSON 레이아웃"이 "마크업 레이아웃"에서는 어떻게 표현되는지, 만들던 당시 뽑아놨던 표를 이 글 하단에 추가했습니다. 이 모듈은 그누보드 코어 파일을 직접 수정하지는 않지만, 서비스 컨테이너 바인딩을 통해 레이아웃 관련 핵심 서비스를 동적으로 대체하는 구조입니다. 표준적인 사용 방식이라고 보기는 어렵고, 코어의 내부 구조가 변경되면 영향을 받을 수 있기 때문에 일반적인 사용을 권장하기보다는 코어를 직접 수정하지 않고 기능을 확장한 하나의 구현 사례로 참고해 주시면 좋겠습니다.

다른 창작물 살펴보기