����JFIFXX�����    $.' ",#(7),01444'9=82<.342  2!!22222222222222222222222222222222222222222222222222����"��4�� ���,�PG"Z_�4�˷����kjز�Z�,F+��_z�,�© �����zh6�٨�ic�fu���#ډb���_�N�?��wQ���5-�~�I���8����TK<5o�Iv-�����k�_U_�����~b�M��d����Ӝ�U�Hh��?]��E�w��Q���k�{��_}qFW7HTՑ��Y��F�?_�'ϔ��_�Ջt��=||I ��6�έ"�����D���/[�k�9���Y�8ds|\���Ҿp6�Ҵ���]��.����6�z<�v��@]�i%��$j��~�g��J>��no����pM[me�i$[����s�o�ᘨ�˸ nɜG-�ĨU�ycP�3.DB�li�;��hj���x7Z^�N�h������N3u{�:j�x�힞��#M&��jL P@_���� P��&��o8������9�����@Sz6�t7#O�ߋ �s}Yf�T���lmr����Z)'N��k�۞p����w\�Tȯ?�8`�O��i{wﭹW�[�r�� ��Q4F�׊���3m&L�=��h3����z~��#�\�l :�F,j@�� ʱ�wQT����8�"kJO���6�֚l����}���R�>ډK���]��y����&����p�}b��;N�1�m�r$�|��7�>e�@B�TM*-iH��g�D�)� E�m�|�ؘbҗ�a��Ҿ����t4���o���G��*oCN�rP���Q��@z,|?W[0�����:�n,jWiE��W��$~/�hp\��?��{(�0���+�Y8rΟ�+����>S-S����VN;�}�s?.����� w�9��˟<���Mq4�Wv'��{)0�1mB��V����W[�����8�/<� �%���wT^�5���b��)iM� pg�N�&ݝ��VO~�q���u���9� ����!��J27����$O-���! �:�%H��� ـ����y�ΠM=t{!S�� oK8������t<����è:a������[�����ա�H���~��w��Qz`�po�^ ����Q��n� �,uu�C�$ ^���,������8�#��:�6��e�|~���!�3�3.�\0��q��o�4`.|� ����y�Q�`~;�d�ׯ,��O�Zw�������`73�v�܋�<���Ȏ�� ـ4k��5�K�a�u�=9Yd��$>x�A�&�� j0� ���vF��� Y�|�y��� ~�6�@c��1vOp�Ig����4��l�OD���L����� R���c���j�_�uX6��3?nk��Wy�f;^*B� ��@�~a�`��Eu������+���6�L��.ü>��}y���}_�O�6�͐�:�YrG�X��kG�����l^w���~㒶sy��Iu�!� W ��X��N�7BV��O��!X�2����wvG�R�f�T#�����t�/?���%8�^�W�aT��G�cL�M���I��(J����1~�8�?aT ���]����AS�E��(��*E}� 2��#I/�׍qz��^t�̔���b�Yz4x���t�){ OH��+(E��A&�N�������XT��o��"�XC��'���)}�J�z�p� ��~5�}�^����+�6����w��c��Q�|Lp�d�H��}�(�.|����k��c4^�"�����Z?ȕ ��a<�L�!039C� �Eu�C�F�Ew�ç ;�n?�*o���B�8�bʝ���'#Rqf���M}7����]����s2tcS{�\icTx;�\��7K���P���ʇ Z O-��~��c>"��?�������P��E��O�8��@�8��G��Q�g�a�Վ���󁶠�䧘��_%#r�>�1�z�a��eb��qcPѵ��n���#L��� =��׀t� L�7�`��V���A{�C:�g���e@�w1 Xp3�c3�ġ����p��M"'-�@n4���fG��B3�DJ�8[Jo�ߐ���gK)ƛ��$���� ���8�3�����+���� �����6�ʻ���� ���S�kI�*KZlT _`���?��K����QK�d����B`�s}�>���`��*�>��,*@J�d�oF*����弝��O}�k��s��]��y�ߘ��c1G�V���<=�7��7����6�q�PT��tXԀ�!9*4�4Tހ3XΛex�46���Y��D ����� �BdemDa����\�_l,��G�/���֌7���Y�](�xTt^%�GE�����4�}bT���ڹ�����;Y)���B�Q��u��>J/J �⮶.�XԄ��j�ݳ�+E��d ��r�5�_D�1 ��o�� �B�x�΢�#���<��W�����8���R6�@g�M�.��� dr�D��>(otU��@x=��~v���2� ӣ�d�oBd��3�eO�6�㣷�����ݜ6��6Y��Qz`��S��{���\P�~z m5{J/L��1������<�e�ͅPu�b�]�ϔ���'������f�b� Zpw��c`"��i���BD@:)ִ�:�]��hv�E�w���T�l��P���"Ju�}��وV J��G6��. J/�Qgl߭�e�����@�z�Zev2u�)]կ�����7x���s�M�-<ɯ�c��r�v�����@��$�ޮ}lk���a���'����>x��O\�ZFu>�����ck#��&:��`�$�ai�>2Δ����l���oF[h��lE�ܺ�Πk:)���`�� $[6�����9�����kOw�\|���8}������ބ:��񶐕��I�A1/�=�2[�,�!��.}gN#�u����b��� ~��݊��}34q����d�E��Lc��$��"�[q�U�硬g^��%B �z���r�pJ�ru%v\h1Y�ne`ǥ:g���pQM~�^�Xi� ��`S�:V29.�P���V�?B�k�� AEvw%�_�9C�Q����wKekPؠ�\�;Io d�{ ߞo�c1eP����\� `����E=���@K<�Y���eڼ�J���w����{av�F�'�M�@/J��+9p���|]�����Iw &`��8���&M�hg��[�{��Xj��%��Ӓ�$��(����ʹN���<>�I���RY���K2�NPlL�ɀ)��&e����B+ь����( � �JTx���_?EZ� }@ 6�U���뙢ط�z��dWI�n` D����噥�[��uV��"�G&Ú����2g�}&m��?ċ�"����Om#��������� ��{�ON��"S�X��Ne��ysQ���@Fn��Vg���dX�~nj�]J�<�K]:��FW��b�������62�=��5f����JKw��bf�X�55��~J �%^����:�-�QIE��P��v�nZum� z � ~ə ���� ���ة����;�f��\v���g�8�1��f24;�V���ǔ�)����9���1\��c��v�/'Ƞ�w�������$�4�R-��t���� e�6�/�ġ �̕Ecy�J���u�B���<�W�ַ~�w[B1L۲�-JS΂�{���΃������A��20�c#��@ 0!1@AP"#2Q`$3V�%45a6�FRUq��� ����^7ׅ,$n�������+��F�`��2X'��0vM��p�L=������5��8������u�p~���.�`r�����\���O��,ư�0oS ��_�M�����l���4�kv\JSd���x���SW�<��Ae�IX����������$I���w�:S���y���›R��9�Q[���,�5�;�@]�%���u�@ *ro�lbI �� ��+���%m:�͇ZV�����u�̉����θau<�fc�.����{�4Ա� �Q����*�Sm��8\ujqs]{kN���)qO�y�_*dJ�b�7���yQqI&9�ԌK!�M}�R�;������S�T���1���i[U�ɵz�]��U)V�S6���3$K{�ߊ<�(� E]Զ[ǼENg�����'�\?#)Dkf��J���o��v���'�%ƞ�&K�u�!��b�35LX�Ϸ��63$K�a�;�9>,R��W��3�3� d�JeTYE.Mϧ��-�o�j3+y��y^�c�������VO�9NV\nd�1 ��!͕_)a�v;����թ�M�lWR1��)El��P;��yوÏ�u 3�k�5Pr6<�⒲l�!˞*��u־�n�!�l:����UNW ��%��Chx8vL'��X�@��*��)���̮��ˍ��� ���D-M�+J�U�kvK����+�x8��cY������?�Ԡ��~3mo��|�u@[XeY�C�\Kp�x8�oC�C�&����N�~3-H���� ��MX�s�u<`���~"WL��$8ξ��3���a�)|:@�m�\���^�`�@ҷ)�5p+��6���p�%i)P M���ngc�����#0Aruz���RL+xSS?���ʮ}()#�t��mˇ!��0}}y����<�e� �-ή�Ԩ��X������ MF���ԙ~l L.3���}�V뽺�v�����멬��Nl�)�2����^�Iq��a��M��qG��T�����c3#������3U�Ǎ���}��לS�|qa��ڃ�+���-��2�f����/��bz��ڐ�� �ݼ[2�ç����k�X�2�* �Z�d���J�G����M*9W���s{��w���T��x��y,�in�O�v��]���n����P�$�JB@=4�OTI�n��e�22a\����q�d���%�$��(���:���: /*�K[PR�fr\nڙdN���F�n�$�4�[�� U�zƶ����� �mʋ���,�ao�u 3�z� �x��Kn����\[��VFmbE;�_U��&V�Gg�]L�۪&#n%�$ɯ�dG���D�TI=�%+AB�Ru#��b4�1�»x�cs�YzڙJG��f��Il��d�eF'T� iA��T���uC�$����Y��H?����[!G`}���ͪ� �纤Hv\������j�Ex�K���!���OiƸ�Yj�+u-<���'q����uN�*�r\��+�]���<�wOZ.fp�ێ��,-*)V?j-kÊ#�`�r��dV����(�ݽBk�����G�ƛk�QmUڗe��Z���f}|����8�8��a���i��3'J�����~G_�^���d�8w������ R�`(�~�.��u���l�s+g�bv���W���lGc}��u���afE~1�Ue������Z�0�8�=e�� f@/�jqEKQQ�J��oN��J���W5~M>$6�Lt�;$ʳ{���^��6�{����v6���ķܰg�V�cnn �~z�x�«�,2�u�?cE+Ș�H؎�%�Za�)���X>uW�Tz�Nyo����s���FQƤ��$��*�&�LLXL)�1�" L��eO��ɟ�9=���:t��Z���c��Ž���Y?�ӭV�wv�~,Y��r�ۗ�|�y��GaF�����C�����.�+� ���v1���fήJ�����]�S��T��B��n5sW}y�$��~z�'�c ��8 ��� ,! �p��VN�S��N�N�q��y8z˱�A��4��*��'������2n<�s���^ǧ˭P�Jޮɏ�U�G�L�J�*#��<�V��t7�8����TĜ>��i}K%,���)[��z�21z ?�N�i�n1?T�I�R#��m-�����������������1����lA�`��fT5+��ܐ�c�q՝��ʐ��,���3�f2U�եmab��#ŠdQ�y>\��)�SLY����w#��.���ʑ�f��� ,"+�w�~�N�'�c�O�3F�������N<���)j��&��,-� �љ���֊�_�zS���TǦ����w�>��?�������n��U仆�V���e�����0���$�C�d���rP �m�׈e�Xm�Vu� �L��.�bֹ��� �[Դaզ���*��\y�8�Է:�Ez\�0�Kq�C b��̘��cө���Q��=0Y��s�N��S.���3.���O�o:���#���v7�[#߫ ��5�܎�L���Er4���9n��COWlG�^��0k�%<���ZB���aB_���������'=��{i�v�l�$�uC���mƎҝ{�c㱼�y]���W�i ��ߧc��m�H� m�"�"�����;Y�ߝ�Z�Ǔ�����:S#��|}�y�,/k�Ld� TA�(�AI$+I3��;Y*���Z��}|��ӧO��d�v��..#:n��f>�>���ȶI�TX��� 8��y����"d�R�|�)0���=���n4��6ⲑ�+��r<�O�܂~zh�z����7ܓ�HH�Ga롏���nCo�>������a ���~]���R���̲c?�6(�q�;5%� |�uj�~z8R=X��I�V=�|{v�Gj\gc��q����z�؋%M�ߍ����1y��#��@f^���^�>N�����#x#۹��6�Y~�?�dfPO��{��P�4��V��u1E1J �*|���%���JN��`eWu�zk M6���q t[�� ��g�G���v��WIG��u_ft����5�j�"�Y�:T��ɐ���*�;� e5���4����q$C��2d�}���� _S�L#m�Yp��O�.�C�;��c����Hi#֩%+) �Ӎ��ƲV���SYź��g |���tj��3�8���r|���V��1#;.SQ�A[���S������#���`n�+���$��$I �P\[�@�s��(�ED�z���P��])8�G#��0B��[ى��X�II�q<��9�~[Z멜�Z�⊔IWU&A>�P~�#��dp<�?����7���c��'~���5 ��+$���lx@�M�dm��n<=e�dyX��?{�|Aef ,|n3�<~z�ƃ�uۧ�����P��Y,�ӥQ�*g�#먙R�\���;T��i,��[9Qi歉����c>]9�� ��"�c��P�� �Md?٥��If�ت�u��k��/����F��9�c*9��Ǎ:�ØF���z�n*�@|I�ށ9����N3{'��[�'ͬ�Ҳ4��#}��!�V� Fu��,�,mTIk���v C�7v���B�6k�T9��1�*l� '~��ƞF��lU��'�M ����][ΩũJ_�{�i�I�n��$���L�� j��O�dx�����kza۪��#�E��Cl����x˘�o�����V���ɞ�ljr��)�/,�߬h�L��#��^��L�ф�,íMƁe�̩�NB�L�����iL����q�}��(��q��6IçJ$�W�E$��:������=#����(�K�B����zђ <��K(�N�۫K�w��^O{!����)�H���>x�������lx�?>Պ�+�>�W���,Ly!_�D���Ō�l���Q�!�[ �S����J��1��Ɛ�Y}��b,+�Lo�x�ɓ)����=�y�oh�@�꥟/��I��ѭ=��P�y9��� �ۍYӘ�e+�p�Jnϱ?V\SO%�(�t� ���=?MR�[Ș�����d�/ ��n�l��B�7j� ��!�;ӥ�/�[-���A�>�dN�sLj ��,ɪv��=1c�.SQ�O3�U���ƀ�ܽ�E����������̻��9G�ϷD�7(�}��Ävӌ\�y�_0[w ���<΍>����a_��[0+�L��F.�޺��f�>oN�T����q;���y\��bՃ��y�jH�<|q-eɏ�_?_9+P���Hp$�����[ux�K w�Mw��N�ی'$Y2�=��q���KB��P��~������Yul:�[<����F1�2�O���5=d����]Y�sw:���Ϯ���E��j,_Q��X��z`H1,#II ��d�wr��P˂@�ZJV����y$�\y�{}��^~���[:N����ߌ�U�������O��d�����ؾe��${p>G��3c���Ė�lʌ�� ת��[��`ϱ�-W����dg�I��ig2��� ��}s ��ؤ(%#sS@���~���3�X�nRG�~\jc3�v��ӍL��M[JB�T��s3}��j�Nʖ��W����;7��ç?=X�F=-�=����q�ߚ���#���='�c��7���ڑW�I(O+=:uxq�������������e2�zi+�kuG�R��������0�&e�n���iT^J����~\jy���p'dtG��s����O��3����9* �b#Ɋ�� p������[Bws�T�>d4�ۧs���nv�n���U���_�~,�v����ƜJ1��s�� �QIz��)�(lv8M���U=�;����56��G���s#�K���MP�=��LvyGd��}�VwWBF�'�à �?MH�U�g2�� ����!�p�7Q��j��ڴ����=��j�u��� Jn�A s���uM������e��Ɔ�Ҕ�!)'��8Ϣ�ٔ��ޝ(��Vp���צ֖d=�IC�J�Ǡ{q������kԭ�߸���i��@K����u�|�p=..�*+����x�����z[Aqġ#s2a�Ɗ���RR�)*HRsi�~�a &f��M��P����-K�L@��Z��Xy�'x�{}��Zm+���:�)�) IJ�-i�u���� ���ܒH��'�L(7�y�GӜq���� j��� 6ߌg1�g�o���,kر���tY�?W,���p���e���f�OQS��!K�۟cҒA�|ս�j�>��=⬒��˧L[�� �߿2JaB~R��u�:��Q�] �0H~���]�7��Ƽ�I���(}��cq '�ήET���q�?f�ab���ӥvr� �)o��-Q��_'����ᴎo��K������;��V���o��%���~OK ����*��b�f:���-ťIR��`B�5!RB@���ï�� �u �̯e\�_U�_������� g�ES��3�������QT��a����x����U<~�c?�*�#]�MW,[8O�a�x��]�1bC|踤�P��lw5V%�)�{t�<��d��5���0i�XSU��m:��Z�┵�i�"��1�^B�-��P�hJ��&)O��*�D��c�W��vM��)����}���P��ܗ-q����\mmζZ-l@�}��a��E�6��F�@��&Sg@���ݚ�M����� ȹ 4����#p�\H����dYDo�H���"��\��..R�B�H�z_�/5˘����6��KhJR��P�mƶi�m���3�,#c�co��q�a)*Pt����R�m�k�7x�D�E�\Y�閣_X�<���~�)���c[[�BP����6�Yq���S��0����%_����;��Àv�~�| VS؇ ��'O0��F0��\���U�-�d@�����7�SJ*z��3n��y��P����O���������m�~�P�3|Y��ʉr#�C�<�G~�.,! ���bqx���h~0=��!ǫ�jy����l�O,�[B��~��|9��ٱ����Xly�#�i�B��g%�S��������tˋ���e���ې��\[d�t)��.+u�|1 ������#�~Oj����hS�%��i.�~X���I�H�m��0n���c�1uE�q��cF�RF�o���7� �O�ꮧ� ���ۛ{��ʛi5�rw?׌#Qn�TW��~?y$��m\�\o����%W� ?=>S�N@�� �Ʈ���R����N�)�r"C�:��:����� �����#��qb��Y�. �6[��2K����2u�Ǧ�HYR��Q�MV��� �G�$��Q+.>�����nNH��q�^��� ����q��mM��V��D�+�-�#*�U�̒ ���p욳��u:�������IB���m���PV@O���r[b= �� ��1U�E��_Nm�yKbN�O���U�}�the�`�|6֮P>�\2�P�V���I�D�i�P�O;�9�r�mAHG�W�S]��J*�_�G��+kP�2����Ka�Z���H�'K�x�W�MZ%�O�YD�Rc+o��?�q��Ghm��d�S�oh�\�D�|:W������UA�Qc yT�q������~^�H��/��#p�CZ���T�I�1�ӏT����4��"�ČZ�����}��`w�#�*,ʹ�� ��0�i��課�Om�*�da��^gJ݅{���l�e9uF#T�ֲ��̲�ٞC"�q���ߍ ոޑ�o#�XZTp����@ o�8��(jd��xw�]�,f���`~�|,s��^����f�1���t��|��m�򸄭/ctr��5s��7�9Q�4�H1꠲BB@l9@���C�����+�wp�xu�£Yc�9��?`@#�o�mH�s2��)�=��2�.�l����jg�9$�Y�S�%*L������R�Y������7Z���,*=�䷘$�������arm�o�ϰ���UW.|�r�uf����IGw�t����Zwo��~5 ��YյhO+=8fF�)�W�7�L9lM�̘·Y���֘YLf�큹�pRF���99.A �"wz��=E\Z���'a� 2��Ǚ�#;�'}�G���*��l��^"q��+2FQ� hj��kŦ��${���ޮ-�T�٭cf�|�3#~�RJ����t��$b�(R��(����r���dx� >U b�&9,>���%E\� Ά�e�$��'�q't��*�א���ެ�b��-|d���SB�O�O��$�R+�H�)�܎�K��1m`;�J�2�Y~9��O�g8=vqD`K[�F)k�[���1m޼c��n���]s�k�z$@��)!I �x՝"v��9=�ZA=`Ɠi �:�E��)`7��vI��}d�YI�_ �o�:ob���o ���3Q��&D&�2=�� �Ά��;>�h����y.*ⅥS������Ӭ�+q&����j|UƧ����}���J0��WW< ۋS�)jQR�j���Ư��rN)�Gű�4Ѷ(�S)Ǣ�8��i��W52���No˓� ۍ%�5brOn�L�;�n��\G����=�^U�dI���8$�&���h��'���+�(������cȁ߫k�l��S^���cƗjԌE�ꭔ��gF���Ȓ��@���}O���*;e�v�WV���YJ\�]X'5��ղ�k�F��b 6R�o՜m��i N�i����>J����?��lPm�U��}>_Z&�KK��q�r��I�D�Չ~�q�3fL�:S�e>���E���-G���{L�6p�e,8��������QI��h��a�Xa��U�A'���ʂ���s�+טIjP�-��y�8ۈZ?J$��W�P� ��R�s�]��|�l(�ԓ��sƊi��o(��S0��Y� 8�T97.�����WiL��c�~�dxc�E|�2!�X�K�Ƙਫ਼�$((�6�~|d9u+�qd�^3�89��Y�6L�.I�����?���iI�q���9�)O/뚅����O���X��X�V��ZF[�یgQ�L��K1���RҖr@v�#��X�l��F���Нy�S�8�7�kF!A��sM���^rkp�jP�DyS$N���q��nxҍ!U�f�!eh�i�2�m���`�Y�I�9r�6� �TF���C}/�y�^���Η���5d�'��9A-��J��>{�_l+�`��A���[�'��յ�ϛ#w:݅�%��X�}�&�PSt�Q�"�-��\縵�/����$Ɨh�Xb�*�y��BS����;W�ջ_mc�����vt?2}1�;qS�d�d~u:2k5�2�R�~�z+|HE!)�Ǟl��7`��0�<�,�2*���Hl-��x�^����'_TV�gZA�'j� ^�2Ϊ��N7t�����?w�� �x1��f��Iz�C-Ȗ��K�^q�;���-W�DvT�7��8�Z�������� hK�(P:��Q- �8�n�Z���܃e貾�<�1�YT<�,�����"�6{/ �?�͟��|1�:�#g��W�>$����d��J��d�B��=��jf[��%rE^��il:��B���x���Sּ�1հ��,�=��*�7 fcG��#q� �eh?��2�7�����,�!7x��6�n�LC�4x��},Geǝ�tC.��vS �F�43��zz\��;QYC,6����~;RYS/6���|2���5���v��T��i����������mlv��������&� �nRh^ejR�LG�f���? �ۉҬܦƩ��|��Ȱ����>3����!v��i�ʯ�>�v��オ�X3e���_1z�Kȗ\<������!�8���V��]��?b�k41�Re��T�q��mz��TiOʦ�Z��Xq���L������q"+���2ۨ��8}�&N7XU7Ap�d�X��~�׿��&4e�o�F��� �H����O���č�c�� 懴�6���͉��+)��v;j��ݷ�� �UV�� i��� j���Y9GdÒJ1��詞�����V?h��l����l�cGs�ځ�������y�Ac�����\V3�? �� ܙg�>qH�S,�E�W�[�㺨�uch�⍸�O�}���a��>�q�6�n6����N6�q������N ! 1AQaq�0@����"2BRb�#Pr���3C`��Scst���$4D���%Td�� ?���N����a��3��m���C���w��������xA�m�q�m���m������$����4n淿t'��C"w��zU=D�\R+w�p+Y�T�&�պ@��ƃ��3ޯ?�Aﶂ��aŘ���@-�����Q�=���9D��ռ�ѻ@��M�V��P��܅�G5�f�Y<�u=,EC)�<�Fy'�"�&�չ�X~f��l�KԆV��?�� �W�N����=(� �;���{�r����ٌ�Y���h{�١������jW����P���Tc�����X�K�r��}���w�R��%��?���E��m�� �Y�q|����\lEE4���r���}�lsI�Y������f�$�=�d�yO����p�����yBj8jU�o�/�S��?�U��*������ˍ�0������u�q�m [�?f����a�� )Q�>����6#������� ?����0UQ����,IX���(6ڵ[�DI�MNލ�c&���υ�j\��X�R|,4��� j������T�hA�e��^���d���b<����n�� �즇�=!���3�^�`j�h�ȓr��jẕ�c�,ٞX����-����a�ﶔ���#�$��]w�O��Ӫ�1y%��L�Y<�wg#�ǝ�̗`�x�xa�t�w��»1���o7o5��>�m뭛C���Uƃߜ}�C���y1Xνm�F8�jI���]����H���ۺиE@I�i;r�8ӭ����V�F�Շ| ��&?�3|x�B�MuS�Ge�=Ӕ�#BE5G�����Y!z��_e��q�р/W>|-�Ci߇�t�1ޯќd�R3�u��g�=0 5��[?�#͏��q�cf���H��{ ?u�=?�?ǯ���}Z��z���hmΔ�BFTW�����<�q�(v� ��!��z���iW]*�J�V�z��gX֧A�q�&��/w���u�gYӘa���; �i=����g:��?2�dž6�ى�k�4�>�Pxs����}������G�9��3 ���)gG�R<>r h�$��'nc�h�P��Bj��J�ҧH� -��N1���N��?��~��}-q!=��_2hc�M��l�vY%UE�@|�v����M2�.Y[|y�"Eï��K�ZF,�ɯ?,q�?v�M 80jx�"�;�9vk�����+ ֧�� �ȺU��?�%�vcV��mA�6��Qg^M����A}�3�nl� QRN�l8�kkn�'�����(��M�7m9و�q���%ޟ���*h$Zk"��$�9��: �?U8�Sl��,,|ɒ��xH(ѷ����Gn�/Q�4�P��G�%��Ա8�N��!� �&�7�;���eKM7�4��9R/%����l�c>�x;������>��C�:�����t��h?aKX�bhe�ᜋ^�$�Iհ �hr7%F$�E��Fd���t��5���+�(M6�t����Ü�UU|zW�=a�Ts�Tg������dqP�Q����b'�m���1{|Y����X�N��b �P~��F^F:����k6�"�j!�� �I�r�`��1&�-$�Bevk:y���#yw��I0��x��=D�4��tU���P�ZH��ڠ底taP��6����b>�xa����Q�#� WeF��ŮNj�p�J* mQ�N����*I�-*�ȩ�F�g�3 �5��V�ʊ�ɮ�a��5F���O@{���NX��?����H�]3��1�Ri_u��������ѕ�� ����0��� F��~��:60�p�͈�S��qX#a�5>���`�o&+�<2�D����: �������ڝ�$�nP���*)�N�|y�Ej�F�5ټ�e���ihy�Z �>���k�bH�a�v��h�-#���!�Po=@k̆IEN��@��}Ll?j�O������߭�ʞ���Q|A07x���wt!xf���I2?Z��<ץ�T���cU�j��]��陎Ltl �}5�ϓ��$�,��O�mˊ�;�@O��jE��j(�ا,��LX���LO���Ц�90�O �.����a��nA���7������j4 ��W��_ٓ���zW�jcB������y՗+EM�)d���N�g6�y1_x��p�$Lv:��9�"z��p���ʙ$��^��JԼ*�ϭ����o���=x�Lj�6�J��u82�A�H�3$�ٕ@�=Vv�]�'�qEz�;I˼��)��=��ɯ���x �/�W(V���p�����$ �m�������u�����񶤑Oqˎ�T����r��㠚x�sr�GC��byp�G��1ߠ�w e�8�$⿄����/�M{*}��W�]˷.�CK\�ުx���/$�WPw���r� |i���&�}�{�X� �>��$-��l���?-z���g����lΆ���(F���h�vS*���b���߲ڡn,|)mrH[���a�3�ר�[1��3o_�U�3�TC�$��(�=�)0�kgP���� ��u�^=��4 �WYCҸ:��vQ�ר�X�à��tk�m,�t*��^�,�}D*� �"(�I��9R����>`�`��[~Q]�#af��i6l��8���6�:,s�s�N6�j"�A4���IuQ��6E,�GnH��zS�HO�uk�5$�I�4��ؤ�Q9�@��C����wp�BGv[]�u�Ov���0I4���\��y�����Q�Ѹ��~>Z��8�T��a��q�ޣ;z��a���/��S��I:�ܫ_�|������>=Z����8:�S��U�I�J��"IY���8%b8���H��:�QO�6�;7�I�S��J��ҌAά3��>c���E+&jf$eC+�z�;��V����� �r���ʺ������my�e���aQ�f&��6�ND��.:��NT�vm�<- u���ǝ\MvZY�N�NT��-A�>jr!S��n�O 1�3�Ns�%�3D@���`������ܟ 1�^c<���� �a�ɽ�̲�Xë#�w�|y�cW�=�9I*H8�p�^(4���՗�k��arOcW�tO�\�ƍR��8����'�K���I�Q�����?5�>[�}��yU�ײ -h��=��% q�ThG�2�)���"ו3]�!kB��*p�FDl�A���,�eEi�H�f�Ps�����5�H:�Փ~�H�0Dت�D�I����h�F3�������c��2���E��9�H��5�zԑ�ʚ�i�X�=:m�xg�hd(�v����׊�9iS��O��d@0ڽ���:�p�5�h-��t�&���X�q�ӕ,��ie�|���7A�2���O%P��E��htj��Y1��w�Ѓ!����  ���� ࢽ��My�7�\�a�@�ţ�J �4�Ȼ�F�@o�̒?4�wx��)��]�P��~�����u�����5�����7X ��9��^ܩ�U;Iꭆ 5 �������eK2�7(�{|��Y׎ �V��\"���Z�1� Z�����}��(�Ǝ"�1S���_�vE30>���p;� ΝD��%x�W�?W?v����o�^V�i�d��r[��/&>�~`�9Wh��y�;���R��� ;;ɮT��?����r$�g1�K����A��C��c��K��l:�'��3 c�ﳯ*"t8�~l��)���m��+U,z��`(�>yJ�?����h>��]��v��ЍG*�{`��;y]��I�T� ;c��NU�fo¾h���/$���|NS���1�S�"�H��V���T���4��uhǜ�]�v;���5�͠x��'C\�SBpl���h}�N����� A�Bx���%��ޭ�l��/����T��w�ʽ]D�=����K���ž�r㻠l4�S�O?=�k �M:� ��c�C�a�#ha���)�ѐxc�s���gP�iG��{+���x���Q���I= �� z��ԫ+ �8"�k�ñ�j=|����c ��y��CF��/��*9ж�h{ �?4�o� ��k�m�Q�N�x��;�Y��4膚�a�w?�6�>e]�����Q�r�:����g�,i"�����ԩA�*M�<�G��b�if��l^M��5� �Ҩ�{����6J��ZJ�����P�*�����Y���ݛu�_4�9�I8�7���������,^ToR���m4�H��?�N�S�ѕw��/S��甍�@�9H�S�T��t�ƻ���ʒU��*{Xs�@����f�����֒Li�K{H�w^���������Ϥm�tq���s� ���ք��f:��o~s��g�r��ט� �S�ѱC�e]�x���a��) ���(b-$(�j>�7q�B?ӕ�F��hV25r[7 Y� }L�R��}����*sg+��x�r�2�U=�*'WS��ZDW]�WǞ�<��叓���{�$�9Ou4��y�90-�1�'*D`�c�^o?(�9��u���ݐ��'PI&� f�Jݮ�������:wS����jfP1F:X �H�9dԯ���˝[�_54 �}*;@�ܨ�� ð�yn�T���?�ןd�#���4rG�ͨ��H�1�|-#���Mr�S3��G�3�����)�.᧏3v�z֑��r����$G"�`j �1t��x0<Ɔ�Wh6�y�6��,œ�Ga��gA����y��b��)��h�D��ß�_�m��ü �gG;��e�v��ݝ�nQ� ��C����-�*��o���y�a��M��I�>�<���]obD��"�:���G�A��-\%LT�8���c�)��+y76���o�Q�#*{�(F�⽕�y����=���rW�\p���۩�c���A���^e6��K������ʐ�cVf5$�'->���ՉN"���F�"�UQ@�f��Gb~��#�&�M=��8�ט�JNu9��D��[̤�s�o�~������ G��9T�tW^g5y$b��Y'��س�Ǵ�=��U-2 #�MC�t(�i� �lj�@Q 5�̣i�*�O����s�x�K�f��}\��M{E�V�{�υ��Ƈ�����);�H����I��fe�Lȣr�2��>��W�I�Ȃ6������i��k�� �5�YOxȺ����>��Y�f5'��|��H+��98pj�n�.O�y�������jY��~��i�w'������l�;�s�2��Y��:'lg�ꥴ)o#'Sa�a�K��Z� �m��}�`169�n���"���x��I ��*+� }F<��cГ���F�P�������ֹ*�PqX�x۩��,� ��N�� �4<-����%����:��7����W���u�`����� $�?�I��&����o��o��`v�>��P��"��l���4��5'�Z�gE���8���?��[�X�7(��.Q�-��*���ތL@̲����v��.5���[��=�t\+�CNܛ��,g�SQnH����}*F�G16���&:�t��4ُ"A��̣��$�b �|����#rs��a�����T�� ]�<�j��BS�('$�ɻ� �wP;�/�n��?�ݜ��x�F��yUn�~mL*-�������Xf�wd^�a�}��f�,=t�׵i�.2/wpN�Ep8�OР���•��R�FJ� 55TZ��T �ɭ�<��]��/�0�r�@�f��V��V����Nz�G��^���7hZi����k��3�,kN�e|�vg�1{9]_i��X5y7� 8e]�U����'�-2,���e"����]ot�I��Y_��n�(JҼ��1�O ]bXc���Nu�No��pS���Q_���_�?i�~�x h5d'�(qw52] ��'ޤ�q��o1�R!���`ywy�A4u���h<קy���\[~�4�\ X�Wt/� 6�����n�F�a8��f���z �3$�t(���q��q�x��^�XWeN'p<-v�!�{�(>ӽDP7��ո0�y)�e$ٕv�Ih'Q�EA�m*�H��RI��=:��� ���4牢) �%_iN�ݧ�l]� �Nt���G��H�L��� ɱ�g<���1V�,�J~�ٹ�"K��Q�� 9�HS�9�?@��k����r�;we݁�]I�!{ �@�G�[�"��`���J:�n]�{�cA�E����V��ʆ���#��U9�6����j�#Y�m\��q�e4h�B�7��C�������d<�?J����1g:ٳ���=Y���D�p�ц� ׈ǔ��1�]26؜oS�'��9�V�FVu�P�h�9�xc�oq�X��p�o�5��Ա5$�9W�V(�[Ak�aY錎qf;�'�[�|���b�6�Ck��)��#a#a˙��8���=äh�4��2��C��4tm^ �n'c���]GQ$[Wҿ��i���vN�{Fu ��1�gx��1┷���N�m��{j-,��x�� Ūm�ЧS�[�s���Gna���䑴�� x�p 8<������97�Q���ϴ�v�aϚG��Rt�Һ׈�f^\r��WH�JU�7Z���y)�vg=����n��4�_)y��D'y�6�]�c�5̪�\� �PF�k����&�c;��cq�$~T�7j ���nç]�<�g ":�to�t}�159�<�/�8������m�b�K#g'I'.W�����6��I/��>v��\�MN��g���m�A�yQL�4u�Lj�j9��#44�t��l^�}L����n��R��!��t��±]��r��h6ٍ>�yҏ�N��fU�� ���� Fm@�8}�/u��jb9������he:A�y�ծw��GpΧh�5����l}�3p468��)U��d��c����;Us/�֔�YX�1�O2��uq�s��`hwg�r~�{ R��mhN��؎*q 42�*th��>�#���E����#��Hv�O����q�}�����6�e��\�,Wk�#���X��b>��p}�դ��3���T5��†��6��[��@�P�y*n��|'f�֧>�lư΂�̺����SU�'*�q�p�_S�����M�� '��c�6�����m�� ySʨ;M��r���Ƌ�m�Kxo,���Gm�P��A�G�:��i��w�9�}M(�^�V��$ǒ�ѽ�9���|���� �a����J�SQ�a���r�B;����}���ٻ֢�2�%U���c�#�g���N�a�ݕ�'�v�[�OY'��3L�3�;,p�]@�S��{ls��X�'���c�jw�k'a�.��}�}&�� �dP�*�bK=ɍ!����;3n�gΊU�ߴmt�'*{,=SzfD� A��ko~�G�aoq�_mi}#�m�������P�Xhύ����mxǍ�΂���巿zf��Q���c���|kc�����?���W��Y�$���_Lv����l߶��c���`?����l�j�ݲˏ!V��6����U�Ђ(A���4y)H���p�Z_�x��>���e��R��$�/�`^'3qˏ�-&Q�=?��CFVR �D�fV�9��{�8g�������n�h�(P"��6�[�D���< E�����~0<@�`�G�6����Hг�cc�� �c�K.5��D��d�B���`?�XQ��2��ٿyqo&+�1^� DW�0�ꊩ���G�#��Q�nL3��c���������/��x ��1�1[y�x�პCW��C�c�UĨ80�m�e�4.{�m��u���I=��f�����0QRls9���f���������9���~f�����Ǩ��a�"@�8���ȁ�Q����#c�ic������G��$���G���r/$W�(��W���V�"��m�7�[m�A�m����bo��D� j����۳� l���^�k�h׽����� ��#� iXn�v��eT�k�a�^Y�4�BN��ĕ��0 !01@Q"2AaPq3BR������?���@4�Q�����T3,���㺠�W�[=JK�Ϟ���2�r^7��vc�:�9 �E�ߴ�w�S#d���Ix��u��:��Hp��9E!�� V 2;73|F��9Y���*ʬ�F��D����u&���y؟��^EA��A��(ɩ���^��GV:ݜDy�`��Jr29ܾ�㝉��[���E;Fzx��YG��U�e�Y�C���� ����v-tx����I�sם�Ę�q��Eb�+P\ :>�i�C'�;�����k|z�رn�y]�#ǿb��Q��������w�����(�r|ӹs��[�D��2v-%��@;�8<a���[\o[ϧw��I!��*0�krs)�[�J9^��ʜ��p1)� "��/_>��o��<1����A�E�y^�C��`�x1'ܣn�p��s`l���fQ��):�l����b>�Me�jH^?�kl3(�z:���1ŠK&?Q�~�{�ٺ�h�y���/�[��V�|6��}�KbX����mn[-��7�5q�94�������dm���c^���h� X��5��<�eޘ>G���-�}�دB�ޟ� ��|�rt�M��V+�]�c?�-#ڛ��^ǂ}���Lkr���O��u�>�-D�ry� D?:ޞ�U��ǜ�7�V��?瓮�"�#���r��չģVR;�n���/_� ؉v�ݶe5d�b9��/O��009�G���5n�W����JpA�*�r9�>�1��.[t���s�F���nQ� V 77R�]�ɫ8����_0<՜�IF�u(v��4��F�k�3��E)��N:��yڮe��P�`�1}�$WS��J�SQ�N�j�ٺ��޵�#l���ј(�5=��5�lǏmoW�v-�1����v,W�mn��߀$x�<����v�j(����c]��@#��1������Ǔ���o'��u+����;G�#�޸��v-lη��/(`i⣍Pm^���ԯ̾9Z��F��������n��1��� ��]�[��)�'������:�֪�W��FC����� �B9،!?���]��V��A�Վ�M��b�w��G F>_DȬ0¤�#�QR�[V��kz���m�w�"��9ZG�7'[��=�Q����j8R?�zf�\a�=��O�U����*oB�A�|G���2�54 �p��.w7� �� ��&������ξxGHp� B%��$g�����t�Џ򤵍z���HN�u�Я�-�'4��0��;_��3 !01"@AQa2Pq#3BR������?��ʩca��en��^��8���<�u#��m*08r��y�N"�<�Ѳ0��@\�p��� �����Kv�D��J8�Fҽ� �f�Y��-m�ybX�NP����}�!*8t(�OqѢ��Q�wW�K��ZD��Δ^e��!� ��B�K��p~�����e*l}z#9ң�k���q#�Ft�o��S�R����-�w�!�S���Ӥß|M�l޶V��!eˈ�8Y���c�ЮM2��tk���� ������J�fS����Ö*i/2�����n]�k�\���|4yX�8��U�P.���Ы[���l��@"�t�<������5�lF���vU�����W��W��;�b�cД^6[#7@vU�xgZv��F�6��Q,K�v��� �+Ъ��n��Ǣ��Ft���8��0��c�@�!�Zq s�v�t�;#](B��-�nῃ~���3g������5�J�%���O������n�kB�ĺ�.r��+���#�N$?�q�/�s�6��p��a����a��J/��M�8��6�ܰ"�*������ɗud"\w���aT(����[��F��U՛����RT�b���n�*��6���O��SJ�.�ij<�v�MT��R\c��5l�sZB>F��<7�;EA��{��E���Ö��1U/�#��d1�a�n.1ě����0�ʾR�h��|�R��Ao�3�m3 ��%�� ���28Q� ��y��φ���H�To�7�lW>����#i`�q���c����a��� �m,B�-j����݋�'mR1Ήt�>��V��p���s�0IbI�C.���1R�ea�����]H�6����������4B>��o��](��$B���m�����a�!=��?�B� K�Ǿ+�Ծ"�n���K��*��+��[T#�{E�J�S����Q�����s�5�:�U�\wĐ�f�3����܆&�)����I���Ԇw��E T�lrTf6Q|R�h:��[K�� �z��c֧�G�C��%\��_�a�84��HcO�bi��ؖV��7H �)*ģK~Xhչ0��4?�0��� �E<���}3���#���u�?�� ��|g�S�6ꊤ�|�I#Hڛ� �ա��w�X��9��7���Ŀ%�SL��y6č��|�F�a 8���b��$�sק�h���b9RAu7�˨p�Č�_\*w��묦��F ����4D~�f����|(�"m���NK��i�S�>�$d7SlA��/�²����SL��|6N�}���S�˯���g��]6��; �#�.��<���q'Q�1|KQ$�����񛩶"�$r�b:���N8�w@��8$�� �AjfG|~�9F ���Y��ʺ��Bwؒ������M:I岎�G��`s�YV5����6��A �b:�W���G�q%l�����F��H���7�������Fsv7��k�� 403WebShell
403Webshell
Server IP : 54.89.25.11  /  Your IP : 216.73.216.134
Web Server : Apache/2.4.7 (Ubuntu)
System : Linux ip-172-31-88-18 3.13.0-74-generic #118-Ubuntu SMP Thu Dec 17 22:52:10 UTC 2015 x86_64
User : www-data ( 33)
PHP Version : 5.5.9-1ubuntu4.24
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,
MySQL : ON  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/share/doc/python-twisted-web/howto/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/share/doc/python-twisted-web/howto/twisted-templates.html
<?xml version="1.0" encoding="utf-8"?><!DOCTYPE html  PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN'  'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'><html lang="en" xmlns="http://www.w3.org/1999/xhtml">
  <head>
<title>Twisted Documentation: HTML Templating with twisted.web.template</title>
<link href="stylesheet.css" rel="stylesheet" type="text/css"/>
  </head>

  <body bgcolor="white">
    <h1 class="title">HTML Templating with twisted.web.template</h1>
    <div class="toc"><ol><li><a href="#auto0">A Very Quick Introduction To Templating In Python</a></li><li><a href="#auto1">twisted.web.template - Why And How you Might Want to Use It</a></li><ul><li><a href="#auto2">Template Attributes</a></li><li><a href="#auto3">Slots</a></li><li><a href="#auto4">Iteration</a></li><li><a href="#auto5">Sub-views</a></li><li><a href="#auto6">Transparent</a></li></ul><li><a href="#auto7">Quoting</a></li><li><a href="#auto8">Deferreds</a></li><li><a href="#auto9">A Brief Note on Formats and DOCTYPEs</a></li><li><a href="#auto10">A Bit of History</a></li></ol></div>
    <div class="content">
<span/>
<h2>A Very Quick Introduction To Templating In Python<a name="auto0"/></h2>
<p>
HTML templating is the process of transforming a template document (one which
describes style and structure, but does not itself include any content) into
some HTML output which includes information about objects in your application.
There are many, many libraries for doing this in Python: to name a few, <a href="http://jinja.pocoo.org/" shape="rect">jinja2</a>, <a href="http://docs.djangoproject.com/en/dev/ref/templates/" shape="rect">django templates</a>,
and <a href="http://www.clearsilver.net/" shape="rect">clearsilver</a>.  You can easily use
any of these libraries in your Twisted Web application, either by running them
as <a href="web-in-60/wsgi.html" shape="rect">WSGI applications</a> or by calling your
preferred templating system's APIs to produce their output as strings, and then
writing those strings to <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.http.Request.write.html" title="twisted.web.http.Request.write">Request.write</a></code>.
</p>
<p>Before we begin explaining how to use it, I'd like to stress that you
don't <i>need</i> to use Twisted's templating system if you prefer some other
way to generate HTML.  Use it if it suits your personal style or your
application, but feel free to use other things.  Twisted includes templating for
its own use, because the <code>twisted.web</code> server needs to produce HTML
in various places, and we didn't want to add another large dependency for that.
Twisted is <em>not</em> in any way incompatible with other systems, so that has
nothing to do with the fact that we use our own.</p>
<p>
</p>
<h2>twisted.web.template - Why And How you Might Want to Use It<a name="auto1"/></h2>
<p>
Twisted includes a templating system, <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.html" title="twisted.web.template">twisted.web.template</a></code>.  This can be convenient for Twisted
applications that want to produce some basic HTML for a web interface without an
additional dependency.
</p>
<p>
<code>twisted.web.template</code> also includes
support for <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.internet.defer.Deferred.html" title="twisted.internet.defer.Deferred">Deferred</a></code>s, so
you can incrementally render the output of a page based on the results of <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.internet.defer.Deferred.html" title="twisted.internet.defer.Deferred">Deferred</a></code>s that your application
has returned.  This feature is fairly unique among templating libraries.
</p>
<p>
In <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.html" title="twisted.web.template">twisted.web.template</a></code>, templates are XHTML files
which also contain a special namespace for indicating dynamic portions of the
document. For example:
</p>
<div class="html-listing"><pre class="htmlsource">
&lt;html xmlns:t=&quot;http://twistedmatrix.com/ns/twisted.web.template/0.1&quot;&gt;
&lt;body&gt;
  &lt;div t:render=&quot;header&quot; /&gt;
  &lt;div id=&quot;content&quot;&gt;
    &lt;p&gt;Content goes here.&lt;/p&gt;
  &lt;/div&gt;
  &lt;div t:render=&quot;footer&quot; /&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><div class="caption">template example - <a href="listings/template-1.xml"><span class="filename">listings/template-1.xml</span></a></div></div>
The basic unit of templating is <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.Element.html" title="twisted.web.template.Element">twisted.web.template.Element</a></code>. An Element is given a way of
loading a bit of markup like the above example, and knows how to
correlate <code>render</code> attributes within that markup to Python methods
exposed with <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.renderer.html" title="twisted.web.template.renderer">twisted.web.template.renderer</a></code>:
<div class="py-listing"><pre><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">template</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Element</span>, <span class="py-src-variable">renderer</span>, <span class="py-src-variable">XMLFile</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span>.<span class="py-src-variable">filepath</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">FilePath</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">ExampleElement</span>(<span class="py-src-parameter">Element</span>):
    <span class="py-src-variable">loader</span> = <span class="py-src-variable">XMLFile</span>(<span class="py-src-variable">FilePath</span>(<span class="py-src-string">'template-1.xml'</span>))

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">header</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-string">'Header.'</span>)

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">footer</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-string">'Footer.'</span>)
</pre><div class="caption">element example - <a href="listings/element_1.py"><span class="filename">listings/element_1.py</span></a></div></div>
In order to combine the two, we must render the element.  For this simple
example, we can use the <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.flattenString.html" title="twisted.web.template.flattenString">flattenString</a></code> API, which will convert a
single template object - such as an <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.Element.html" title="twisted.web.template.Element">Element</a></code> - into a <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.internet.defer.Deferred.html" title="twisted.internet.defer.Deferred">Deferred</a></code> which fires with a single string,
the HTML output of the rendering process.
<div class="py-listing"><pre><p class="py-linenumber">1
2
3
4
5
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">template</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">flattenString</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">element_1</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">ExampleElement</span>
<span class="py-src-keyword">def</span> <span class="py-src-identifier">renderDone</span>(<span class="py-src-parameter">output</span>):
    <span class="py-src-keyword">print</span> <span class="py-src-variable">output</span>
<span class="py-src-variable">flattenString</span>(<span class="py-src-variable">None</span>, <span class="py-src-variable">ExampleElement</span>()).<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">renderDone</span>)
</pre><div class="caption">rendering snippet - <a href="listings/render_1.py"><span class="filename">listings/render_1.py</span></a></div></div>
<p>This short program cheats a little bit; we know that there are no <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.internet.defer.Deferred.html" title="twisted.internet.defer.Deferred">Deferred</a></code>s in the template which
require the reactor to eventually fire; therefore, we can simply add a callback
which outputs the result.  Also, none of the <code>renderer</code> functions
require the <code>request</code> object, so it's acceptable to
pass <code>None</code> through here.  (The 'request' object here is used only to
relay information about the rendering process to each renderer, so you may
always use whatever object makes sense for your application.  Note, however,
that renderers from library code may require an <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.iweb.IRequest.html" title="twisted.web.iweb.IRequest">IRequest</a></code>.)</p>
<p>
If you run it yourself, you can see that it produces the following output:
</p>
<div class="html-listing"><pre class="htmlsource">
&lt;html&gt;
&lt;body&gt;
  &lt;div&gt;Header.&lt;/div&gt;
  &lt;div id=&quot;content&quot;&gt;
    &lt;p&gt;Content goes here.&lt;/p&gt;
  &lt;/div&gt;
  &lt;div&gt;Footer.&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><div class="caption">rendering output 1 - <a href="listings/output-1.html"><span class="filename">listings/output-1.html</span></a></div></div>
The third parameter to a renderer method is a <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.Tag.html" title="twisted.web.template.Tag">Tag</a></code> object which represents the XML element
with the <code>t:render</code> attribute in the template. Calling a <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.Tag.html" title="twisted.web.template.Tag">Tag</a></code> adds children to the element
in the DOM, which may be strings, more <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.Tag.html" title="twisted.web.template.Tag">Tag</a></code>s, or other renderables such as <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.Element.html" title="twisted.web.template.Element">Element</a></code>s.
For example, to make the header and footer bold:
<div class="py-listing"><pre><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">template</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Element</span>, <span class="py-src-variable">renderer</span>, <span class="py-src-variable">XMLFile</span>, <span class="py-src-variable">tags</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span>.<span class="py-src-variable">filepath</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">FilePath</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">ExampleElement</span>(<span class="py-src-parameter">Element</span>):
    <span class="py-src-variable">loader</span> = <span class="py-src-variable">XMLFile</span>(<span class="py-src-variable">FilePath</span>(<span class="py-src-string">'template-1.xml'</span>))

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">header</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">b</span>(<span class="py-src-string">'Header.'</span>))

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">footer</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">b</span>(<span class="py-src-string">'Footer.'</span>))
</pre><div class="caption">tag manipulation example - <a href="listings/element_2.py"><span class="filename">listings/element_2.py</span></a></div></div>

Rendering this in a similar way to the first example would produce:

<div class="html-listing"><pre class="htmlsource">
&lt;html&gt;
&lt;body&gt;
  &lt;div&gt;&lt;b&gt;Header.&lt;/b&gt;&lt;/div&gt;
  &lt;div id=&quot;content&quot;&gt;
    &lt;p&gt;Content goes here.&lt;/p&gt;
  &lt;/div&gt;
  &lt;div&gt;&lt;b&gt;Footer.&lt;/b&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><div class="caption">tag manipulation output - <a href="listings/output-2.html"><span class="filename">listings/output-2.html</span></a></div></div>

In addition to adding children, call syntax can be used to set attributes on a
tag. For example, to change the <code>id</code> on the <code>div</code> while
adding children:

<div class="py-listing"><pre><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">template</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Element</span>, <span class="py-src-variable">renderer</span>, <span class="py-src-variable">XMLFile</span>, <span class="py-src-variable">tags</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span>.<span class="py-src-variable">filepath</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">FilePath</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">ExampleElement</span>(<span class="py-src-parameter">Element</span>):
    <span class="py-src-variable">loader</span> = <span class="py-src-variable">XMLFile</span>(<span class="py-src-variable">FilePath</span>(<span class="py-src-string">'template-1.xml'</span>))

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">header</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">p</span>(<span class="py-src-string">'Header.'</span>), <span class="py-src-variable">id</span>=<span class="py-src-string">'header'</span>)

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">footer</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-variable">tags</span>.<span class="py-src-variable">p</span>(<span class="py-src-string">'Footer.'</span>), <span class="py-src-variable">id</span>=<span class="py-src-string">'footer'</span>)
</pre><div class="caption">attributes example - <a href="listings/element_3.py"><span class="filename">listings/element_3.py</span></a></div></div>

And this would produce the following page:

<div class="html-listing"><pre class="htmlsource">
&lt;html&gt;
&lt;body&gt;
  &lt;div id=&quot;header&quot;&gt;&lt;p&gt;Header.&lt;/p&gt;&lt;/div&gt;
  &lt;div id=&quot;content&quot;&gt;
    &lt;p&gt;Content goes here.&lt;/p&gt;
  &lt;/div&gt;
  &lt;div id=&quot;footer&quot;&gt;&lt;p&gt;Footer.&lt;/p&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><div class="caption">attributes output - <a href="listings/output-3.html"><span class="filename">listings/output-3.html</span></a></div></div>

<p>
Calling a tag mutates it, it and returns the tag itself, so you can pass it
forward and call it multiple times if you have multiple children or attributes
to add to it. <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.html" title="twisted.web.template">twisted.web.template</a></code> also exposes some
convenient objects for building more complex markup structures from within
renderer methods in the <code>tags</code> object.  In the examples above, we've
only used <code>tags.p</code> and <code>tags.b</code>, but there should be a <code>tags.x</code> for each <em>x</em> which is a valid HTML tag.  There may be
some omissions, but if you find one, please feel free to file a bug.
</p>

<h3>Template Attributes<a name="auto2"/></h3>

<code>t:attr</code> tags allow you to set HTML attributes
(like <code>href</code> in an <code>&lt;a href=&quot;...</code>) on an enclosing
element.

<h3>Slots<a name="auto3"/></h3>

<code>t:slot</code> tags allow you to specify &quot;slots&quot; which you can
conveniently fill with multiple pieces of data straight from your Python
program.

The following example demonstrates both <code>t:attr</code>
and <code>t:slot</code> in action. Here we have a layout which displays a person's
profile on your snazzy new Twisted-powered social networking site. We use
the <code>t:attr</code> tag to drop in the &quot;src&quot; attribute on the profile picture,
where the actual value of src attribute gets specified by a <code>t:slot</code>
tag <em>within</em> the <code>t:attr</code> tag. Confused? It should make more
sense when you see the code:

<div class="html-listing"><pre class="htmlsource">
&lt;div xmlns:t=&quot;http://twistedmatrix.com/ns/twisted.web.template/0.1&quot;
    t:render=&quot;person_profile&quot;
    class=&quot;profile&quot;&gt;
&lt;img&gt;&lt;t:attr name=&quot;src&quot;&gt;&lt;t:slot name=&quot;profile_image_url&quot; /&gt;&lt;/t:attr&gt;&lt;/img&gt; 
&lt;p&gt;&lt;t:slot name=&quot;person_name&quot; /&gt;&lt;/p&gt;
&lt;/div&gt;
</pre><div class="caption">slots and attributes template - <a href="listings/slots-attributes-1.xml"><span class="filename">listings/slots-attributes-1.xml</span></a></div></div>

<div class="py-listing"><pre><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">template</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Element</span>, <span class="py-src-variable">renderer</span>, <span class="py-src-variable">XMLFile</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span>.<span class="py-src-variable">filepath</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">FilePath</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">ExampleElement</span>(<span class="py-src-parameter">Element</span>):
    <span class="py-src-variable">loader</span> = <span class="py-src-variable">XMLFile</span>(<span class="py-src-variable">FilePath</span>(<span class="py-src-string">'slots-attributes-1.xml'</span>))

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">person_profile</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-comment"># Note how convenient it is to pass these attributes in!</span>
        <span class="py-src-variable">tag</span>.<span class="py-src-variable">fillSlots</span>(<span class="py-src-variable">person_name</span>=<span class="py-src-string">'Luke'</span>,
                      <span class="py-src-variable">profile_image_url</span>=<span class="py-src-string">'http://example.com/user.png'</span>)
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>
</pre><div class="caption">slots and attributes element - <a href="listings/slots_attributes_1.py"><span class="filename">listings/slots_attributes_1.py</span></a></div></div>
<div class="html-listing"><pre class="htmlsource">
&lt;div class=&quot;profile&quot;&gt;
&lt;img src=&quot;http://example.com/user.png&quot; /&gt; 
&lt;p&gt;Luke&lt;/p&gt;
&lt;/div&gt;
</pre><div class="caption">slots and attributes output - <a href="listings/slots-attributes-output.html"><span class="filename">listings/slots-attributes-output.html</span></a></div></div>

<h3>Iteration<a name="auto4"/></h3>

<p>Often, you will have a sequence of things, and want to render each of them,
repeating a part of the template for each one. This can be done by
cloning <code>tag</code> in your renderer:</p>

<div class="html-listing"><pre class="htmlsource">
&lt;ul xmlns:t=&quot;http://twistedmatrix.com/ns/twisted.web.template/0.1&quot;&gt;
    &lt;li t:render=&quot;widgets&quot;&gt;&lt;t:slot name=&quot;widgetName&quot;/&gt;&lt;/li&gt;
&lt;/ul&gt;
</pre><div class="caption">iteration template - <a href="listings/iteration-1.xml"><span class="filename">listings/iteration-1.xml</span></a></div></div>
<div class="py-listing"><pre><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">template</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Element</span>, <span class="py-src-variable">renderer</span>, <span class="py-src-variable">XMLFile</span>, <span class="py-src-variable">flattenString</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span>.<span class="py-src-variable">filepath</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">FilePath</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">WidgetsElement</span>(<span class="py-src-parameter">Element</span>):
    <span class="py-src-variable">loader</span> = <span class="py-src-variable">XMLFile</span>(<span class="py-src-variable">FilePath</span>(<span class="py-src-string">'iteration-1.xml'</span>))

    <span class="py-src-variable">widgetData</span> = [<span class="py-src-string">'gadget'</span>, <span class="py-src-string">'contraption'</span>, <span class="py-src-string">'gizmo'</span>, <span class="py-src-string">'doohickey'</span>]

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">widgets</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">for</span> <span class="py-src-variable">widget</span> <span class="py-src-keyword">in</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">widgetData</span>:
            <span class="py-src-keyword">yield</span> <span class="py-src-variable">tag</span>.<span class="py-src-variable">clone</span>().<span class="py-src-variable">fillSlots</span>(<span class="py-src-variable">widgetName</span>=<span class="py-src-variable">widget</span>)

<span class="py-src-keyword">def</span> <span class="py-src-identifier">printResult</span>(<span class="py-src-parameter">result</span>):
    <span class="py-src-keyword">print</span> <span class="py-src-variable">result</span>

<span class="py-src-variable">flattenString</span>(<span class="py-src-variable">None</span>, <span class="py-src-variable">WidgetsElement</span>()).<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">printResult</span>)
</pre><div class="caption">iteration element - <a href="listings/iteration-1.py"><span class="filename">listings/iteration-1.py</span></a></div></div>
<div class="html-listing"><pre class="htmlsource">
&lt;ul&gt;
    &lt;li&gt;gadget&lt;/li&gt;&lt;li&gt;contraption&lt;/li&gt;&lt;li&gt;gizmo&lt;/li&gt;&lt;li&gt;doohickey&lt;/li&gt;
&lt;/ul&gt;
</pre><div class="caption">iteration output - <a href="listings/iteration-output-1.xml"><span class="filename">listings/iteration-output-1.xml</span></a></div></div>

<p>This renderer works because a renderer can return anything that can be
rendered, not just <code>tag</code>. In this case, we define a generator, which
returns a thing that is iterable. We also could have returned
a <code>list</code>. Anything that is iterable will be rendered by <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.html" title="twisted.web.template">twisted.web.template</a></code> rendering each item in it. In
this case, each item is a copy of the tag the renderer received, each filled
with the name of a widget.</p>

<h3>Sub-views<a name="auto5"/></h3>

<p>Another common pattern is to delegate the rendering logic for a small part of
the page to a separate <code>Element</code>.  For example, the widgets from the
iteration example above might be more complicated to render.  You can define
an <code>Element</code> subclass which can render a single widget.  The renderer
method on the container can then yield instances of this
new <code>Element</code> subclass.</p>

<div class="py-listing"><pre><p class="py-linenumber">1
2
3
</p>&lt;<span class="py-src-variable">ul</span> <span class="py-src-variable">xmlns</span>:<span class="py-src-variable">t</span>=<span class="py-src-string">&quot;http://twistedmatrix.com/ns/twisted.web.template/0.1&quot;</span>&gt;
    &lt;<span class="py-src-variable">li</span> <span class="py-src-variable">t</span>:<span class="py-src-variable">render</span>=<span class="py-src-string">&quot;widgets&quot;</span>&gt;&lt;<span class="py-src-variable">span</span> <span class="py-src-variable">t</span>:<span class="py-src-variable">render</span>=<span class="py-src-string">&quot;name&quot;</span> /&gt;&lt;/<span class="py-src-variable">li</span>&gt;
&lt;/<span class="py-src-variable">ul</span>&gt;
</pre><div class="caption">subview template - <a href="listings/subviews-1.xml"><span class="filename">listings/subviews-1.xml</span></a></div></div>
<div class="py-listing"><pre><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">template</span> <span class="py-src-keyword">import</span> (
    <span class="py-src-variable">XMLFile</span>, <span class="py-src-variable">TagLoader</span>, <span class="py-src-variable">Element</span>, <span class="py-src-variable">renderer</span>, <span class="py-src-variable">flattenString</span>)
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span>.<span class="py-src-variable">filepath</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">FilePath</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">WidgetsElement</span>(<span class="py-src-parameter">Element</span>):
    <span class="py-src-variable">loader</span> = <span class="py-src-variable">XMLFile</span>(<span class="py-src-variable">FilePath</span>(<span class="py-src-string">'subviews-1.xml'</span>))

    <span class="py-src-variable">widgetData</span> = [<span class="py-src-string">'gadget'</span>, <span class="py-src-string">'contraption'</span>, <span class="py-src-string">'gizmo'</span>, <span class="py-src-string">'doohickey'</span>]

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">widgets</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">for</span> <span class="py-src-variable">widget</span> <span class="py-src-keyword">in</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">widgetData</span>:
            <span class="py-src-keyword">yield</span> <span class="py-src-variable">WidgetElement</span>(<span class="py-src-variable">TagLoader</span>(<span class="py-src-variable">tag</span>), <span class="py-src-variable">widget</span>)

<span class="py-src-keyword">class</span> <span class="py-src-identifier">WidgetElement</span>(<span class="py-src-parameter">Element</span>):
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">loader</span>, <span class="py-src-parameter">name</span>):
        <span class="py-src-variable">Element</span>.<span class="py-src-variable">__init__</span>(<span class="py-src-variable">self</span>, <span class="py-src-variable">loader</span>)
        <span class="py-src-variable">self</span>.<span class="py-src-variable">_name</span> = <span class="py-src-variable">name</span>

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">name</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-variable">self</span>.<span class="py-src-variable">_name</span>)

<span class="py-src-keyword">def</span> <span class="py-src-identifier">printResult</span>(<span class="py-src-parameter">result</span>):
    <span class="py-src-keyword">print</span> <span class="py-src-variable">result</span>

<span class="py-src-variable">flattenString</span>(<span class="py-src-variable">None</span>, <span class="py-src-variable">WidgetsElement</span>()).<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">printResult</span>)
</pre><div class="caption">subview element - <a href="listings/subviews-1.py"><span class="filename">listings/subviews-1.py</span></a></div></div>
<div class="html-listing"><pre class="htmlsource">
&lt;ul&gt;
      &lt;li&gt;&lt;span&gt;gadget&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;contraption&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;gizmo&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span&gt;doohickey&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
</pre><div class="caption">subview output - <a href="listings/subviews-output-1.xml"><span class="filename">listings/subviews-output-1.xml</span></a></div></div>

<p><code>TagLoader</code> lets the portion of the overall template related to
widgets be re-used for <code>WidgetElement</code>, which is otherwise a
normal <code>Element</code> subclass not much different
from <code>WidgetsElement</code>.  Notice that the <em>name</em> renderer on
the <code>span</code> tag in this template is satisfied
from <code>WidgetElement</code>, not <code>WidgetsElement</code>.</p>

<h3>Transparent<a name="auto6"/></h3>

Note how renderers, slots and attributes require you to specify a renderer on
some outer HTML element. What if you don't want to be forced to add an element
to your DOM just to drop some content into it? Maybe it messes with your
layout, and you can't get it to work in IE with that extra <code>div</code>
tag? Perhaps you need <code>t:transparent</code>, which allows you to drop some
content in without any surrounding &quot;container&quot; tag. For example:

<div class="html-listing"><pre class="htmlsource">
&lt;div xmlns:t=&quot;http://twistedmatrix.com/ns/twisted.web.template/0.1&quot;&gt;
&lt;!-- layout decision - these things need to be *siblings* --&gt;
&lt;t:transparent t:render=&quot;renderer1&quot; /&gt;
&lt;t:transparent t:render=&quot;renderer2&quot; /&gt;
&lt;/div&gt;

</pre><div class="caption">transparent template - <a href="listings/transparent-1.xml"><span class="filename">listings/transparent-1.xml</span></a></div></div>

<div class="py-listing"><pre><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">template</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Element</span>, <span class="py-src-variable">renderer</span>, <span class="py-src-variable">XMLFile</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span>.<span class="py-src-variable">filepath</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">FilePath</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">ExampleElement</span>(<span class="py-src-parameter">Element</span>):
    <span class="py-src-variable">loader</span> = <span class="py-src-variable">XMLFile</span>(<span class="py-src-variable">FilePath</span>(<span class="py-src-string">'transparent-1.xml'</span>))

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">renderer1</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-string">&quot;hello&quot;</span>)

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">renderer2</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-string">&quot;world&quot;</span>)
</pre><div class="caption">transparent element - <a href="listings/transparent_element.py"><span class="filename">listings/transparent_element.py</span></a></div></div>

<div class="html-listing"><pre class="htmlsource">
&lt;div&gt;
&lt;!-- layout decision - these things need to be *siblings* --&gt;
hello
world
&lt;/div&gt;
</pre><div class="caption">transparent rendering output - <a href="listings/transparent-output.html"><span class="filename">listings/transparent-output.html</span></a></div></div>

<h2>Quoting<a name="auto7"/></h2>

<code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.html" title="twisted.web.template">twisted.web.template</a></code> will quote any strings that place
into the DOM.  This provides protection against <a href="http://en.wikipedia.org/wiki/Cross-site_scripting" shape="rect">XSS attacks</a>, in
addition to just generally making it easy to put arbitrary strings onto a web
page, without worrying about what they might have in them.  This can easily be
demonstrated with an element using the same template from our earlier examples.
Here's an element that returns some &quot;special&quot; characters in HTML ('&lt;', '&gt;',
and '&quot;', which is special in attribute values):

<div class="py-listing"><pre><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
</p><span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">template</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Element</span>, <span class="py-src-variable">renderer</span>, <span class="py-src-variable">XMLFile</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">python</span>.<span class="py-src-variable">filepath</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">FilePath</span>

<span class="py-src-keyword">class</span> <span class="py-src-identifier">ExampleElement</span>(<span class="py-src-parameter">Element</span>):
    <span class="py-src-variable">loader</span> = <span class="py-src-variable">XMLFile</span>(<span class="py-src-variable">FilePath</span>(<span class="py-src-string">'template-1.xml'</span>))

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">header</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-string">'&lt;&lt;&lt;Header&gt;&gt;&gt;!'</span>)

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">footer</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">tag</span>(<span class="py-src-string">'&gt;&gt;&gt;&quot;Footer!&quot;&lt;&lt;&lt;'</span>, <span class="py-src-variable">id</span>=<span class="py-src-string">'&lt;&quot;fun&quot;&gt;'</span>)
</pre><div class="caption">renderers returning &quot;special&quot; characters - <a href="listings/quoting_element.py"><span class="filename">listings/quoting_element.py</span></a></div></div>

Note that they are all safely quoted in the output, and will appear in a web
browser just as you returned them from your Python method:

<div class="html-listing"><pre class="htmlsource">
&lt;html&gt;
&lt;body&gt;
  &lt;div&gt;&amp;lt;&amp;lt;&amp;lt;Header&amp;gt;&amp;gt;&amp;gt;!&lt;/div&gt;
  &lt;div id=&quot;content&quot;&gt;
    &lt;p&gt;Content goes here.&lt;/p&gt;
  &lt;/div&gt;
  &lt;div id=&quot;&amp;lt;&amp;quot;fun&amp;quot;&amp;gt;&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&quot;Footer!&quot;&amp;lt;&amp;lt;&amp;lt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><div class="caption">output containing &quot;special&quot; characters - <a href="listings/quoting-output.html"><span class="filename">listings/quoting-output.html</span></a></div></div>

<h2>Deferreds<a name="auto8"/></h2>

Finally, a simple demonstration of Deferred support, the unique feature of <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.html" title="twisted.web.template">twisted.web.template</a></code>.  Simply put, any renderer may
return a Deferred which fires with some template content instead of the template
content itself.  As shown above, <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.flattenString.html" title="twisted.web.template.flattenString">flattenString</a></code> will return a Deferred that
fires with the full content of the string.  But if there's a lot of content, you
might not want to wait before starting to send some of it to your HTTP client:
for that case, you can use <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.flatten.html" title="twisted.web.template.flatten">flatten</a></code>.
It's difficult to demonstrate this directly in a browser-based application;
unless you insert very long delays before firing your Deferreds, it just looks
like your browser is instantly displaying everything.  Here's an example that
just prints out some HTML template, with markers inserted for where certain
events happen:

<div class="py-listing"><pre><p class="py-linenumber"> 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
</p><span class="py-src-keyword">import</span> <span class="py-src-variable">sys</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">web</span>.<span class="py-src-variable">template</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">XMLString</span>, <span class="py-src-variable">Element</span>, <span class="py-src-variable">renderer</span>, <span class="py-src-variable">flatten</span>
<span class="py-src-keyword">from</span> <span class="py-src-variable">twisted</span>.<span class="py-src-variable">internet</span>.<span class="py-src-variable">defer</span> <span class="py-src-keyword">import</span> <span class="py-src-variable">Deferred</span>

<span class="py-src-variable">sample</span> = <span class="py-src-variable">XMLString</span>(
    <span class="py-src-string">&quot;&quot;&quot;
    &lt;div xmlns:t=&quot;http://twistedmatrix.com/ns/twisted.web.template/0.1&quot;&gt;
    Before waiting ...
    &lt;span t:render=&quot;wait&quot;&gt;&lt;/span&gt;
    ... after waiting.
    &lt;/div&gt;
    &quot;&quot;&quot;</span>)

<span class="py-src-keyword">class</span> <span class="py-src-identifier">WaitForIt</span>(<span class="py-src-parameter">Element</span>):
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">__init__</span>(<span class="py-src-parameter">self</span>):
        <span class="py-src-variable">Element</span>.<span class="py-src-variable">__init__</span>(<span class="py-src-variable">self</span>, <span class="py-src-variable">loader</span>=<span class="py-src-variable">sample</span>)
        <span class="py-src-variable">self</span>.<span class="py-src-variable">deferred</span> = <span class="py-src-variable">Deferred</span>()

    @<span class="py-src-variable">renderer</span>
    <span class="py-src-keyword">def</span> <span class="py-src-identifier">wait</span>(<span class="py-src-parameter">self</span>, <span class="py-src-parameter">request</span>, <span class="py-src-parameter">tag</span>):
        <span class="py-src-keyword">return</span> <span class="py-src-variable">self</span>.<span class="py-src-variable">deferred</span>.<span class="py-src-variable">addCallback</span>(
            <span class="py-src-keyword">lambda</span> <span class="py-src-variable">aValue</span>: <span class="py-src-variable">tag</span>(<span class="py-src-string">&quot;A value: &quot;</span> + <span class="py-src-variable">repr</span>(<span class="py-src-variable">aValue</span>)))

<span class="py-src-keyword">def</span> <span class="py-src-identifier">done</span>(<span class="py-src-parameter">ignore</span>):
    <span class="py-src-keyword">print</span>(<span class="py-src-string">&quot;[[[Deferred fired.]]]&quot;</span>)

<span class="py-src-keyword">print</span>(<span class="py-src-string">'[[[Rendering the template.]]]'</span>)
<span class="py-src-variable">it</span> = <span class="py-src-variable">WaitForIt</span>()
<span class="py-src-variable">flatten</span>(<span class="py-src-variable">None</span>, <span class="py-src-variable">it</span>, <span class="py-src-variable">sys</span>.<span class="py-src-variable">stdout</span>.<span class="py-src-variable">write</span>).<span class="py-src-variable">addCallback</span>(<span class="py-src-variable">done</span>)
<span class="py-src-keyword">print</span>(<span class="py-src-string">'[[[In progress... now firing the Deferred.]]]'</span>)
<span class="py-src-variable">it</span>.<span class="py-src-variable">deferred</span>.<span class="py-src-variable">callback</span>(<span class="py-src-string">&quot;&lt;value&gt;&quot;</span>)
<span class="py-src-keyword">print</span>(<span class="py-src-string">'[[[All done.]]]'</span>)
</pre><div class="caption">deferred example - <a href="listings/wait_for_it.py"><span class="filename">listings/wait_for_it.py</span></a></div></div>

If you run this example, you should get the following output:

<div class="html-listing"><pre class="htmlsource">
[[[Rendering the template.]]]
&lt;div&gt;
    Before waiting ...
    [[[In progress... now firing the Deferred.]]]
&lt;span&gt;A value: '&amp;lt;value&amp;gt;'&lt;/span&gt;
    ... after waiting.
    &lt;/div&gt;[[[Deferred fired.]]]
[[[All done.]]]
</pre><div class="caption">output from deferred example - <a href="listings/waited-for-it.html"><span class="filename">listings/waited-for-it.html</span></a></div></div>

This demonstrates that part of the output (everything up to
&quot;<code>[[[In progress...</code>&quot;) is written out immediately as it's rendered.
But once it hits the Deferred, <code>WaitForIt</code>'s rendering needs to pause
until <code>.callback(...)</code> is called on that Deferred.  You can see that
no further output is produced until the message indicating that the Deferred is
being fired is complete.  By returning Deferreds and using <code class="API"><a href="http://twistedmatrix.com/documents/13.2.0/api/twisted.web.template.flatten.html" title="twisted.web.template.flatten">flatten</a></code>, you can avoid buffering large
amounts of data.

<h2>A Brief Note on Formats and DOCTYPEs<a name="auto9"/></h2>

<p>
The goal of <code>twisted.web.template</code> is to emit both valid <a href="http://whatwg.org/html" shape="rect">HTML</a> or <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-xhtml-syntax.html#the-xhtml-syntax" shape="rect">XHTML</a>.
However, in order to get the maximally standards-compliant output format you
desire, you have to know which one you want, and take a few simple steps to emit
it correctly.  Many browsers will probably work with most output if you ignore
this section entirely, but <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#the-doctype" shape="rect">the
    HTML specification recommends that you specify an appropriate DOCTYPE</a>.
</p>

<p>
As a <code>DOCTYPE</code> declaration in your template would describe the
template itself, rather than its output, it won't be included in your output.
If you wish to annotate your template output with a DOCTYPE, you will have to
write it to the browser out of band.  One way to do this would be to simply
do <code>request.write('&lt;!DOCTYPE html&gt;\n')</code> when you are ready to
begin emitting your response.  The same goes for an XML <code>DOCTYPE</code>
declaration.
</p>

<p>
<code>twisted.web.template</code> will remove the <code>xmlns</code> attributes
used to declare
the <code>http://twistedmatrix.com/ns/twisted.web.template/0.1</code> namespace,
but it will not modify other namespace declaration attributes.  Therefore if you
wish to serialize in HTML format, you should not use other namespaces; if you
wish to serialize to XML, feel free to insert any namespace declarations that
are appropriate, and they will appear in your output.
</p>

<div class="note"><strong>Note: </strong>
This relaxed approach is correct in many cases.  However, in certain contexts -
especially &lt;script&gt; and &lt;style&gt; tags - quoting rules differ in
significant ways between HTML and XML, and between different browsers' parsers
in HTML.  If you want to generate dynamic content inside a script or stylesheet,
the best option is to load the resource externally so you don't have to worry
about quoting rules.  The second best option is to strictly configure your
content-types and DOCTYPE declarations for XML, whose quoting rules are simple
and compatible with the approach that <code>twisted.web.template</code> takes.
And, please remember: regardless of how you put it there, any user input placed
inside a &lt;script&gt; or &lt;style&gt; tag is a potential security issue.
</div>

<h2>A Bit of History<a name="auto10"/></h2>
<p>
Those of you who used Divmod Nevow may notice some
similarities.  <code>twisted.web.template</code> is in fact derived from the
latest version of Nevow, but includes only the latest components from Nevow's
rendering pipeline, and does not have any of the legacy compatibility layers
that Nevow grew over time.  This should make
using <code>twisted.web.template</code> a similar experience for many long-time
users of Twisted who have previously used Nevow for its twisted-friendly
templating, but more straightforward for new users.
</p>
</div>

    <p><a href="index.html">Index</a></p>
    <span class="version">Version: 13.2.0</span>
  </body>
</html>

Youez - 2016 - github.com/yon3zu
LinuXploit