Twig & the new theme layer in Drupal 8

114
THE NEW THEME LAYER IN DRUPAL 8 Jen Lampton Thursday, April 11, 2013

Transcript of Twig & the new theme layer in Drupal 8

Page 1: Twig & the new theme layer in Drupal 8

THE NEW THEME LAYERIN DRUPAL 8

Jen Lampton

Thursday, April 11, 2013

Page 2: Twig & the new theme layer in Drupal 8

 

JEN LAMPTON

@jenlampton on twitter “jenlampton” http://drupal.org/user/85586

www.jenlampton.com

if you forget my name, just Google “Drupal developer”

Thursday, April 11, 2013

Page 3: Twig & the new theme layer in Drupal 8

 

Building websites since 1997

MY BACKGROUND

Thursday, April 11, 2013

Page 4: Twig & the new theme layer in Drupal 8

 

Working with Drupal since 2006

MY BACKGROUND

Thursday, April 11, 2013

Page 5: Twig & the new theme layer in Drupal 8

 

Consider myself a developer.

MY BACKGROUND

Thursday, April 11, 2013

Page 6: Twig & the new theme layer in Drupal 8

 

Also a Drupal trainer.

MY BACKGROUND

Thursday, April 11, 2013

Page 7: Twig & the new theme layer in Drupal 8

 

Accidental Drupal 8 “initiative” leader.

MY BACKGROUND

Thursday, April 11, 2013

Page 8: Twig & the new theme layer in Drupal 8

 

MY “INITIATIVE”(unofficial)

Thursday, April 11, 2013

Page 9: Twig & the new theme layer in Drupal 8

 

MY “INITIATIVE”

A new theme layer for Drupal 8

(unofficial)

Thursday, April 11, 2013

Page 10: Twig & the new theme layer in Drupal 8

 

THEME LAYER?1) Generation of Markup:

•Template files (as close to HTML as possible)•Preparation of data (for insertion into template files)•Addition of assets (CSS + JS)

Thursday, April 11, 2013

Page 11: Twig & the new theme layer in Drupal 8

 

THEME LAYER?2) System of complete overrides:

•Alteration of HTML in template files•Alteration of data (before insertion into templates)•Inclusion of additional assets

(or exclusion of existing assets)

Thursday, April 11, 2013

Page 12: Twig & the new theme layer in Drupal 8

 

THEME LAYER?3) System of partial overrides:

•Alteration of HTML in template files•Alteration of data (before insertion into templates)•Inclusion of additional assets

(or exclusion of existing assets)

...but only under certain circumstances.

Thursday, April 11, 2013

Page 13: Twig & the new theme layer in Drupal 8

DRUPAL 7 THEME LAYER

 

but, we have this now!

Thursday, April 11, 2013

Page 14: Twig & the new theme layer in Drupal 8

DRUPAL 7 THEME LAYER

 

it looks like this (simplified)

Thursday, April 11, 2013

Page 15: Twig & the new theme layer in Drupal 8

 

DRUPAL 7 THEME LAYERit feels like this

Thursday, April 11, 2013

Page 16: Twig & the new theme layer in Drupal 8

 

HARD TO LEARN

Thursday, April 11, 2013

Page 17: Twig & the new theme layer in Drupal 8

 

HARD TO LEARNfor lots of reasons

Thursday, April 11, 2013

Page 18: Twig & the new theme layer in Drupal 8

 

String, Object or Array?

HARD TO LEARNMixed data types

Thursday, April 11, 2013

Page 19: Twig & the new theme layer in Drupal 8

 

print or print render()?

HARD TO LEARNDifferent methods of printing variables

Thursday, April 11, 2013

Page 20: Twig & the new theme layer in Drupal 8

 

Two ways to override markup:

When do I use what?

THEME FUNCTIONSTEMPLATE FILES

HARD TO LEARN

Thursday, April 11, 2013

Page 21: Twig & the new theme layer in Drupal 8

 

HARD

Too many template files

Thursday, April 11, 2013

Page 22: Twig & the new theme layer in Drupal 8

 

HARDER

Way too many theme functions

Thursday, April 11, 2013

Page 23: Twig & the new theme layer in Drupal 8

 

HARD TO LEARNInsecure.

Thursday, April 11, 2013

Page 24: Twig & the new theme layer in Drupal 8

 

HARD TO LEARNReally, it’s insecure.

Thursday, April 11, 2013

Page 25: Twig & the new theme layer in Drupal 8

 

HARD TO LEARN

Drupalism noun Something that only exists in Drupal.

Drupal-specific

Thursday, April 11, 2013

Page 26: Twig & the new theme layer in Drupal 8

 

too many complex subsystems

HARD TO LEARN

Thursday, April 11, 2013

Page 27: Twig & the new theme layer in Drupal 8

 

1. Mixed data types (strings, objects & arrays)2. Different methods of printing variables (print, render)3.Two ways to override markup: templates & theme fns4. Too many template files & Too many theme functions5. Insecure6. Drupal-specific7. A complex mix of subsystems

HARD TO LEARNbecause

Thursday, April 11, 2013

Page 28: Twig & the new theme layer in Drupal 8

DRUPAL 8 THEME LAYER

Principals to guide us.

lb.com/twig#principles

Thursday, April 11, 2013

Page 29: Twig & the new theme layer in Drupal 8

Principals to guide us

1. Start with nothingCore default markup should strive for semantic simplicity, with few HTML elements, added only as needed

DRUPAL 8 THEME LAYER

lb.com/twig#principles

Thursday, April 11, 2013

Page 30: Twig & the new theme layer in Drupal 8

Principals to guide us

1. Start with nothing2. Build from use cases

We won't assume we know what people want or add features based on "What-if...?" We will think about the 90% of use cases.

DRUPAL 8 THEME LAYER

lb.com/twig#principles

Thursday, April 11, 2013

Page 31: Twig & the new theme layer in Drupal 8

Principals to guide us

1. Start with nothing2. Build from use cases3. Provide tools

Give front-end experts a way to achieve specific goals; goals that apply to the remaining 10% of use cases.

DRUPAL 8 THEME LAYER

lb.com/twig#principles

Thursday, April 11, 2013

Page 32: Twig & the new theme layer in Drupal 8

Principals to guide us

1. Start with nothing2. Build from use cases3. Provide tools4. Consolidate

Don't make something new when something common can be used instead. (let’s create a Theme Component Library).

DRUPAL 8 THEME LAYER

lb.com/twig#principles

Thursday, April 11, 2013

Page 33: Twig & the new theme layer in Drupal 8

Principals to guide us

1. Start with nothing2. Build from use cases3. Provide tools4. Consolidate5. Visibility

You should be able to see what's going on without reading docs.

DRUPAL 8 THEME LAYER

lb.com/twig#principles

Thursday, April 11, 2013

Page 34: Twig & the new theme layer in Drupal 8

Principals to guide us

1. Start with nothing2. Build from use cases3. Provide tools4. Consolidate5. Visibility6. Consistency

Do the same things everywhere, follow patterns.

DRUPAL 8 THEME LAYER

lb.com/twig#principles

Thursday, April 11, 2013

Page 35: Twig & the new theme layer in Drupal 8

Principals to guide us

1. Start with nothing2. Build from use cases3. Provide tools4. Consolidate5. Visibility6. Consistency7. Don't dumb it down

Complexity should be reduced but not obscured.

DRUPAL 8 THEME LAYER

lb.com/twig#principles

Thursday, April 11, 2013

Page 36: Twig & the new theme layer in Drupal 8

Principals to guide us

1. Start with nothing2. Build from use cases3. Provide tools4. Consolidate5. Visibility6. Consistency7. Don't dumb it down8. Organization should be driven by meaning and semantics over technical convenience

Consider what an element means rather than how it structurally appears. Theme developers want to see markup in templates, not abstraction.

DRUPAL 8 THEME LAYER

Thursday, April 11, 2013

Page 37: Twig & the new theme layer in Drupal 8

A NEW THEME ENGINE?

Thursday, April 11, 2013

Page 38: Twig & the new theme layer in Drupal 8

TWIG

well documented

Thursday, April 11, 2013

Page 39: Twig & the new theme layer in Drupal 8

TWIG

extensible

Thursday, April 11, 2013

Page 40: Twig & the new theme layer in Drupal 8

TWIG

secure

Thursday, April 11, 2013

Page 41: Twig & the new theme layer in Drupal 8

TWIG

fast

Thursday, April 11, 2013

Page 42: Twig & the new theme layer in Drupal 8

TWIG

IDE integration

Thursday, April 11, 2013

Page 43: Twig & the new theme layer in Drupal 8

TWIG

recognizable syntax

Thursday, April 11, 2013

Page 44: Twig & the new theme layer in Drupal 8

TWIG

by the creator of Symfony, Fabien Potencier

Thursday, April 11, 2013

Page 45: Twig & the new theme layer in Drupal 8

TWIGwhat does it look like?

Thursday, April 11, 2013

Page 46: Twig & the new theme layer in Drupal 8

what does it look like?

TWIG

Thursday, April 11, 2013

Page 47: Twig & the new theme layer in Drupal 8

TWIGprint with {{ }}

Thursday, April 11, 2013

Page 48: Twig & the new theme layer in Drupal 8

commands with {% %}

TWIG

Thursday, April 11, 2013

Page 49: Twig & the new theme layer in Drupal 8

comments with {# #}

TWIG

Thursday, April 11, 2013

Page 50: Twig & the new theme layer in Drupal 8

drill down into all variables with .

TWIG

Thursday, April 11, 2013

Page 51: Twig & the new theme layer in Drupal 8

All markup is generated in template files.

TWIG

Thursday, April 11, 2013

Page 52: Twig & the new theme layer in Drupal 8

 

D7 PAIN POINTS

1. Mixed data types2. Different methods of printing variables3.Two ways to override markup4. Too many template files & theme functions 5. Insecure6. Drupal-specific7. A complex mix of subsystems

does Twig help?

Thursday, April 11, 2013

Page 53: Twig & the new theme layer in Drupal 8

1. Mixed data types

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 54: Twig & the new theme layer in Drupal 8

1. Mixed data typesAll template variables are accessed

consistently: node.nid

content.links

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 55: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 56: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 57: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variablesRemoved calls to render() from templates:

{{ node.nid }}{{ content.links }}

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 58: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 59: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 60: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup

All theme functions become templates.node.tpl.php becomes node.html.twigtheme_table() becomes table.html.twig

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 61: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 62: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 63: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions

We’re working on this right now

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 64: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions @todo

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 65: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions @todo5. Insecure

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 66: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions @todo5. InsecureAll variables are *automatically* sanitized

and most PHP functions cannot be executed in template files.

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 67: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions @todo5. Insecure FIXED

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 68: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions @todo5. Insecure FIXED6. Drupal-specific

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 69: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions @todo5. Insecure FIXED6. Drupal-specific

Twig is used elsewhere on the webis syntactically similar to other languages

and looks a lot more like HTML.

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 70: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions @todo5. Insecure FIXED6. Drupal-specific FIXED

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 71: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions @todo5. Insecure FIXED6. Drupal-specific FIXED7. A complex mix of subsystems

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 72: Twig & the new theme layer in Drupal 8

D7 THEME LAYER

Thursday, April 11, 2013

Page 73: Twig & the new theme layer in Drupal 8

remove theme functions (and overrides) entirely.

D8 IMPROVEMENTS

Thursday, April 11, 2013

Page 74: Twig & the new theme layer in Drupal 8

remove process.

D8 IMPROVEMENTS

Thursday, April 11, 2013

Page 75: Twig & the new theme layer in Drupal 8

remove render.

D8 IMPROVEMENTS

Thursday, April 11, 2013

Page 76: Twig & the new theme layer in Drupal 8

remove page alter?

D8 IMPROVEMENTS

Thursday, April 11, 2013

Page 77: Twig & the new theme layer in Drupal 8

remove preprocess?

D9 IMPROVEMENTS

Thursday, April 11, 2013

Page 78: Twig & the new theme layer in Drupal 8

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions @todo5. Insecure FIXED6. Drupal-specific FIXED7. A complex mix of subsystems We can remove all theme functions, render,

process & (maybe) preprocess too.

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 79: Twig & the new theme layer in Drupal 8

 

D7 PAIN POINTS

1. Mixed data types FIXED2. Different methods of printing variables FIXED3.Two ways to override markup FIXED4. Too many template files & theme functions @todo5. Insecure FIXED6. Drupal-specific FIXED7. A complex mix of subsystems @todo

does Twig help?

Thursday, April 11, 2013

Page 80: Twig & the new theme layer in Drupal 8

 

D7 PAIN POINTSdoes Twig help?

Thursday, April 11, 2013

Page 81: Twig & the new theme layer in Drupal 8

 

D7 PAIN POINTS

YES!!!

does Twig help?

Thursday, April 11, 2013

Page 82: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINS

Thursday, April 11, 2013

Page 83: Twig & the new theme layer in Drupal 8

less code than PHP functions

TWIG: OTHER WINS

Thursday, April 11, 2013

Page 84: Twig & the new theme layer in Drupal 8

theme_image becomes image.html.twig

less code than PHP functions

D7

D8

TWIG: OTHER WINS

Thursday, April 11, 2013

Page 85: Twig & the new theme layer in Drupal 8

TWIG

D8

theme_username becomes username.html.twig

D7

less code than PHP functions

Thursday, April 11, 2013

Page 86: Twig & the new theme layer in Drupal 8

TWIG

D8

theme_link becomes link.html.twig

D7

less code than PHP functions

Thursday, April 11, 2013

Page 87: Twig & the new theme layer in Drupal 8

theme_item_list becomes item_list.html.twig

D7

D8

lots less code than PHP functions

Thursday, April 11, 2013

Page 88: Twig & the new theme layer in Drupal 8

Awesome template inspection.

TWIG: OTHER WINS

Thursday, April 11, 2013

Page 89: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINS

(“devel themer” in core)

Awesome template inspection.

Thursday, April 11, 2013

Page 90: Twig & the new theme layer in Drupal 8

Awesome variable inspection.

TWIG: OTHER WINS

Thursday, April 11, 2013

Page 91: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINS

(devel’s dpm() in core)

Awesome variable inspection.

Thursday, April 11, 2013

Page 92: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSTemplate inheritance

Thursday, April 11, 2013

Page 93: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSTemplate inheritance

comment-wrapper.html.twig before

Thursday, April 11, 2013

Page 94: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSTemplate inheritance

comment-wrapper.html.twig after

Thursday, April 11, 2013

Page 95: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSTemplate inheritance

comment-wrapper--forum.html.twig(child template)

Thursday, April 11, 2013

Page 96: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSPossible performance gains (Much TBD)

Thursday, April 11, 2013

Page 97: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSPossible performance gains (Much TBD)

• PHPtemplate reads files from disk on every use(or stat()s them with APC)

• Twig templates are read once & compiled into classes

Thursday, April 11, 2013

Page 98: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSPossible performance gains (Much TBD)

• PHPtemplate reads files from disk on every use(or stat()s them with APC)

• Twig templates are read once & compiled into classes

Rendering should get much faster when the same content element appears multiple times on the page.

Thursday, April 11, 2013

Page 99: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSPossible performance gains (Much TBD)

• PHPtemplate reads files from disk on every use(or stat()s them with APC)

• Twig templates are read once & compiled into classes

Rendering should get much faster when the same content element appears multiple times on the page.

Consolidating many similar templates will result in an additional gain.

Thursday, April 11, 2013

Page 100: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSIn-browser template editing finally safe.

Thursday, April 11, 2013

Page 101: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSIn-browser template editing finally safe.

• Saving PHP code in the database is a HUGE no-no.• Twig is not PHP, and is safe to store!

Thursday, April 11, 2013

Page 102: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSIn-browser template editing finally safe.

• Saving PHP code in the database is a HUGE no-no.• Twig is not PHP, and is safe to store!

Modules like ‘Contemplate’ (Content templates) will finally be safe to use.

Thursday, April 11, 2013

Page 103: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSIn-browser template editing finally safe.

• Saving PHP code in the database is a HUGE no-no.• Twig is not PHP, and is safe to store!

Modules like ‘Contemplate’ (Content templates) will finally be safe to use.

In-browser template editing is something WordPress users have been asking of Drupal for a very long time.

Thursday, April 11, 2013

Page 104: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINSTwig template files can be used on the front end, too.

Thursday, April 11, 2013

Page 105: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINS

One template can return markup for both your PHP-generated pages, as well as pages generated vi JS in AJAX callbacks.

Twig template files can be used on the front end, too.

Thursday, April 11, 2013

Page 106: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINS

One template can return markup for both your PHP-generated pages, as well as pages generated vi JS in AJAX callbacks.

We can use other open source libraries like TwigJS.(https://github.com/schmittjoh/twig.js)

Twig template files can be used on the front end, too.

Thursday, April 11, 2013

Page 107: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINS2-way communication between UI and code.

Thursday, April 11, 2013

Page 108: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINS

No broken UIs.

2-way communication between UI and code.

Thursday, April 11, 2013

Page 109: Twig & the new theme layer in Drupal 8

TWIG: OTHER WINS

No broken UIs.

Template files can be created first, and the Drupal site can build itself* based on the presence and location of variables in the

templates.

*within reason

2-way communication between UI and code.

Thursday, April 11, 2013

Page 110: Twig & the new theme layer in Drupal 8

THE NEW THEME LAYERIN DRUPAL 8

looks pretty awesome, right?

Thursday, April 11, 2013

Page 111: Twig & the new theme layer in Drupal 8

QUESTIONS?

Thursday, April 11, 2013

Page 112: Twig & the new theme layer in Drupal 8

HELP US GET THERE

we need your help!

we could be “done” in 1.5 weeks

http://drupal.org/node/1757550

IRC: #drupal-twig

Thursday, April 11, 2013

Page 113: Twig & the new theme layer in Drupal 8

Jen Lampton ~ @jenlamptonwww.jenlampton.com

THE NEW THEME LAYERIN DRUPAL 8

Thursday, April 11, 2013

Page 114: Twig & the new theme layer in Drupal 8

photo credits:lolcat-flexible

http://cheezburger.com/2679924736

anything is possible pebbleshttp://www.invergordontours.com/aip.html

lolcat questionmark http://icanhascheezburger.com/2007/10/31/11197/

wheel-reinventedhttp://www.brainwads.net/drewhawkins/2012/01/dont-re-invent-the-wheel-make-something-better/

objectshttp://2teachers1classroom.blogspot.com/2009_02_01_archive.html

shapeshttp://englishclass.jp/reading/topic/For_Screening_Purposes_Only

securehttp://blog.stratepedia.org/2010/06/03/what-is-a-secure-site/

consistencyhttp://icsigns.org/press/2010/03/23/consistency-staying-on-the-mark/

twig bird comichttp://s302.photobucket.com/albums/nn105/walkseva/?action=view&current=thebirdneedsthattwig.gif&currenttag=bird%20park%20twig%20comic%20need%20it

twig docs screenshotshttp://twig.sensiolabs.org/documentation

twig speed graphshttp://phpcomparison.net/

python iconhttp://python-hosting.org/

ruby iconhttp://itmediaconnect.ro/en/web

django logohttp://py-arahat.blogspot.com/2010/08/django-vs-pylons.html

symfony logohttp://symfony.com/logo

scotch glasshttp://www.thespir.it/articles/scotch-101/?viewall=1

speech bubblehttp://ljtfash.blogspot.com/2012/10/youre-beautiful-no-matter-what-they-say.html

Thursday, April 11, 2013