亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Table of Contents
=$title;?>
User List
Home php教程 php手冊 超越模板引擎

超越模板引擎

Jun 21, 2016 am 09:14 AM
gt lt quot template the

模板

總體來說,模板引擎是一個"好東西"

作為一個PHP/Perl的程序員,許多模板引擎(fastTemplate, Smarty, Perl的 HTML::Template)的用戶,以及我自己的(bTemplate [1] 的作者),我講這句話很多次了。

然而,在同事進行了長時間的討論之后,我確信了大量的模板引擎(包括我自己寫的)根本是錯誤的。 我想唯一的例外是Smarty [2],雖然我認為它太龐大了,并且考慮到這篇文章的其余部分相當?shù)臎]有觀點。然而,就你為什么選擇Smarty(或者類似的解決方案)有幾個理由,這些將在文章后面探究。

這篇文章討論模板的理論。我們將看到為什么大部分"模板引擎"是過于肥大,并且最終我們將回過頭來看一個輕量級的,小巧快速的另類選擇。



下載和授權
模板類和所有在本文中使用的例子能夠在這里下載:template.zip [3]。你可以根據(jù)發(fā)布 [4]在 OSI [5] 的 MIT Open Source License使用這些文件中的代碼。



一些關于模板引擎的背景知識
讓我們首先研究一下模板引擎的背景知識。模板引擎被設計出來用于把商業(yè)邏輯(例如從數(shù)據(jù)庫中獲取數(shù)據(jù)或者計算貿(mào)易耗費)從數(shù)據(jù)的表現(xiàn)分離開來。模板引擎解決了兩個主要問題:


如何實現(xiàn)這種分離
如何從HTML中分離"復雜"的php代碼

這從理論上使得沒有PHP經(jīng)驗的HTML設計者能夠不看任何PHP代碼的條件下修改站點的外觀。

然而,模板系統(tǒng)也引入了一些復雜性。首先,我們現(xiàn)在有一個從多個文件得來的"頁面"。典型的,你可能有一個主PHP頁負責業(yè)務邏輯,一個外面的"布局"模板把整個站點的整體布局進行渲染,一個內(nèi)部的內(nèi)容特定的模板,一個數(shù)據(jù)庫抽象層,以及模板引擎本身(這些可能是也可能不是由多個文件組成)。也有可能,一些人僅僅簡單地在每個PHP頁面的首尾處包含"頭部"和"尾部"文件。

這產(chǎn)生的單個頁面的文件數(shù)量是很可觀的。然而,因為PHP解析器非???,用到的文件數(shù)量可能不是那么重要除非你的站點流量很大。
然而,要記住模板系統(tǒng)引入了另外一個處理的層次。模板文件不僅僅是必須被包含,他們還必須被解析(取決于模板系統(tǒng),這個行為有很多種方式來完成 —— 使用正則表達式,字符串替換,編譯,詞法分析,等等)。這就是為什么對模板進行測速變得流行起來:因為模板引擎使用各種方法來解析數(shù)據(jù),它們中的一些比另外一些要快(而且,一些模板引擎提供了比其他引擎更加豐富的功能)。



模板引擎基礎知識
簡單地說,模板引擎利用了用C寫的腳本語言(PHP)。在這些嵌入的腳本語言中,你有另外一個偽腳本語言(無論你的模板引擎支持何種標簽)。某些提供了簡單的變量改寫和循環(huán)。另外一些呢,則提供了條件和嵌套循環(huán)。而再其他的呢(至少有Smarty)提供了一個PHP的比較大的子集的接口,以及一個緩沖層。

為什么我認為Smarty最接近于正確的方向?因為Smarty的目標是"把業(yè)務邏輯從表現(xiàn)中分離出來"而不是"PHP代碼和HTML代碼的分離"。這看上去區(qū)別不大,但是它正是要點所在。任何模板引擎的最終目標不應該是從HTML移除所有的邏輯。它應該是把表現(xiàn)邏輯從業(yè)務邏輯中分離出來。

有很多你僅僅需要邏輯來正確顯示你的數(shù)據(jù)的例子。例如,你的業(yè)務邏輯是從你的數(shù)據(jù)庫中獲取一個用戶列表。你的表現(xiàn)邏輯可能是把用戶列表用3列顯示??赡苄薷挠脩袅斜砗瘮?shù)使得它返回3個數(shù)組是很笨的辦法。畢竟函數(shù)不應該關心數(shù)據(jù)接下來要怎么處理這樣的事情。然而,在你的模板文件中缺少一些邏輯,那些正是你要做的事情。

在這點上Smarty是正確的(使得你利用PHP的很多東西),但是仍然有許多問題?;旧?,它僅僅提供了一個以新語法訪問PHP的接口。以那開始,它看上去不那么聰明了。是不是事實上寫 {foreach --args} 比 foreach --args ?> 更加簡單?如果你認為這樣簡單一些,問問你自己是不是在包含一個巨大的模板庫來到成這種分離時能夠看到真正的意義要更加簡單一些。誠然,Smarty提供了許多其他很好的特性,但是看上去這些益處能夠在不用承擔包含Smarty類庫的情況下也能獲得。



別樣的解決方案
我主要要鼓吹的一個解決方案是一個使用PHP代碼作為它的原生腳本語言的"模板引擎"。我知道這以前有人做過。而且當我第一次看到的時候,我想,"為什么要這樣做?",然而我在考慮過我同事的論據(jù)之后,并且實現(xiàn)了一個直接使用PHP代碼仍然實現(xiàn)了把業(yè)務邏輯和表現(xiàn)邏輯分離的最終目標的模板系統(tǒng)時(只用了大約25行代碼,不包括注釋),我意識到了好處所在。

這個系統(tǒng)給像我們這樣的開發(fā)者提供了對PHP核心函數(shù)的訪問權利,我們能夠使用他們來格式化輸出——像日期格式化這樣的任務應該在模板中處理。而且,因為模板是普通的PHP文件,像Zend Performance Suite [6] 和PHP Accelerator [7] 這樣的字節(jié)碼緩存程序,能夠自動緩存模板(因而,它們不需要在每次被訪問時都被重新解釋執(zhí)行)。只要你記得把你的模板文件命名為程序能夠辨認出是PHP文件的名字(通常,你僅僅需要確保它們有一個.php的后綴),這確實是一個好處。

當我認為這種方法比經(jīng)典的模板引擎要高明得多時,肯定還有一些要商榷的問題。最明顯的反面意見是,PHP代碼太復雜了,而且設計者不應該強迫去學習PHP。事實上,PHP代碼和像Smarty這樣的高級模板引擎的語法差不多簡單(如果不是更簡單的話)。而且,設計者能夠使用像=$var;?>這樣的簡寫PHP。這要比{$var}復雜很多?當然,這要長一些,但是如果你習慣了,你能夠獲得了PHP的威力而且不用承受解析模板文件帶來的負擔。
第二,而且可能更重要的,在基于PHP的模板中沒有固有的安全。Smarty提供了選項在模板文件中徹底禁用PHP代碼。它使得開發(fā)者能夠約束模板能夠訪問的函數(shù)和變量。如果你沒有不懷好意的設計者,這不會是什么問題。然而,如果你允許外部的用戶上傳或者修改模板,我在此展示的基于PHP的解決方案絕對沒有任何安全可言!任何代碼都能放入模板中并且得到運行。是的,甚至是一個print_r($GLOBALS)(這將改有惡意的用戶訪問腳本中任何變量的權利)。

但是,我個人或者工作上寫過的項目中,絕大多數(shù)不允許最終的用戶修改或者上傳模板。如果是這樣,問題就不存在了。因此現(xiàn)在讓我們來看看代碼吧。



例子
這是一個簡單的用戶列表頁面的例子。

require_once('template.php');

/**
* This variable holds the file system path to all our template files.
*/
$path = './templates/';

/**
* Create a template object for the outer template and set its variables.
*/
$tpl = & new Template($path);
$tpl->set('title', 'User List');

/**
* Create a template object for the inner template and set its variables. The
* fetch_user_list() function simply returns an array of users.
*/
$body = & new Template($path);
$body->set('user_list', fetch_user_list());

/**
* Set the fetched template of the inner template to the 'body' variable in
* the outer template.
*/
$tpl->set('body', $body->fetch('user_list.tpl.php'));

/**
* Echo the results.
*/
echo $tpl->fetch('index.tpl.php');
?>
其中有兩個值得注意的重要的概念。第一個就是內(nèi)部和外部模板的概念。外部模板包含定義站點主要外觀的HTML代碼。而內(nèi)部模板包含定義站點內(nèi)容區(qū)域的HTML代碼。當然,你能夠在任意數(shù)目的層上有任意數(shù)目的模板。因為通常我們給每個區(qū)域使用不同的模板對象,所以沒有名字空間的問題。例如,我能在內(nèi)部和外部模板中都有變量叫"title",而不用害怕有什么沖突。

這是一個用來顯示用戶列表的模板的簡單例子。注意特殊的foreach和endforeach;語法在PHP手冊中有說明 [8]。它完全是可選擇的。

而且,你可能奇怪我為什么要用.php的后綴來命名我的模板文件。呵呵,許多PHP字節(jié)碼緩存解決方案(比如 phpAccelerator)如果要被認成PHP文件,需要文件有一個.php后綴。因為這些模板是PHP文件,為什么不去獲得這些好處?








foreach($user_list as $user): ?>






endforeach; ?>
Id Name Email Banned
=$user['id'];?> =$user['name'];?> =$user['email'];?> =($user['banned'] ? 'X' : '?');?>


這個layout.tpl.php是一個簡單的例子(定義了整個頁面看上去是什么樣子的模板文件)


=$title;?>




=$title;?>



=$body;?>




而這是解析后的輸出。


User List




User List








































Id Name Email Banned
1 bob bob@mozilla.org ?
2 judy judy@php.net ?
3 joe joe@opera.com ?
4 billy billy@wakeside.com X
5 eileen eileen@slashdot.org ?





緩存
因為解決方案簡單如斯,實現(xiàn)模板緩存成為了一個非常簡單的任務。為了實現(xiàn)緩存,我們有一個二級類,它擴展了原來的模板類。CachedTemplate類事實上使用和原來的模板類相同的API。不同點是我們必須傳遞緩存的設置給構造函數(shù),并且調(diào)用fetch_cache()而不是fetch()。

緩存的概念是簡單的。簡單的說,我們設置一個緩存時間來調(diào)表輸出應該被保存的時長(以秒為單位)。在產(chǎn)生一個頁面的所有工作開展之前,我們必須首先測試頁面是否已經(jīng)被緩存了,而且緩存是否仍然沒有過期。如果緩存在這那,我們不需要在去麻煩數(shù)據(jù)庫和業(yè)務邏輯來產(chǎn)生頁面——我們可以簡單地輸出原先緩存地內(nèi)容。

這種方法需要解決唯一地標識緩存文件的問題。如果一個站點是被一個顯示基于GET變量的中心腳本所控制,對每個PHP文件只有一個緩存不會有什么幫助。例如,如果index.php?page=about_us和用戶調(diào)用index.php?page=contact_us得到的顯示完全不同。

問題是通過給每個頁面產(chǎn)生一個唯一的cache_id來解決的。為了做到這個目的,我們把事實上被請求的文件變成REQUEST_URI(基本上就是整個URL:index.php?foo=bar&bar=foo)。當然,這個轉換過程是受到CachedTemplate類控制的,但是要記住的重要的事情是你絕對要在創(chuàng)建CachedTemplate對象時傳遞一個唯一的cache_id。當然下面有例子來說明。

使用緩存包括以下步驟。


include() 模板源文件


創(chuàng)建一個新的CachedTemplate對象(并且傳遞路徑,唯一的cache_id和緩存過期時間給模板)


測試內(nèi)容是否已經(jīng)被緩存了


如果還促拿了,顯示文件并且結束腳本


否則,進行所有的處理并且fetch()模板


對fetch_cache()的調(diào)用將自動產(chǎn)生一個新的緩存文件

這個腳本假定你的緩存文件將放到./cache/中,因此你必須創(chuàng)建那個目錄并且改變它的目錄權限(chmod)使得Web服務器能夠寫入文件。而且還要注意如果你在編寫腳本的過程中發(fā)現(xiàn)了錯誤,錯誤也會被緩存!因而在你開發(fā)的過程中禁用緩存是一個好主意。最好的辦法是給cache的生存周期傳遞0——這樣,緩存總是立即就失效了。

這是一個實際的緩存的例子。

/**
* Example of cached template usage. Doesn't provide any speed increase since
* we're not getting information from multiple files or a database, but it
* introduces how the is_cached() method works.
*/

/**
* First, include the template class.
*/
require_once('template.php');

/**
* Here is the path to the templates.
*/
$path = './templates/';

/**
* Define the template file we will be using for this page.
*/
$file = 'list.tpl.php';

/**
* Pass a unique string for the template we want to cache. The template
* file name + the server REQUEST_URI is a good choice because:
* 1. If you pass just the file name, re-used templates will all
* get the same cache. This is not the desired behavior.
* 2. If you just pass the REQUEST_URI, and if you are using multiple
* templates per page, the templates, even though they are completely
* different, will share a cache file (the cache file names are based
* on the passed-in cache_id.
*/
$cache_id = $file . $_SERVER['REQUEST_URI'];
$tpl = & new CachedTemplate($path, $cache_id, 900);

/**
* Test to see if the template has been cached. If it has, we don't
* need to do any processing. Thus, if you put a lot of db calls in
* here (or file reads, or anything processor/disk/db intensive), you
* will significantly cut the amount of time it takes for a page to
* process.
*
* This should be read aloud as "If NOT Is_Cached"
*/
if(!($tpl->is_cached())) {
$tpl->set('title', 'My Title');
$tpl->set('intro', 'The intro paragraph.');
$tpl->set('list', array('cat', 'dog', 'mouse'));
}

/**
* Fetch the cached template. It doesn't matter if is_cached() succeeds
* or fails - fetch_cache() will fetch a cache if it exists, but if not,
* it will parse and return the template as usual (and make a cache for
* next time).
*/
echo $tpl->fetch_cache($file);
?>


設置多個變量
我們?nèi)绾文軌蛲瑫r設置多個變量?這又一個使用由Ricardo Garcia貢獻的函數(shù)的例子。

require_once('template.php');

$tpl = & new Template('./templates/');
$tpl->set('title', 'User Profile');

$profile = array(
'name' => 'Frank',
'email' => 'frank@bob.com',
'password' => 'ultra_secret'
);

$tpl->set_vars($profile);

echo $tpl->fetch('profile.tpl.php');
?>
相關的模板是這樣的:














Name =$name;?>
Email =$email;?>
Password =$password;?>

而且解析后的輸出是這樣的:














Name Frank
Email frank@bob.com
Password ultra_secret

特別感謝Ricardo Garcia和Harry Fuecks他們的對這篇文章的貢獻。



相關的鏈接
這兒是一個總體上探究模板引擎的好去處的列表。


Web Application Toolkit Template View [9] - 許多關于模板實現(xiàn)方法的信息
MVC Pattern [10] - 描述3層應用程序的設計
SimpleT [11] - 另一個使用PEAR::Cache_Lite的基于php的模板引擎
Templates and Template Engines [12] - 更多關于各種模板實現(xiàn)的信息
Smarty [13] - 編譯型模板引擎



模板類源代碼
以及最后出場的,模板類。

/**
* Copyright (c) 2003 Brian E. Lozier (brian@massassi.net)
*
* set_vars() method contributed by Ricardo Garcia (Thanks!)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/

class Template {
var $vars; /// Holds all the template variables
var $path; /// Path to the templates

/**
* Constructor
*
* @param string $path the path to the templates
*
* @return void
*/
function Template($path = null) {
$this->path = $path;
$this->vars = array();
}

/**
* Set the path to the template files.
*
* @param string $path path to template files
*
* @return void
*/
function set_path($path) {
$this->path = $path;
}

/**
* Set a template variable.
*
* @param string $name name of the variable to set
* @param mixed $value the value of the variable
*
* @return void
*/
function set($name, $value) {
$this->vars[$name] = $value;
}

/**
* Set a bunch of variables at once using an associative array.
*
* @param array $vars array of vars to set
* @param bool $clear whether to completely overwrite the existing vars
*
* @return void
*/
function set_vars($vars, $clear = false) {
if($clear) {
$this->vars = $vars;
}
else {
if(is_array($vars)) $this->vars = array_merge($this->vars, $vars);
}
}

/**
* Open, parse, and return the template file.
*
* @param string string the template file name
*
* @return string
*/
function fetch($file) {
extract($this->vars); // Extract the vars to local namespace
ob_start(); // Start output buffering
include($this->path . $file); // Include the file
$contents = ob_get_contents(); // Get the contents of the buffer
ob_end_clean(); // End buffering and discard
return $contents; // Return the contents
}
}

/**
* An extension to Template that provides automatic caching of
* template contents.
*/
class CachedTemplate extends Template {
var $cache_id;
var $expire;
var $cached;

/**
* Constructor.
*
* @param string $path path to template files
* @param string $cache_id unique cache identifier
* @param int $expire number of seconds the cache will live
*
* @return void
*/
function CachedTemplate($path, $cache_id = null, $expire = 900) {
$this->Template($path);
$this->cache_id = $cache_id ? 'cache/' . md5($cache_id) : $cache_id;
$this->expire = $expire;
}

/**
* Test to see whether the currently loaded cache_id has a valid
* corrosponding cache file.
*
* @return bool
*/
function is_cached() {
if($this->cached) return true;

// Passed a cache_id?
if(!$this->cache_id) return false;

// Cache file exists?
if(!file_exists($this->cache_id)) return false;

// Can get the time of the file?
if(!($mtime = filemtime($this->cache_id))) return false;

// Cache expired?
if(($mtime + $this->expire) @unlink($this->cache_id);
return false;
}
else {
/**
* Cache the results of this is_cached() call. Why? So
* we don't have to double the overhead for each template.
* If we didn't cache, it would be hitting the file system
* twice as much (file_exists() & filemtime() [twice each]).
*/
$this->cached = true;
return true;
}
}

/**
* This function returns a cached copy of a template (if it exists),
* otherwise, it parses it as normal and caches the content.
*
* @param $file string the template file
*
* @return string
*/
function fetch_cache($file) {
if($this->is_cached()) {
$fp = @fopen($this->cache_id, 'r');
$contents = fread($fp, filesize($this->cache_id));
fclose($fp);
return $contents;
}
else {
$contents = $this->fetch($file);

// Write the cache
if($fp = @fopen($this->cache_id, 'w')) {
fwrite($fp, $contents);
fclose($fp);
}
else {
die('Unable to write cache.');
}

return $contents;
}
}
}
?>
另外一個值得注意的重要的事情是這里展示的解決辦法是我們傳遞模板的文件名給fetch()函數(shù)。如果你需要重用模板對象而不去re-set()所有的變量,這將比較有用。

并且記?。耗0逡娴囊c是把你的業(yè)務邏輯從你的表現(xiàn)邏輯中分離出來,而不是把你的PHP代碼從HTML代碼中分離出來。

本文附件下載:template.zip [1] http://www.massassi.com/bTemplate/
[2] http://smarty.php.net/
[3] http://www.sitepoint.com/examples/tempeng/template.zip
[4] http://opensource.org/licenses/mit-license.html
[5] http://www.opensource.org/
[6] http://zend.com/store/products/zend-performance-suite.php
[7] http://www.php-accelerator.co.uk/
[8] http://www.php.net/manual/en/control-structures.alternative-syntax.php
[9] http://wact.sourceforge.net/index.php/TemplateView
[10] http://www.phppatterns.com/index.php/article/articleview/11/
[11] http://simplet.sourceforge.net/
[12] http://phppatterns.com/index.php/article/articleview/4/1/1/
[13] http://smarty.php.net/

本文英文原版地址:http://www.sitepoint.com/article/1218/



Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

PHP Tutorial
1488
72
What are the differences between Huawei GT3 Pro and GT4? What are the differences between Huawei GT3 Pro and GT4? Dec 29, 2023 pm 02:27 PM

Many users will choose the Huawei brand when choosing smart watches. Among them, Huawei GT3pro and GT4 are very popular choices. Many users are curious about the difference between Huawei GT3pro and GT4. Let’s introduce the two to you. . What are the differences between Huawei GT3pro and GT4? 1. Appearance GT4: 46mm and 41mm, the material is glass mirror + stainless steel body + high-resolution fiber back shell. GT3pro: 46.6mm and 42.9mm, the material is sapphire glass + titanium body/ceramic body + ceramic back shell 2. Healthy GT4: Using the latest Huawei Truseen5.5+ algorithm, the results will be more accurate. GT3pro: Added ECG electrocardiogram and blood vessel and safety

After 2 months, the humanoid robot Walker S can fold clothes After 2 months, the humanoid robot Walker S can fold clothes Apr 03, 2024 am 08:01 AM

Editor of Machine Power Report: Wu Xin The domestic version of the humanoid robot + large model team completed the operation task of complex flexible materials such as folding clothes for the first time. With the unveiling of Figure01, which integrates OpenAI's multi-modal large model, the related progress of domestic peers has been attracting attention. Just yesterday, UBTECH, China's "number one humanoid robot stock", released the first demo of the humanoid robot WalkerS that is deeply integrated with Baidu Wenxin's large model, showing some interesting new features. Now, WalkerS, blessed by Baidu Wenxin’s large model capabilities, looks like this. Like Figure01, WalkerS does not move around, but stands behind a desk to complete a series of tasks. It can follow human commands and fold clothes

Fix: Snipping tool not working in Windows 11 Fix: Snipping tool not working in Windows 11 Aug 24, 2023 am 09:48 AM

Why Snipping Tool Not Working on Windows 11 Understanding the root cause of the problem can help find the right solution. Here are the top reasons why the Snipping Tool might not be working properly: Focus Assistant is On: This prevents the Snipping Tool from opening. Corrupted application: If the snipping tool crashes on launch, it might be corrupted. Outdated graphics drivers: Incompatible drivers may interfere with the snipping tool. Interference from other applications: Other running applications may conflict with the Snipping Tool. Certificate has expired: An error during the upgrade process may cause this issu simple solution. These are suitable for most users and do not require any special technical knowledge. 1. Update Windows and Microsoft Store apps

Golang and the Template package: creating personalized user interfaces Golang and the Template package: creating personalized user interfaces Jul 18, 2023 am 10:27 AM

Golang and Template package: Create personalized user interface In modern software development, the user interface is often the most direct way for users to interact with the software. In order to provide a user interface that is easy to use and beautiful, developers need flexible tools to create and customize the user interface. In Golang, developers can use the Template package to achieve this goal. This article will introduce the basic usage of Golang and Template packages, and show how to create a personalized user interface through code examples.

How to Fix Can't Connect to App Store Error on iPhone How to Fix Can't Connect to App Store Error on iPhone Jul 29, 2023 am 08:22 AM

Part 1: Initial Troubleshooting Steps Checking Apple’s System Status: Before delving into complex solutions, let’s start with the basics. The problem may not lie with your device; Apple's servers may be down. Visit Apple's System Status page to see if the AppStore is working properly. If there's a problem, all you can do is wait for Apple to fix it. Check your internet connection: Make sure you have a stable internet connection as the "Unable to connect to AppStore" issue can sometimes be attributed to a poor connection. Try switching between Wi-Fi and mobile data or resetting network settings (General > Reset > Reset Network Settings > Settings). Update your iOS version:

Data visualization through Golang's Template package Data visualization through Golang's Template package Jul 17, 2023 am 09:01 AM

Data visualization through Golang's Template package. With the advent of the big data era, data visualization has become one of the important means of information processing and analysis. Data visualization can present data in a concise and intuitive way, helping people better understand and analyze data. In Golang, we can use the Template package to implement data visualization functions. This article will introduce how to use Golang's Template package to achieve data visualization and provide code examples. GolangTem

php提交表單通過后,彈出的對話框怎樣在當前頁彈出,該如何解決 php提交表單通過后,彈出的對話框怎樣在當前頁彈出,該如何解決 Jun 13, 2016 am 10:23 AM

php提交表單通過后,彈出的對話框怎樣在當前頁彈出php提交表單通過后,彈出的對話框怎樣在當前頁彈出而不是在空白頁彈出?想實現(xiàn)這樣的效果:而不是空白頁彈出:------解決方案--------------------如果你的驗證用PHP在后端,那么就用Ajax;僅供參考:HTML code

How to optimize iPad battery life with iPadOS 17.4 How to optimize iPad battery life with iPadOS 17.4 Mar 21, 2024 pm 10:31 PM

How to Optimize iPad Battery Life with iPadOS 17.4 Extending battery life is key to the mobile device experience, and the iPad is a good example. If you feel like your iPad's battery is draining too quickly, don't worry, there are a number of tricks and tweaks in iPadOS 17.4 that can significantly extend the run time of your device. The goal of this in-depth guide is not just to provide information, but to change the way you use your iPad, enhance your overall battery management, and ensure you can rely on your device for longer without having to charge it. By adopting the practices outlined here, you take a step toward more efficient and mindful use of technology that is tailored to your individual needs and usage patterns. Identify major energy consumers

See all articles