jqQuiz

What is Pug (Jade)?

Pug is a template engine for Node.js and browsers that makes the markup creation more easy and allows to process the HTML. Is like SASS but for HTML.\

What is a 'mixin'?

In Pug, a mixin is kind of a function that could recieve parameters and return a processed result.
The mixins allows to unify and process HTML that appears in a lot of places with small changes.
For example:

//- Declare the mixin
mixin list(items)
    ul
        //- For each item
        each item in items
            //- Create a li and asigns the content
            li!= item
//- Invoke the mixin with parameters (note the + before the name of the mixin)
+list(["Hello", "my", "friend"])
// Some code ...
//- I need a list again
+list(["Other", "list"])

results in:

<ul>
    <li>Hello</li>
    <li>my</li>
    <li>friend</li>
</ul>
<!-- Some code ... -->
<ul>
    <li>Other</li>
    <li>list</li>
</ul>

Cool, right?, with mixins is possible to reduce the amount of code and increases the maintainability and the extensibility of the HTML.
The benefict over JS rendering(dynamic) is that Pug compiles(the most of the cases) out of the browser (with Node.js) without penalize the user browser performance.
For more information about Pug please go to the oficial page
For more info about the mixins please go here

The Mixins way

The mixins gives more control over the markup than the JSON, for example is possible to add more markup above and below to use a grid system like flexbox grid or bootstrap grid.\

+jq-quiz({
    id:"myQuiz"
})
    div.my-awesome-div
        +jq-quiz__header()
            div.row
                div.col-xs-12.col-sm-6
                    +jq-quiz__title({
                        content:"My quiz title"
                    })
                div.col-xs-12.col-sm-6
                    +jq-quiz__description({
                        content:"Description for my quiz"
                    })
            div.row
                div.col-xs-12
                    +jq-quiz__actions()
                        div.col-xs-12.col-sm-6
                            +jq-quiz__action({
                                type:"start",
                                 content:"Start the quiz"
                            })
        +jq-quiz__body()
            +jq-quiz__questions()
                +jq-quiz__question({
                    statement:"Some question"
                })
                    +jq-quiz__options()
                        div.row
                            div.col-xs-12.col-sm-6
                                +jq-quiz__option({
                                    name:"q1",
                                    isCorrect:false,
                                    content:"Incorrect"
                                })
                            div.col-xs-12.col-sm-6
                                +jq-quiz__option({
                                    name:"q1",
                                    isCorrect:true,
                                    content:"Correct"
                                })
            +jq-quiz__actions()
                div.row
                    div.col-xs-12.col-sm-3
                        +jq-quiz__action({
                            type:"prev",
                            content:"Previous question"
                        })
                    div.col-xs-12.col-sm-3
                        +jq-quiz__action({
                            type:"next",
                            content:"Next question"
                        })
                    div.col-xs-12.col-sm-3.col-sm-offset-3
                        +jq-quiz__action({
                            type:"end",
                            content:"End the quiz"
                        })
        +jq-quiz__result()
            +jq-quiz__result-item({
                type: "success ? Perfect! : Ohhh, try again"
            })

All the mixins have common and specific parameters.
The common parameters are:

tag             : The HTML tag to render. Depending of the mixin the default type is different, for example, for the jq-quiz__header the default tag is "header".
cssClass        : Css classes to add
attributes      : HTML attributes to add, all the attributes are allowed. Is a JSON object where the key will be the attribute and the value the attribute value
id              : An id for the element

An example:

+jq-quiz({
    id:"myQuiz",
    cssClass:"my-quiz-class another-quiz-class",
    tag:"div",
    attributes:{
        "data-id":"someId",
        "data-some-attribute":"someAttributeValue"
    }
})

results in:

<div class="jq-quiz my-quiz-class another-quiz-class"
     id="myQuiz"
     data-id="someId"
     data-some-attribute="someAttributeValue">
    <form class="jq-quiz__form"
          data-jq-quiz-wrapper>
    </form>
</div>

Available mixins

We use pug-jsdoc package to create the doc for the mixins, the documentation has the mixins, a description, the parameters and related mixins and examples of use.
You could see all the docs here
The available mixins are:

Example

//- NPM
include node_modules/jqQuiz/jq-quiz
+jq-quiz({
    id:"myQuiz"
})
    +jq-quiz__header
        +jq-quiz__title({
            content:"My quiz"
        })
        +jq-quiz__description({
            content:"Description for my quiz"
        })
        +jq-quiz__properties
            +jq-quiz__property({
                type:"cutOfMark",
                content:"Minimum score to pass"
            })
        +jq-quiz__actions
            +jq-quiz__action({
                type:"start",
                content:"Start the quiz"
            })
    +jq-quiz__body
        +jq-quiz__questions
            //- Question
            +jq-quiz__question
                +jq-quiz__statement
                    span Some question
                +jq-quiz__options
                    +jq-quiz__option({
                        name:"q1",
                        content:"Incorrect",
                        isCorrect:false
                    })
                    +jq-quiz__option({
                        name:"q1",
                        content:"Correct",
                        isCorrect:true
                    })
                +jq-quiz__feedback({
                    type:"ok",
                    content:"Success feedback"
                })
            //- End question
            //- Question
            +jq-quiz__question
                +jq-quiz__statement
                    span Some question
                +jq-quiz__options
                    +jq-quiz__option({
                        name:"q2",
                        content:"Incorrect",
                        isCorrect:false
                    })
                    +jq-quiz__option({
                        name:"q2",
                        content:"Correct",
                        isCorrect:true
                    })
                +jq-quiz__feedback({
                    type:"ok",
                    content:"Success feedback"
                })
            //- End question
        +jq-quiz__actions
            +jq-quiz__action({
                type:"prev",
                content:"Previous question"
            })
            +jq-quiz__action({
                type:"next",
                content:"Next question"
            })
            +jq-quiz__action({
                type:"end",
                content:"End quiz"
            })
    +jq-quiz__result
        +jq-quiz__result-item({
            type: "success ? Well done! : Ohhh, try again",
            content:"Feedback"
        })
        +jq-quiz__result-item({
            type:"maxScore",
            content:"Max score"
        })
        +jq-quiz__result-item({
            type:"score",
            content:"Score"
        })
        +jq-quiz__result-item({
            type: "questionsSuccess",
            content: "Num of successes"
        })
        +jq-quiz__result-item({
            type:"questionsFail",
            content:"Num of fails"
        })
        +jq-quiz__result-item({
            type:"questionsNotAttempted",
            content:"Num of questions not attempted"
        })