ちょっと修正しました、これで関数を指定できるので実行時に親のレイアウトを決定できるとおもいます。
(defclass layout () ((parent-layout :initform nil :initarg :parent :accessor parent) (layout-func :initform (error "You must specitic layout function") :initarg :layout :accessor layout))) (defmacro render (contents) `(markup:raw ,contents)) (defmacro deflayout (name parent place-holders &body body) `(setf ,name (make-instance 'layout :parent ,parent :layout (lambda ,place-holders ,(if (null parent) `(markup:markup ,@body) `(with-layout ,parent (markup:markup ,@body))))))) (defmacro with-layout (layout-name &rest args) `(if (null ,layout-name) (error "With-layout: get nil") (if (functionp ,layout-name) (let ((result (funcall ,layout-name))) (if (null result) (error "With-layout: get nil") (funcall (layout result) ,@args))) (funcall (layout ,layout-name) ,@args)))) (deflayout app-main nil (main-contents) (:html (:header (:title "App-main")) (:body (render main-contents) (:hr) "Footer"))) (deflayout in-header app-main (str) (:h1 (render str))) (defvar *parent* "fuge") (setf *parent* "fuga") (deflayout in-hader2 (lambda () (if (equal *parent* "fuga") app-main in-header)) (str) (:h2 str))