FlaskViewComponent 0.1.dev0
A framework to create reusable server rendered components in Python's Flask Framework.
License: MIT

# FlaskViewComponent
A framework to create reusable server rendered components in Python's Flask Framework.




## Requirements

1. Python 3+
2. Flask

## Requirements

    https://github.com/JarriqTheTechie/FlaskViewComponent.git

## How to Add to your Project

    from flask import Flask
	from flask_view_components import FlaskViewComponent

	app = Flask(__name__)
	FlaskViewComponent(app)
    
	
## Making FlaskViewComponents
Components are read from the following directory of your flask project.
`templates/components`

Components require two files to be created. 
1. FooComponent.html eg. `NameComponent.html`
2. FooComponentComponent.py eg. `NameComponent.py`
#
*templates/components/NameComponent.py*
    
    class NameComponent:  
	    def __init__(self, name):  
	        self.name= name
<br>

*templates/components/NameComponent.html*
    
    <h1>{{ name }}</h1>
    

## Using the FlaskViewComponent

View Components can be used in any of the following ways. 

1. Calling the render method from Flask Jinja template. eg.
	*templates/index.html*
###	
    {{ render("NameComponent", name="Jane Doe") }}

<br>

2. In a controller you can render the FlaskViewComponent by returning the component using the following syntax.
### 

    return render_inline('{{ render("NameComponent", name="Jane Doe") }}')

## Parameters
### Passing Parameters

Underneath the hood, components are simply python classes with a matching html template. Parameters are passed to the __init__ function of the component class. 

For example, lets use our NameComponent which has the "name" instance variable. Here's how we would pass a name to the component. 

     {{ render("NameComponent", name="James Blunt") }}


## Properties

FlaskViewComponent passes data to instance variables of the component class.

    import random

	class ButtonComponent:
	    def __init__(self, text, variant="danger"):
	        self.text = text
	        self.variant = random.choice(["primary", "success", "danger", "warning", "info", "secondary"])


## Nested Components
Component nesting is supported and doesn't require subclassing in the .py file. This can be done entirely in the .html component file.

## API

#**render()**
Render a component in a template

    {{ render("ProductComponent", name="Gatorade", price=2.25) }}
    
<br>

#**render_inline()**
Returning the string representation of a component

    render_inline('{{ render("ProductComponent", name="Gatorade", price=2.25) }}')
    
<br>

#**render_with_collection()**
Render a component for each element in a collection
*sample collection*
 `fruit = [{"name": "apple", "vendor": "Super Value"}, {"name": "grapes", "vendor": "Buy for Less"}, {"name": "banana", "vendor": "Cost Right"}]`

    {{ render_with_collection("FruitPickerComponent", "fruit", fruit=fruit)|safe }}

This replaces `{% for fruit in fruits %}{% endfor %}`

<br>

#**render_if()**
Determine whether the component should render
If the result of the .render_if() method is False then the component will not render. 

    class ListComponent:  
    	with_collection_parameter = "fruit"  
      
    def __init__(self, fruit, fruit_counter=int):  
        self.fruit = fruit  
        self.fruit_counter = ""  
      
    def render_if(self):  
        return self.fruit["name"] == "grapes"

## Roadmap
TODO