简体   繁体   中英

How to properly call functions in templates?

Okay, I've learned a little and am now able to replicate my site in web.py, BUT I don't like how I'm doing it in certain places.

1) I want to be able to call the templates without calling Main each time.

2) I want to be able to call the functions from the Layout.

Any advice to the above would be helpful, thank you in advance.

Below is a shortened version of the code to give you an idea of what's going on. Please let me know if I missed posting something important.

code.py:

import web
import Universal
import Navigation
import Content
import Versions


urls = (
    '/favicon.ico', 'icon',
    '/', 'index',
    '/Section1/index', 'Section1',
    '/Section2/index', 'Section2',
    '/Section3/index', 'Section3'
)

app = web.application(urls, globals(), autoreload=True)
render = web.template.render('templates/')#, base='Layout')

static = web.template.render('static/')

Main = web.template.render('templates/')
Section1 = web.template.render('templates/Section1/')
Section2 = web.template.render('templates/Section2/')
Section3 = web.template.render('templates/Section3/')

class static:
    def GET(self):
        return static()

#class icon:
#    def GET(self):
#        return static.favicon()

class index:
    def GET(self):
        vPage = '0'
        vLevel = '0'
        vSection = '0'
        vHead = Universal.getHead(vSection)
        vHeader = Universal.getHeader()
        vNavBar = Universal.getNavBar()
        vNavigation = Navigation.getNavigation(vLevel)
        vContent = Content.getContent(vLevel)
        vVersions = Versions.getVersions(vLevel)
        vFooter = Universal.getFooter()
        return Main.Layout(vHead, vHeader, vNavBar, vNavigation, vContent, vVersions, vFooter)

class Section1:
    def GET(self):
        vPage = '0'
        vLevel = '1'
        vSection = '1'
        vHead = Universal.getHead(vSection)
        vHeader = Universal.getHeader()
        vNavBar = Universal.getNavBar()
        vNavigation = Navigation.getNavigation(vLevel)
        vContent = Content.getContent(vLevel)
        vVersions = Versions.getVersions(vLevel)
        vFooter = Universal.getFooter()
        return Main.Section1.Layout(vHead, vHeader, vNavBar, vNavigation, vContent, vVersions, vFooter)

class Section2:
    def GET(self):
        vPage = '0'
        vLevel = '2'
        vSection = '2'
        vHead = Universal.getHead(vSection)
        vHeader = Universal.getHeader()
        vNavBar = Universal.getNavBar()
        vNavigation = Navigation.getNavigation(vLevel)
        vContent = Content.getContent(vLevel)
        vVersions = Versions.getVersions(vLevel)
        vFooter = Universal.getFooter()
        return Main.Section2.Layout(vHead, vHeader, vNavBar, vNavigation, vContent, vVersions, vFooter)

class Section3:
    def GET(self):
        vPage = '0'
        vLevel = '3'
        vSection = '3'
        vHead = Universal.getHead(vSection)
        vHeader = Universal.getHeader()
        vNavBar = Universal.getNavBar()
        vNavigation = Navigation.getNavigation(vLevel)
        vContent = Content.getContent(vLevel)
        vVersions = Versions.getVersions(vLevel)
        vFooter = Universal.getFooter()
        #return render.Layout(vHead, vHeader, vNavBar, vNavigation, vContent, vVersions, vFooter)
        return Main.Section3.Layout(vHead, vHeader, vNavBar, vNavigation, vContent, vVersions, vFooter)

templates/Layout.html:

$def with (vHead, vHeader, vNavBar, vNavigation, vContent, vVersions, vFooter)

<html>
<head>
    $:vHead
</head>
<body id="idBody">
    <table id="idTableMain">
        <tr id="idHeaderRow">
            <td id="idHeaderRowCenter" colspan="3">
                $:vHeader
            </td>
        </tr>
        <tr id="idNavigationRow">
            <td id="idNavigationBar" colspan="3">
                $:vNavBar
            </td>
        </tr>               
        <tr id="idCenterRow">
            <td id="idCenterRowLeft">
                <h4>
                    Navigation
                </h4>
                $:vNavigation
            </td>
            <td id="idCenterRowMain">
                $:vContent
            </td>
            <td id="idCenterRowRight">
                <h4>
                    Information
                </h4>
                This was written with Python 2.7 and web.py.<br><br>
                Other versions of this page are here:<br>
                $:vVersions
            </td>   
        </tr>
        <tr id="idFooterRow">
            <td id="idFooterMain" colspan="3">
                $:vFooter
            </td>
        </tr>
    </table>
</body>
</html>

Universal.py

def getHead(vSection):
    vResult = '<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\">'
    vResult += '<link href=' + getCSS(vSection) + ' rel=\"stylesheet\" type="text/css">'
    return vResult

def getCSS(vSection):
    if vSection == '1':
        vResult = '/static/Section1/Section1.css'
    elif vSection == '2':
        vResult = '/static/Section2/Section2.css'
    elif vSection == '3':
        vResult = '/static/Section3/Section3.css'
    else:
        vResult = '/static/Main.css'
    return vResult

def getHeader():
    vResult = '<img id=\"idLogo\" src=' + getLogo() + '>'
    return vResult
def getNavBar():
    vResult = '<a class=\'navBar\' href=\'/index\'>Home</a>'
    vResult += '<a class=\'navBar\' href=\'/Section1/index\'>Web Programming</a>'
    vResult += '<a class=\'navBar\' href=\'/Section2/index\'>Private Projects</a>'
    vResult += '<a class=\'navBar\' href=\'/Section3/index\'>Downloadable Projects</a>'
    return vResult

web.py templates use a white-list to identify functions which can be executed within a template. You can add to this by creating a dict and passing it into your renderers. For example:

common_globals = {'getHeader': Universal.getHeader,
                  'getCSS': Universal.getCSS,
                  'getHead': Universal.getHead,
                  'getNavBar': Universal.getNavBar}
Main = web.template.render('templates/')
Section1 = web.template.render('templates/Section1/', globals=common_globals)
Section2 = web.template.render('templates/Section2/', globals=common_globals)
Section3 = web.template.render('templates/Section3/', globals=common_globals)

Then, within you Layout.html you can do:

$def with(page, level, section)
<html>
<head>
    $:getHead(section)
</head>
etc....

...and then your call in code.py for class Section2 looks like:

class Section2(object):
    def GET(self):
        return Main.Section2.Layout(page=0, level=2, section=2)

(Actually, I don't think you ever need to call Main, just render as return Section2.Layout(0, 2, 2)

Repeat for the other sections and update your Layout to make calls to your functions directly and it will work.

Credit realy goes to @pbuck on this one. The first part of the problem is solved by using a dict and updating everything to match that:

dict in code.py:

common_globals = {'getHead': Universal.getHead,
                    'getCSS': Universal.getCSS,
                    'getHeader': Universal.getHeader,
                    'getLogo': Universal.getLogo,
                    'getNavBar': Universal.getNavBar,
                    'getFooter': Universal.getFooter,
                    'getNavigation': Navigation.getNavigation,
                    'getContent': Content.getContent,
                    'getVersions': Versions.getVersions
                    }

reference to page in code.py

class index:
    def GET(self):
        vPage = '0'
        vLevel = '0'
        vSection = '0'
        return Main.Layout(vPage, vLevel, vSection)

templates/Layout.html $def with (vPage, vLevel, vSection)

<html>
<head>
    $:getHead(vSection)
</head>
<body id="idBody">
    <table id="idTableMain">
        <tr id="idHeaderRow">
            <td id="idHeaderRowCenter" colspan="3">
                $:getHeader()
            </td>
        </tr>
        <tr id="idNavigationRow">
            <td id="idNavigationBar" colspan="3">
                $:getNavBar()
            </td>
        </tr>               
        <tr id="idCenterRow">
            <td id="idCenterRowLeft">
                <h4>
                    Navigation
                </h4>
                $:getNavigation(vLevel)
            </td>
            <td id="idCenterRowMain">
                $:getContent(vLevel+'_'+vPage+'P')
            </td>
            <td id="idCenterRowRight">
                <h4>
                    Information
                </h4>
                This was written with Python 2.7 and web.py.<br><br>
                Other versions of this page are here:<br>
                $:getVersions(vLevel+'_'+vPage+'P')
            </td>   
        </tr>
        <tr id="idFooterRow">
            <td id="idFooterMain" colspan="3">
                $:getFooter()
            </td>
        </tr>
    </table>
</body>
</html>

I understand its not fancy, but this was a great learning exercise. Only thing left is the renderer issue, and that's just more about WHERE the work happens in Code.py

I'll probably post that as a separate question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM