• Stars
    star
    845
  • Rank 51,842 (Top 2 %)
  • Language
    Shell
  • License
    GNU Affero Genera...
  • Created about 9 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

commandline asciii kanban board for minimalist productivity hackers & managers (csv-based) #scriptable #nestable #statistics #singlefile #shellscript


commandline kanban #notetaking #todomanager #scriptable for teams AND personal CSV kanban for minimalist productivity hackers.

WHY? online issuetrackers are great for teams, but how to manage (personal) todo's on a crossrepo-, macro-, or micro-level? This is a very simple powerful tool to do that AND measure productivity. Just store the CSV-file(s) inside repos, clouddrives and local filesystems. #teamfriendly #symlinktheplanet #nestedkanbans

Install

$ curl -LO "https://raw.githubusercontent.com/coderofsalvation/kanban.bash/master/kanban"
$ chmod 755 kanban

Show me the kanban board!

$ ./kanban init
$ ./kanban add TODO PERSONAL "buy rose for girlfriend foo bar"
$ ./kanban show

NOTE: columns are configurable, and board resizes according to terminal width

Usage

$ ./kanban
Usage:

  kanban init                             # initialize kanban in current directory
  kanban add                              # add item interactive (adviced) 
  kanban show [status] ....               # show ascii kanban board [with status]
  kanban <id>                             # edit or update item 
  kanban <id> <status>                    # update status of todo id (uses $EDITOR as preferred editor)
  kanban <status> .....                   # list only todo items with this status(es)
  kanban list                             # list all todos (heavy)
  kanban tags                             # list all submitted tags
  kanban add <status> <tag> <description> # add item (use quoted strings for args)  
  kanban stats status [tag]
  kanban stats tag 
  kanban stats history 
  kanban csv                              # edit raw csv

  NOTE #1: statuses can be managed in ~/.kanban/.kanban.conf
  NOTE #2: the database csv can be found in ~/.kanban/.kanban.csv

Examples:

  kanban add TODO projectX "do foo"
  kanban TODO DOING HOLD                 
  kanban stats status projectX
  kanban stats tag projectX 
  watch NOCOLOR=1 kanban show
  # notekeeping by entering a filename as description:
  echo hello > note.txt && kanban add DOING note.txt
  # store in github repo
  git clone https://../foo.git && cd foo.git && kanban init && git add .kanban

Environment:

  X=120 kanban ....         # set max line-width to 120
  NOCOLOR=1 kanban ....     # disable colors
  PLAIN=1 kanban ...        # plaintext, disable utf8 chars

Change status

$ ./kanban show
.------.              .------.              .-------.
| TODO |_______       | HOLD |_______       | DOING |_______
|                     |                     |
| 1 foobar                                  | 3 ipsum
| 2 lorem                                   

$ ./kanban 2 DOING
TODO -> DOING

Edit item

NOTE: make sure you have your favorite editor set in ~/.bashrc (export EDITOR=vim e.g.)

$ ./kanban 2        # this executes ${EDITOR} 

Todo grep

$ ./kanban TODO DOING | grep projectfoo 

Nice to get project-specific kanban overviews.

Note-taking

adding a filename as a description, will trigger kanban to launch $EDITOR:

$ echo -e "hello\nworld" > my_idea.txt
$ kanban add TODO note my_idea.txt
$ kanban list
  id  status   tag        description
  -   -        -          -                                                                                                                                                                -
  4   TODO     note       my_idea.txt
$ k 4

TIP: use symlinks to share notes across boards (cd myproject && ln -s ~/.kanban/timelog.txt timelog.txt e.g.)

Simple listing of status

NOTE: from here we use the k-alias, see the 'Attention Unix ninjas' on how to use it

$ k TODO
id   status  tag   description                 history
-    -       -     -                           -
185  TODO    bly   fooo bar flop               BTBDHDHDHT
199  TODO    bly   meeting about techdesign    BT
245  TODO    lb    checkout testsuite          BT
246  TODO    nus   add field to db             BT
242  TODO    nus   fix db lag                  BT 

as you can see in the history, todo 185 is quite problematic. It went from Backlog->Todo->Backlog->Doing->Hold->... and so on. Obviously the person who assigned this todo should rethink it, and chop it up into seperate todos.

$ k TODO 2015-08
id   status  tag   description                 history
-    -       -     -                           -
246  TODO    nus   add field to db             BT
242  TODO    nus   fix db lag                  BT

Here you can see all todo's which were 'touched' in august 2015

Configuration

see ~/.kanban/.kanban.conf (gets created automatically) You can define the kanban statuses, and limit the maximum amount of todos per status.
See .kanban/kanban.conf in case you initialized a board in your current dir (using kanban init)

Idiotproof csv-editing

Safest way to keep the CSV sane:

$ ./kanban add
enter description:
> do laundry
enter one of statuses: BACKLOG TODO IN_PROGRESS HOLD DONE
> TODO
enter one of tags: projectA, projectB 
> projectA
$

Responsive kanban.

As mentioned earlier, the status/categorynames can be changed in .kanban/.kanban.conf. No widescreen? Show a tag-less, simplified kanban board by hiding some categories:

XSMALL=119                           # show simplified kanban for terminalwidth < 119 chars
SMALLSCREEN=('DOING' 'TODO' 'HOLD')  # define simplified kanban board statuses

Nested kanbans

$ kanban init
$ mkdir featureX           
$ kanban add TODO featureX 
$ cd featureX
$ kanban init
$ kanban add TODO foobar
$ cd ..
$ kanban show
 .____.
| TODO |_____
|
| 12 featureX

$ kanban 12                         # shows kanban inside featureX 
 .____.
| TODO |_____
|
| 1  foobar 

Or, how about centralized kanbans in your dotfiles repo + 1 in a projectrepo

$ cd ~                         # go to homedir (where your dotfiles live)
$ kanban init                  # creates ~/.kanban
$ cd projects/foo 
$ kanban init                 
$ mv .kanban ~/.kanban/foo    
$ ln -s ~/.kanban/foo .kanban  # link dotfiles-folder to here
$ cd ~
$ git add .kanban && git commit -m "dotfiles: updated kanbans"
$ cd projects/bar
$ kanban init
$ git add .kanban && git commit -m "added kanban to project repo"

Scriptable / Kanban Bot

kanban items are SCRIPTABLE using your favorite language. This allows dynamic statuses, tags & descriptions in the CSV-file:

"$(~/.kanban/bot status_day TODO '1 4')","script","database backup","T","2021-10-04@15:36"

this will call the following (executable) shellscript (~/.kanban/bot)

#!/bin/bash
status_day(){
  [[ "$2" =~ $(date +%u) ]] && printf $1 || printf BACKLOG
}

"$@"

Profit!
The database backup item will have status TODO on mondays & fridays, otherwise BACKLOG

TIP: use curl to generate dynamic descriptions, for example:

"$(curl https://api.github.com/repos/coderofsalvation/kanban.bash/issues | grep total_count | sed 's/[^0-9]//g') open issues"

Blinking text

Just wrap a word with stars (*iamblinking* e.g.) in your csv to catch more attention.

Attention UNIX ninjas

type 'k' instead of './kanban'

$ cp kanban ~/bin 
$ echo 'export PATH=$PATH:~/bin' >> ~/.bashrc
$ echo 'alias k=kanban'          >> ~/.bashrc
$ source ~/.bashrc

(now all terminals will recognize 'k' as a command)

Cleanup your kanban board with some bash-fu:

$ for i in {19,36,49}; do kanban $i BACKLOG; done
DONE -> BACKLOG
DONE -> BACKLOG
DONE -> BACKLOG

mass-renames:

$ sed -i 's/FOO/BAR/g' ~/.kanban.csv

Open a terminal on an extra monitor/screen/tmux:

$ NOCOLOR=1 watch kanban show

Run ninja-commands like: 'k 23 DONE' and withness the update:

$ k 34 DONE 
TODO -> DONE
$ k add TODO NINJW workout" "$(date --date='tomorrow' +'%Y-%m-%d') deadline"

Automatically display boards

Put the following in ~/.bashrc to display boards whenever you enter a directory with a kanban:

cd(){
  builtin cd ${1:+"$@"} && [[ -d ./.kanban ]] && kanban show
}

Statistics

With the power of grep you can get overviews:

$ k stats status

            DONE   155 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
         BACKLOG    73 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
            HOLD     9 β–†β–† 
            TODO     5 β–† 
           DOING     5 β–† 

$ k status 2015-08

            DONE   155 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
         BACKLOG    73 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
            HOLD     9 β–†β–† 
            TODO     5 β–† 
           DOING     5 β–† 

$ k stats status DONE 2015-08 

      projectfoo    62 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
      opensource    43 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
        projectX     3 β–† 
           admin     2 β–† 

$ k stats status projectfoo 

            DONE    56 β–†β–†β–†β–†β–†β–†β–†β–† 
         BACKLOG    33 β–†β–†β–†β–†β–† 
            HOLD     6 β–† 
            TODO     2 β–† 
           DOING     1 β–† 

Lets see what the slacking / project ratio is :)

$ k stats tag 2015-08

         slacking   76 β–†β–†β–†β–†β–†β–†β–†β–† 
         projecfoo  36 β–†β–†β–†β–† 

What are are typical tasktransitions:

$ k stats history
              T   129 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
        BTDHDHD    16 β–†β–†β–† 
              T   129 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
             BD    16 β–†β–†β–†  ```


View which projects were put on hold at least 2 times in 2014:

```bash
$ k stats history HDHD 2014 

   project30     6 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
   project40     4 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
   project20     4 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 
   project10     3 β–†β–†β–†β–†β–†β–†β–†β–†β–†β–† 

Realtime Web-based kanban boards

Create the following index.html:

<!DOCTYPE html>
<pre id="log"></pre>
<script>
  // helper function: log message to screen
  function log(msg) { document.getElementById('log').textContent += msg + '\n'; }
  // setup websocket with callbacks
  var ws = new WebSocket('ws://localhost:8080/');
  ws.onopen = function() { console.log('CONNECT'); };
  ws.onclose = function() { console.log('DISCONNECT'); };
  ws.onmessage = function(event) { log(event.data); };
</script>

And then serve it to the web:

$ sudo apt-get install websocketd
$ X=120 NOCOLOR=1 PLAIN=1 websocketd -passenv 'X,NOCOLOR,PLAIN' -port 8080 -staticdir . ./kanban show
Mon, 04 Oct 2021 18:23:08 +0200 | INFO   | server     |  | Serving using application   : ./kanban show
Mon, 04 Oct 2021 18:23:08 +0200 | INFO   | server     |  | Serving static content from : .
Mon, 04 Oct 2021 18:23:08 +0200 | INFO   | server     |  | Starting WebSocket server   : ws://localhost:8080/

Now surf to http://localhost:8080 and PROFIT!

Tab completion

Somehow source kanban.completion in your ~/.bashrc or just copy it to /etc/bash_completion.d

Why

For developers, there's no such thing as the ultimate todo-utility

KANBAN.bash brings the lean and mean kanban board to the console. It uses csv as database backend, a very popular tabular format. The commandline usage is very minimal so few keystrokes can do magic.

Developer info

tests oneliners:

  • run: cd test; for test in test-*; do ./$test &>/dev/null; done && echo OK || echo ERROR
  • debug: cd test; for test in test-*; do bash -x $test; done && echo OK || echo ERROR

Todo

  • more testing
  • easier way of adding todos

More Repositories

1

powscript

transpiler written in bash: painless shellscript, indentbased, coffee for the shell with hipster-sparkles v1 BETA LANDED πŸŽ‰πŸŽ‰πŸŽ‰πŸŽ‰ thanks fcard!
Shell
144
star
2

Gexpress

Express middleware for google appscript (build NODEJS-like applications) + generated api-client
56
star
3

pd-puredata-vanilla-patches

collection of public puredata vanilla patches found on internet
C
53
star
4

hubot-script-shellcmd

easy integration, execution and outputting of shellcommands +(line by line output instead of whole output at once)
CoffeeScript
45
star
5

pm.sh

pm2 in 1 shellscript without the fat + git webhooksupport (bitbucket/github/CI)
Shell
26
star
6

electribe-emx-esx-reverse-engineering

projectplaceholder to organize all possible research concerning 'freeing-the-electribe'-attempts
C++
18
star
7

debootstrap-container

simple way of running multiple debian containers on a (openvz) VPS (instead of docker )
Shell
17
star
8

audiobrowse.bash

simple commandline audio preview of directories for sample-artists / musician and producers
Shell
14
star
9

gspreadsheet-bash

portable google spreadsheet bash client for easily piping/replacing data between spreadsheets
Shell
14
star
10

hubot-script-spreadsheet

hubot plugin: (query) interface to google spreadsheet (*with* authentication)
CoffeeScript
13
star
11

bashdown

markdown to html converter with bash as templating language, written in 100% pure bash, macgyver-style documentation generator
HTML
12
star
12

aframe-verse

deadsimple immersive navigation: a single-player-verse component
JavaScript
12
star
13

parse-server-scheduler

get scheduled jobs to run automatically (without external server) in parse
JavaScript
11
star
14

usm

[unix sample manager] search TERABYTES of samples across different (network) disks in few seconds (+offline)
Shell
11
star
15

soxmasterhouse

automatically mastering of audio using sox/ladspa/vst
Shell
11
star
16

npm-collect

automatically update package.json according to installed/linked modules in node_modules
CoffeeScript
10
star
17

json-dsl

easily create dsl's from json by evaluating json keys and values, json decode on steroids
CoffeeScript
9
star
18

sample-multi-shotifier

hack which expands your traditional hardware/software samplers using many-samples-in-one-sample (poor man's soundfont). Perfect for electribe esx.
Shell
9
star
19

lodash-fp-composition

supercharge lodash/fp with promise- and immutable support
JavaScript
8
star
20

parse-server-image-resize-byurl

Flexible way to resize images on demand (using url-arguments)
JavaScript
8
star
21

syslog-flexible

Minimal PHP class to easily log messages to local syslog and/or papertrail and/or a remote syslog server
PHP
8
star
22

imagegrep-bash

grep word in pdf or image based on OCR
Shell
7
star
23

instr2raw

SF2/XI instrument inspection/conversion utilities + looppoint insertiontools for AIFF/WAV..all for loopedinstrument fanatics
C++
7
star
24

pixilang.GUI

minimal gui library for pixilang
7
star
25

hubot-script-http

run all hubot commands thru the browser or using bash terminal
CoffeeScript
6
star
26

dpd-swagger-doc

automatically generated apidocs from deployd resources
JavaScript
6
star
27

json-ref-lite

Extremely light weight way to resolve jsonschema '$ref' references & inheritance: create circular/graphs, fractals from json (browser/coffeescript/javascript)
Shell
6
star
28

hubot-script-ical

google calendar integration, allows hubot to notify roommembers when ical events (are about) to happen
CoffeeScript
6
star
29

podi

a cute gitops utility (~7kb) to turn servers into PaaS platforms using only git+ssh. #hybrid #baremetal #bubblewrap #k8s #podman #docker
Shell
6
star
30

puretheme

drop-in solution to create beautiful gui's and node-editor using puredata (VANILLA)
5
star
31

framebuffer.bash

framebuffer in bash to draw ascii pixels, borders, animate e.g. (bash ui bootstrap)
Shell
5
star
32

soakbean

Write beautiful ~2.3MB redbean (docker) apps using (redbean) plug-and-play middleware. #tiniest_fastest_server_in_the_universe
Lua
5
star
33

webpipe.bash

extend your bash using webpipes, aka bash-in-the-cloud
Shell
4
star
34

restify-generator

generates a restify RESTserver from a iodocs json schema
JavaScript
4
star
35

sunvoxjs

mirror of Alexander Zolotov's sunvoxjs lib
JavaScript
4
star
36

express-datafire

Live-editing & testing of datafire endpoints & scheduled tasks using express
JavaScript
4
star
37

bashdoc

simple portable documentation generator for any sourcecode using simply bash & markdown
Shell
4
star
38

sheetlabs-google-restproxy

gscript + nodejs rest-proxy which turn a google spreadsheet in sheetlabs.com into a full REST api
JavaScript
4
star
39

dpd-filebased-mongodb

run deployd without mongodb (but a jsonfile instead to store data)
JavaScript
4
star
40

parse-server-jsreactor

A flexible IFTTT-engine with generated gui (backend-agnostic)
JavaScript
3
star
41

dpd-test

easily mock & e2e tests for deployd endpoints, without mongodb-requirement
JavaScript
3
star
42

testosteron

simple crosslanguage testing-utility using bash, crosslanguage bootstrapper for unittests
Shell
3
star
43

nodejs-deploy-githook.bash

DEPRECATED, SUPERSEDED BY pm.sh -------------- KISS automatic node deployment for VPS (minimalist PAAS) node container bootstrapper in few lines of bash using only git & ssh, similar like gitreceive
Shell
3
star
44

ffnode

visual node editor (powered by ffmpeg filtergraph)
C++
3
star
45

aap

an npm-like, highlevel dependency manager, buildtool and installer using bash+git
Shell
3
star
46

middleware-remoteshell

allow developers to tail logs remotely using curl (and run cmds)
JavaScript
3
star
47

dpd-acl-roles-permissions

Easily configure roles/permissions and limitations for methods and (nested) keyvalue-pairs for deployd
JavaScript
3
star
48

restglue

multi-api restful client (javascript) with endpoint-glue & promises (lightweight, no buildchain needed)
JavaScript
3
star
49

BrowserStream

Stream text to browser in realtime without using websockets using PHP
PHP
3
star
50

expressa-swagger

genereated api documentation-page + restclients for expressa
JavaScript
3
star
51

logfilter

easy portable bashscript to monitor syslog- and logfile events with on-the-fly filtering and highlight features
Shell
3
star
52

udev-autorun

udev rule + utility which automatically runs a shellscript on drives when plugged in (or asks for action like windows)
Shell
3
star
53

bashlive.repo

official repo for BASHLIVE, a BASH communitysnippetfunctionframeworkcoderepository-tool for bashhackers
Shell
3
star
54

bless

256 bytes mixin-alternative for ALL js frameworks in the world FOREVER: function bless(πŸ’ͺ)
JavaScript
2
star
55

expressa-cli

helper commands for expressa applications
JavaScript
2
star
56

hubot-syslogd

flexible monitoring and aggregation of logs by using hubot as syslog server (replacement)
CoffeeScript
2
star
57

flowee

a lightweight way to create JSONAPI-compatible api's_ using nodejs:
CoffeeScript
2
star
58

jsongraph

minimalist dataflow programming with json based on jsonschema references (nodejs/coffeescript)
CoffeeScript
2
star
59

mongodb-filebased

mongodb without mongodb (but stores into jsonfile)
JavaScript
2
star
60

nohupr

the 6K minimalist way to manage an multi-app linux server
Shell
2
star
61

sutra-php

Automatically exported from code.google.com/p/sutra-php
PHP
2
star
62

typeshave.js

Lightweight function wrapper to ensure typesafe data. Wrap functions,forms,api's and more with jsonschema
Shell
2
star
63

riot-admin

generic api-agnostic admin dashboard interface, like ng-admin but less javascript-ish
CSS
2
star
64

podman-sh

redirect (ssh) users to a podman/docker container by setting podman-sh as usershell
Shell
2
star
65

timetrack.bash

passive timetracking to csv based on bash history + cronjob and patternmatching
Shell
2
star
66

node-red-contrib-splitter

A Node-RED node to split arrays into seperate messages, making it easy to loop over
HTML
2
star
67

VikingBot

Vikingbot is yet another simple PHP based IRC bot with support for plugins and secure IRC servers. The bot requires Unix/Linux shell access with PHP support and SSL support in PHP for use against secure IRC servers.
PHP
2
star
68

ohmygraph

Easily generate a REST (graph)client from a json api-modelspecification. Like restangular/traverse/backbone/restful but more atheist-style.
Shell
2
star
69

bullmq

*deprecated* simple api management rate limiting: http proxy + throttler + message/job queue based on nodejs bull
JavaScript
2
star
70

docker.alpine.nodejs.pod

alpine linux nodejs pm2+pod docker image for ARM and x86
Shell
2
star
71

notmuch-bash

portable bash client for notmuch, simple consolewrapper for notmuch to save yourself from typing all the time
Shell
2
star
72

jsonschema-acl

jsonschema validator with acl-layer added for nodejs: handy validator before doing db inserts, api replies, form submits etc
JavaScript
2
star
73

deployogi

easy, automatic deployment of webapplications/databases on staging/production webservers using GIT hooks and bash triggers. DEPRECATED: use pm.sh
Shell
2
star
74

bash_builtin_skeleton

"hello world" skeleton for bash custom builtin-commands in C/C++
C
1
star
75

node-red-contrib-coffeescript

coffeescript node for node-red
HTML
1
star
76

loopback-swagger-cli

extend your swagger json with loopback syntax, one jsonfile to rule them all
Shell
1
star
77

bashdownjson

portable/easy way of generating of json feeds using commandline (piping) using 100% bash and bashdown templates
Shell
1
star
78

dot.bash

interactive bash toolbelt for webdevelopment hipsters
Shell
1
star
79

webpipe.bash.php

php-skeleton to run bash webpipes using another server
PHP
1
star
80

lsmail

deadsimple console imapclient (think: ls [email protected] ) written in bash & php
PHP
1
star
81

parse-server-queue

easy-peasy parse-dashboard-compatible queue for parse-server with mongodb
JavaScript
1
star
82

bashlive

BASHLIVE, a BASH communitysnippetfunctionframeworkcoderepository-tool for bashhackers
Shell
1
star
83

jsreactor-channel-sendgrid

sendgrid-integration for jsreactor
JavaScript
1
star
84

expressa-folder

extend expressa collections with ORM-ish js-code (get.js/post.js/functions.js/etc) & setup sub-endpoints
JavaScript
1
star
85

microfunctional.php

bare minimum functional programming for php5
PHP
1
star
86

riot-datatables

riotjs datagrid tag (based on datatables.net)
Shell
1
star
87

dpd-api-token

simple headerbased X-API-TOKEN authentication for 3rd party api auth (+ google analytics for API metrics)
JavaScript
1
star
88

renoise2soundfont

experimental renoise module to soundfont converter
Python
1
star
89

dpd-ratelimit

ratelimit incoming requests based on ip or user
JavaScript
1
star
90

webhookmonkey

webhook monitoring & patch platform (prevent webhook-spaghetti & centralizes webhook routing)
JavaScript
1
star
91

jsreactor

A flexible IFTTT-engine with generated gui (backend-agnostic)
JavaScript
1
star
92

micro-material-css3

lightweight micro material stylesheet for mobile webapps using css3
CSS
1
star
93

spadmin

RAD framework for a SPA rest-to-admin interface
JavaScript
1
star
94

google-keep-lab

codesnippets for the google keep lab chrome extension (brew our own features)
1
star
95

coffeerest-api

Api scaffolding from a model specification in few lines OH MY (coffeescript)
CoffeeScript
1
star
96

nrpn2jesusonic

Bash script which easily converts midi nrpn-descriptions into jesusonic plugins (to gain full midicontrol over your hardware mididevice).
Shell
1
star
97

watchmakers

watch multiple files, directories and run commands accordingly, a multi modular build tool in few lines of bash
Shell
1
star
98

protoplug.scripts

protoplug dsp scripts
Lua
1
star
99

webpipe.coffeescript.nodejs

coffeescript skeleton webpipe
CoffeeScript
1
star
100

datamapper-minimal

Easily transform arrays and objects in PHP with different layouts into one format
PHP
1
star