README.md

[![badge](https://img.shields.io/badge/Texas-v0.3.1-blue.svg?style=for-the-badge&label=Texas)](https://hex.pm/packages/texas/0.3.1)
[![badge](https://img.shields.io/badge/texasjs-v0.3.18-blue.svg?style=for-the-badge&label=TexasJS)](https://www.npmjs.com/package/texasjs/v/0.3.18)

# What is Texas?

Texas is a back-end Virtual DOM library.  It aims to overhaul how you work with phoenix's view layer so that you can spend more time developing on the server, rather than dealing with complex toolchains and build systems that offload work to the client.  The main goal for Texas is to create a library that significantly speeds up development and testing, but I believe this library can achieve many advancements over how we've been writing web apps, including: reduced data over the wire, faster response times, and graceful degredation to an application that continues to function in the abscence of any JS.

#### This project builds on top of [Phoenix](http://phoenixframework.org/), so you'll need a new phoenix project.  These install docs assume you're using phoenix 1.3+.

#### You can find an example application [here](https://gitlab.com/dgmcguire/example_texas_app).
#### The example application live: https://warm-citadel-23442.herokuapp.com/

# Installation

## 1. Add Texas to your dependencies
```elixir
# file: ./mix.exs
  defp deps do
    [
      ...
      {:texas, "X.X.X"}, # latest should be denoted by the Texas hex badge at the top
      ...
    ]
  end
```
```elixir
# file: ./assets/package.json
  ...
  "dependencies": {
    ...
    "texasjs": "X.X.X", # latest should be denoted by the texasjs npm badge at the top
    ...
  },
```

After updating your dependencies, install them:
 - $ `mix deps.get`
 - $ `cd assets/ && npm install`

## 2. Setup your websocket channels and texasjs
```javascript
// file: ./assets/js/app.js

// Import dependencies...
import "phoenix_html"

// Import local files...

import socket from "./socket"
import texasjs from "texasjs"

// Texas needs access to the phoenix apps websocket
new texasjs(socket)
```
```elixir
# file: ./lib/<your_app>_web/channels/user_socket.ex
defmodule <your_app>Web.UserSocket do
  use Phoenix.Socket
  use Texas.Socket
  ...
end
```

## 3. Let Texas know where your endpoint and router modules are via config and setup the templating engine to compile .tex files
> NOTE: It doesn't matter which order you declare your configuration variables, but they must at least be declared after `use Mix.Config`

```elixir
# file: ./config/config.exs
config :texas, pubsub: <YourApp>Web.Endpoint
config :texas, router: <YourApp>Web.Router
config :phoenix, :template_engines,
  tex:  Texas.TemplateEngine
```

## 4. Insert the Texas plug into your http pipeline and import some rendering functions Texas gives you into the controllers you want to use with Texas
```elixir
 # file: ./lib/<your_app>_web/router.ex

defmodule <YourAppWeb>.Router do
  ...

  pipeline :browser do
    ...
    plug Texas.Plug
  end

  ...
end
```

```elixir
# file: ./lib/<your_app>_web/controllers/page_controller.ex
defmodule <YourApp>Web.PageController do
  ...
  import Texas.Controller

  ...
end
```

## 5. Creating a dynamic template and view
> NOTE: The template needs to be `.tex` (or whatever you put in your config) to get run thru the texas template engine!

```html
# file: ./lib/<your_app>_web/templates/page/index.html.tex

<div data-texas="example_list">
  Some example prototype data that will be overwritten.
</div>
```

> NOTE: With a default Phoenix install, the <your_view> placeholder should be `./lib/<your_app>_web/templates/page/index.html.eex`.
> We'll be changing the `index.html.eex` file to `index.html.tex`

```elixir
# file: ./lib/<your_app>_web/views/page_view.ex

defmodule <YourApp>Web.PageView do
  use <YourApp>Web, :view

  def data(conn) do
    %{ example_list: example_list(conn) }
  end

  def example_list(_conn) do
    {"div", [class: "some-class"], [example_text_node()]}
  end

  defp example_text_node, do: {"div", [], ["see it's overwritten!"]}
end
```

## 6. Responding with that rendered view via a controller
```elixir
# file: ./lib/<your_app>_web/controllers/page_controller.ex

defmodule <YourApp>Web.PageController do
  use <YourApp>Web, :controller
  import Texas.Controller

  def index(conn, _params) do
    texas_render conn, "index.html", [texas: <YourApp>Web.PageView.data(conn)]
  end
end
```