2011-10-31 2 views
1

나는 코드를 짧고 깨끗하게 유지하는 cgicc로 시작하고 있습니다. 하지만 지금은 고군분투하고 있습니다. 나는 이런 식으로하고 싶다 :cgicc : 동일한 요소의 다중 레벨

<ul> 
    <li> 
    <a href="#" ><span>Main 1</span></a> 
    <ul> 
     <li><a href="ref1-1" ><span>Sub 1</span></a></li> 
     <li><a href="ref1-2" ><span>Sub 2</span></a></li> 
     <li><a href="ref1-3" ><span>Sub 3</span></a></li> 
    </ul> 
    </li> 
    <li> 
    <a href="#" ><span>Main 2</span></a> 
    <ul> 
     <li><a href="ref2-1" ><span>Sub 1</span></a></li> 
     <li><a href="ref2-2" ><span>Sub 2</span></a></li> 
     <li><a href="ref2-3" ><span>Sub 3</span></a></li> 
    </ul> 
    </li> 
</ul> 

내부 블록이 너무 커서 호출을 결합하고 싶지 않다. 이 같은 내 첫 atttempt (내가 잘 코딩 희망) :

cout << ul() << endl; 
    cout << li() << endl; 
    cout << a("Main 1").set("href", "#") << endl; 
    cout << ul() << endl; // <-- must fail here! 
     cout << li(a("Sub 1").set("href", "ref1-1")) << endl; 
     cout << li(a("Sub 2").set("href", "ref1-2")) << endl; 
     cout << li(a("Sub 3").set("href", "ref1-3")) << endl; 
    cout << ul() << endl; 
    cout << li() << endl; 
    cout << li() << endl; 
    cout << a("Main 2").set("href", "#") << endl; 
    cout << ul() << endl; 
     cout << li(a("Sub 1").set("href", "ref2-1")) << endl; 
     cout << li(a("Sub 2").set("href", "ref2-2")) << endl; 
     cout << li(a("Sub 3").set("href", "ref2-3")) << endl; 
    cout << ul() << endl; 
    cout << li() << endl; 
cout << ul() << endl; 

문제가 < UL>과 < 리> 등 지금과 같은 요소에 대한 부울 상태, 가장 좋은 방법은 스마트 솔루션이 처리하는 것입니다 이? - 앤디

편집 : 내 새로운 솔루션 : 추가 요소 클래스 "간단한": 나는 멤버 함수를 사용할 수 있습니다

#include <cgicc/HTMLElement.h> 
#include <cgicc/HTMLAttributeList.h> 

template<class Tag> 
class HTMLSimpleElement : public cgicc::HTMLElement 
{ 
public: 
    HTMLSimpleElement() : HTMLElement(0, 0, 0, EElementType(-1)) 
    {} 

    HTMLSimpleElement(const cgicc::HTMLAttributeList& attributes) : HTMLElement(&attributes, 0, 0, EElementType(-1)) 
    {} 

    virtual ~HTMLSimpleElement() {} 

    virtual inline HTMLElement* clone() const 
    { return new HTMLSimpleElement<Tag>(*this); } 

    virtual inline const char* getName() const 
    { return Tag::getName(); } 

    virtual void render(std::ostream& out) const 
    { 
    const cgicc::HTMLAttributeList* attributes = getAttributes(); 

    out << '<' << getName(); 

    if (attributes != NULL) 
    { 
     out << ' '; 
     attributes->render(out); 
    } 

    out << ">"; 
    } 
}; 

#define TAG(name, tag) \ 
class name##Tag \ 
{ public: inline static const char* getName() { return tag; } } 

#define SIMPLE_ELEMENT(name, tag) \ 
TAG(name, tag); typedef HTMLSimpleElement<name##Tag> name 

SIMPLE_ELEMENT (divB, "div"); 
SIMPLE_ELEMENT (divE, "/div"); 

// and so on... 

이 방법은 BEGIN 및 END 태그를 완벽하게 제어 할 수 있습니다. 다른 사람, 더 똑똑한 솔루션?

+0

다음과 같은 방법으로 해결할 수 있습니다. 내 BOOLEAN_ELEMENT를 (를) 정의하는 것 : BOOLEAN_ELEMENT (ul1, "ul"); BOOLEAN_ELEMENT (ul2, "ul"); 등등. 그런 다음 관련 레벨에서 번호가 매겨진 모든 것을 사용합니다. 다른 아이디어? – Andi

답변

2

이것은 고대의 일종이며, 아마도 당신의 답을 발견했을 것입니다. 그러나 그들은 같은 이슈가 있다면 누군가에게 도움이 될 수 있습니다.

두 번째 코드 블록이 잘못되었습니다. cgicc를 사용하여 태그를 추출하면 포함 된 하위 태그를 포함한 전체 태그가 출력됩니다. 포함 된 어린이가 없으면 국가는 암기되어 각 건축물과 교체됩니다. 즉, 이들을 쌓으려면 트리로 어셈블하는 객체를 사용해야합니다. 간단한 예를 들어 이 짧아 원하는 출력 걸릴 :

:

cout << ul() << endl; 
    cout << li() << endl; 
    cout << a("Main 1").set("href", "#") << endl; 
    cout << ul() << endl; // <-- must fail here! 
     cout << li(a("Sub 1").set("href", "ref1-1")) << endl; 
     cout << li(a("Sub 2").set("href", "ref1-2")) << endl; 
     cout << li(a("Sub 3").set("href", "ref1-3")) << endl; 
    cout << ul() << endl; 
    cout << li() << endl; 
cout << ul() << endl; 

당신은 올바른 HTML없는이 혼란을 얻을 것이다 : 당신은 같은 cgicc 코드를하려고하면

<ul> 
    <li> 
    <a href="#" ><span>Main 1</span></a> 
    <ul> 
     <li><a href="ref1-1" ><span>Sub 1</span></a></li> 
     <li><a href="ref1-2" ><span>Sub 2</span></a></li> 
     <li><a href="ref1-3" ><span>Sub 3</span></a></li> 
    </ul> 
    </li> 
</ul> 

<ul> 
<li> 
<a href="#" >Main 1</a> 
</ul> 
<li><a href="ref1-1" >Sub 1</a></li> 
<li><a href="ref1-2" >Sub 2</a></li> 
<li><a href="ref1-3" >Sub 3</a></li> 
<ul> 
</li> 
</ul> 

페이지를 빌드하는 데 사용하는 개체를 추적하여 개체 지향적 인 방식으로 처리해야합니다 (예 : 포인터가 새 adde를 추적합니다. 어린이들에게 불필요한 복사를 피할 것입니다. 포인터없이, 당신은) 올바른 순서로 태그를 추가해야합니다 :

ul* outerList = new ul(); 
li* outerItem = new li(); 
ul* innerList = new ul(); 

outerList->add(outerItem); 
outerItem->add(a(span("Main 1")).set("href", "#")); 
outerItem->add(innerList); 
innerList->add(li(a(span("Sub 1")).set("href", "ref1-1"))); 
innerList->add(li(a(span("Sub 2")).set("href", "ref1-2"))); 
innerList->add(li(a(span("Sub 3")).set("href", "ref1-3"))); 

cout << *outerList << endl; 

또한 생성자를 사용하여 즉시이를 구축하고 추가 방법을 설정할 수 있습니다

cout << ul(li().add(a(span("Main 1")).set("href", "#")).add(ul().add(li(a(span("Sub 1")).set("href", "ref1-1"))).add(li(a(span("Sub 2")).set("href", "ref1-2"))).add(li(a(span("Sub 3")).set("href", "ref1-3"))))) << endl; 

이것은을 논쟁의 여지가 덜 분명하고, 따르기가 더 어려우며, 디버그하기가 어렵고, 실수를하기 쉽습니다. 당신은 줄 바꿈과 들여 쓰기로 그것을 완화 할 수 있을지 모르지만, 얼마나 도움이 될지 모르겠습니다.

HTML을 계층 구조로 생각하십시오. 나는 항상 libxml과 함께 XHTML을 사용하는 더 좋은 시간을 보냈다.

+0

트리 동작을 지적 해 주셔서 감사합니다. 사실, 나는이 가능성을 깨닫지 못했다. 내 코드를 이런 종류의 내부 - 외부 정의로 리팩터링하는 것이 더 읽기 쉽지만 확실하지는 않지만이 라이브러리에 올바른 방법이 될 것입니다. 괴물 라인을 사용하는 마지막 예제는 권장하지 않습니다. ;-) – Andi