Jade —— 源于 Node.js 的 HTML 模板引擎

Jade —— 源于 Node.js 的 HTML 模板引擎

54

Jade 是一個高性能的模板引擎,它深受?Haml?影響,它是用 JavaScript 實現的,并且可以供?Node?使用。

jade

試玩

你可以在網上試玩 Jade。

特性

  • 客戶端支持
  • 代碼高可讀
  • 靈活的縮進
  • 塊展開
  • Mixins
  • 靜態包含
  • 屬性改寫
  • 安全,默認代碼是轉義的
  • 運行時和編譯時上下文錯誤報告
  • 命令行下編譯jade模板
  • HTML5 模式 (使用?!!! 5?文檔類型)
  • 在內存中緩存(可選)
  • 合并動態和靜態標簽類
  • 可以通過?filters?修改樹
  • 模板繼承
  • 原生支持?Express JS
  • 通過?each?枚舉對象、數組甚至是不能枚舉的對象
  • 塊注釋
  • 沒有前綴的標簽
  • AST Filters
  • 過濾器

    • :stylus?必須已經安裝?stylus
    • :less?必須已經安裝?less.js
    • :markdown?必須已經安裝?markdown-js?或者?node-discount
    • :cdata
    • :coffeescript?必須已經安裝coffee-script
  • Emacs Mode
  • Vim Syntax
  • TextMate Bundle
  • Coda/SubEtha syntax Mode
  • Screencasts
  • html2jade?轉換器

其它實現

jade有其他語言的實現,可以實現前后端渲染的統一:

  • php
  • scala
  • ruby
  • python
  • java

安裝

npm install jade

瀏覽器支持

把 Jade 編譯為一個可供瀏覽器使用的單文件,只需要簡單的執行:

make jade.js

如果你已經安裝了 uglifyjs (npm install uglify-js),你可以執行下面的命令它會生成所有的文件。其實每一個正式版本里都幫你做了這事。

make jade.min.js 

默認情況下,為了方便調試Jade會把模板組織成帶有形如?__.lineno = 3?的行號的形式。 在瀏覽器里使用的時候,你可以通過傳遞一個選項?{ compileDebug: false }?來去掉這個。
下面的模板

p Hello #{name}

會被翻譯成下面的函數:

function anonymous(locals, attrs, escape, rethrow) { var buf = []; with (locals || {}) { var interp; buf.push('\n<p>Hello ' + escape((interp = name) == null ? '' : interp) + '\n</p>'); } return buf.join(""); } 

通過使用 Jade 的?./runtime.js你可以在瀏覽器使用這些預編譯的模板而不需要使用 Jade, 你只需要使用?runtime.js?里的工具函數, 它們會放在?jade.attrs,?jade.escape?這些里。 把選項?{ client: true }?傳遞給?jade.compile(), Jade 會把這些幫助函數的引用放在jade.attrs,?jade.escape.

function anonymous(locals, attrs, escape, rethrow) { var attrs = jade.attrs, escape = jade.escape, rethrow = jade.rethrow; var buf = []; with (locals || {}) { var interp; buf.push('\n<p>Hello ' + escape((interp = name) == null ? '' : interp) + '\n</p>'); } return buf.join(""); } 

API

var jade = require('jade');// Compile a function
var fn = jade.compile('string of jade', options); fn(locals); 

選項

  • self?使用?self?命名空間來持有本地變量.?(默認為?false)
  • locals?本地變量對象
  • filename?異常發生時使用,includes 時必需
  • debug?輸出 token 和翻譯后的函數體
  • compiler?替換掉 jade 默認的編譯器
  • compileDebug?false的時候調試的結構不會被輸出
  • pretty?為輸出加上了漂亮的空格縮進?(默認為?false)

標簽

標簽就是一個簡單的單詞:

html

它會被轉換為?<html></html>

標簽也是可以有 id 的:

div#container

它會被轉換為?<div id="container"></div>

怎么加 class 呢?

div.user-details

轉換為?<div class="user-details"></div>

多個 class 和 id? 也是可以搞定的:

div#foo.bar.baz 

轉換為?<div id="foo" class="bar baz"></div>

不停的?div div div?很討厭啊 , 可以這樣:

#foo
.bar

這個算是我們的語法糖,它已經被很好的支持了,上面的會輸出:

<div id="foo"></div><div class="bar"></div> 

標簽文本

只需要簡單的把內容放在標簽之后:

p wahoo!

它會被渲染為?<p>wahoo!</p>.

很帥吧,但是大段的文本怎么辦呢:

p| foo bar baz| rawr rawr| super cool| go jade go

渲染為?<p>foo bar baz rawr.....</p>

怎么和數據結合起來? 所有類型的文本展示都可以和數據結合起來,如果我們把?{ name: 'tj', email: 'tj@vision-media.ca' }?傳給編譯函數,下面是模板上的寫法:

#user #{name} &lt;#{email}&gt;

它會被渲染為?<div id="user">tj &lt;tj@vision-media.ca&gt;</div>

當就是要輸出?#{}?的時候怎么辦? 轉義一下!

p \#{something}

它會輸出?<p>#{something}</p>

同樣可以使用非轉義的變量?!{html}, 下面的模板將直接輸出一個?<script>?標簽:

- var html = "<script></script>" | !{html} 

內聯標簽同樣可以使用文本塊來包含文本:

label| Username:input(name='user[name]')

或者直接使用標簽文本:

label Username:input(name='user[name]')

?包含文本的標簽,比如?<script>,?<style>, 和?<textarea>?不需要前綴?|?字符, 比如:

htmlheadtitle Examplescriptif (foo) {bar();} else {baz();}

這里還有一種選擇,可以使用?.?來開始一段文本塊,比如:

p.foo asdfasdfasdfasdfafasdfasd.

會被渲染為:

<p>foo asdf
asdfasdfasdfafasdf
asd
.
</p>

這和帶一個空格的?.?是不一樣的, 帶空格的會被 Jade 的解析器忽略,當作一個普通的文字:

p .

渲染為:

<p>.</p>

需要注意的是文本塊需要兩次轉義。比如想要輸出下面的文本:

</p>foo\bar</p>

使用:

p.foo\\bar

注釋

單行注釋和 JavaScript 里是一樣的,通過?//?來開始,并且必須單獨一行:

// just some paragraphs
p foo
p bar

渲染為:

<!-- just some paragraphs -->
<p>foo</p> <p>bar</p> 

Jade 同樣支持不輸出的注釋,加一個短橫線就行了:

//- will not output within markup
p foo
p bar

渲染為:

<p>foo</p>
<p>bar</p> 

塊注釋

塊注釋也是支持的:

body//#contenth1 Example

渲染為:

<body><!--<div id="content"><h1>Example</h1></div>-->
</body> 

Jade 同樣很好的支持了條件注釋:

body//if IEa(href='http://www.mozilla.com/en-US/firefox/') Get Firefox

渲染為:

<body><!--[if IE]><a href="http://www.mozilla.com/en-US/firefox/">Get Firefox</a><![endif]-->
</body> 

內聯

Jade 支持以自然的方式定義標簽嵌套:

ulli.firsta(href='#') foolia(href='#') barli.lasta(href='#') baz 

塊展開

塊展開可以幫助你在一行內創建嵌套的標簽,下面的例子和上面的是一樣的:

ulli.first: a(href='#') foo
  li: a(href='#') barli.last: a(href='#') baz 

Case

case?表達式按下面這樣的形式寫:

htmlbodyfriends = 10case friends when 0 p you have no friends when 1 p you have a friend default p you have #{friends} friends 

塊展開在這里也可以使用:

friends = 5htmlbodycase friends when 0: p you have no friends when 1: p you have a friend default: p you have #{friends} friends 

屬性

Jade 現在支持使用?(?和?)?作為屬性分隔符

a(href='/login', title='View login page') Login

當一個值是?undefined?或者?null?屬性??會被加上,
所以呢,它不會編譯出 'something="null"'.

div(something=null)

Boolean 屬性也是支持的:

input(type="checkbox", checked)

使用代碼的 Boolean 屬性只有當屬性為?true?時才會輸出:

input(type="checkbox", checked=someValue)

多行同樣也是可用的:

input(type='checkbox',name='agreement',checked)

多行的時候可以不加逗號:

input(type='checkbox'name='agreement'checked)

加點空格,格式好看一點?同樣支持

input(type='checkbox'name='agreement'checked)

冒號也是支持的:

rss(xmlns:atom="atom")

假如我有一個?user?對象?{ id: 12, name: 'tobi' }
我們希望創建一個指向?/user/12?的鏈接?href, 我們可以使用普通的 JavaScript 字符串連接,如下:

a(href='/user/' + user.id)= user.name

或者我們使用 Jade 的修改方式, 這個我想很多使用 Ruby 或者 CoffeeScript 的人會看起來像普通的 JS..:

a(href='/user/#{user.id}')= user.name

class?屬性是一個特殊的屬性,你可以直接傳遞一個數組,比如?bodyClasses = ['user', 'authenticated']?:

body(class=bodyClasses)

HTML

內聯的 HTML 是可以的,我們可以使用管道定義一段文本 :

htmlbody| <h1>Title</h1>| <p>foo bar baz</p> 

或者我們可以使用?.?來告訴 Jade 我們需要一段文本:

htmlbody.<h1>Title</h1><p>foo bar baz</p> 

上面的兩個例子都會渲染成相同的結果:

<html><body><h1>Title</h1> <p>foo bar baz</p> </body></html> 

這條規則適應于在 Jade 里的任何文本:

htmlbodyh1 User <em>#{name}</em>

Doctypes

添加文檔類型只需要簡單的使用?!!!, 或者?doctype?跟上下面的可選項:

!!!

會渲染出?transitional?文檔類型, 或者:

!!! 5

!!! html

doctype html

Doctype 是大小寫不敏感的, 所以下面兩個是一樣的:

doctype Basic
doctype basic

當然也是可以直接傳遞一段文檔類型的文本:

doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"

渲染后:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN">

會輸出?HTML5?文檔類型. 下面的默認的文檔類型,可以很簡單的擴展:

var doctypes = exports.doctypes = {'5': '<!DOCTYPE html>','xml': '<?xml version="1.0" encoding="utf-8" ?>','default': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">','transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">','strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">', 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">', '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">', 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">', 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">' }; 

通過下面的代碼可以很簡單的改變默認的文檔類型:

    jade.doctypes.default = 'whatever you want';

過濾器

過濾器前綴?:, 比如?:markdown?會把下面塊里的文本交給專門的函數進行處理。查看頂部?特性?里有哪些可用的過濾器。

body:markdownWoah! jade _and_ markdown, very **cool**we can even link to [stuff](http://google.com)

渲染為:

<body><p>Woah! jade <em>and</em> markdown, very <strong>cool</strong> we can even link to <a href="http://google.com">stuff</a></p></body> 

代碼

Jade 目前支持三種類型的可執行代碼。第一種是前綴?-, 這是不會被輸出的:

- var foo = 'bar';

這可以用在條件語句或者循環中:

- for (var key in obj)p= obj[key]

由于 Jade 的緩存技術,下面的代碼也是可以的:

- if (foo)ulli yay li foo li worked - else p oh no! didnt work 

哈哈,甚至是很長的循環也是可以的:

- if (items.length)ul- items.forEach(function(item){ li= item - }) 

所以你想要的!

下一步我們要?轉義?輸出的代碼,比如我們返回一個值,只要前綴一個?=

- var foo = 'bar'
= foo
h1= foo

它會渲染為?bar<h1>bar</h1>. 為了安全起見,使用?=?輸出的代碼默認是轉義的,如果想直接輸出不轉義的值可以使用?!=

p!= aVarContainingMoreHTML

Jade 同樣是設計師友好的,它可以使 JavaScript 更直接更富表現力。比如下面的賦值語句是相等的,同時表達式還是通常的 JavaScript:

- var foo = 'foo ' + 'bar'
foo = 'foo ' + 'bar' 

Jade 會把?if,?else if,?else,?until,?while,?unless?同別的優先對待, 但是你得記住它們還是普通的 JavaScript:

if foo == 'bar'ulli yay li foo li worked else p oh no! didnt work 

循環

盡管已經支持 JavaScript 原生代碼,Jade 還是支持了一些特殊的標簽,它們可以讓模板更加易于理解,其中之一就是?each, 這種形式:

each VAL[, KEY] in OBJ

一個遍歷數組的例子 :

- var items = ["one", "two", "three"]
each item in items li= item 

渲染為:

<li>one</li>
<li>two</li> <li>three</li> 

遍歷一個數組同時帶上索引:

items = ["one", "two", "three"]
each item, i in itemsli #{item}: #{i}

渲染為:

<li>one: 0</li>
<li>two: 1</li> <li>three: 2</li> 

遍歷一個數組的鍵值:

obj = { foo: 'bar' }
each val, key in objli #{key}: #{val}

將會渲染為:<li>foo: bar</li>

Jade 在內部會把這些語句轉換成原生的 JavaScript 語句,就像使用?users.forEach(function(user){, 詞法作用域和嵌套會像在普通的 JavaScript 中一樣:

each user in userseach role in user.rolesli= role

如果你喜歡,也可以使用?for?:

for user in usersfor role in user.rolesli= role

條件語句

Jade 條件語句和使用了(-) 前綴的 JavaScript 語句是一致的,然后它允許你不使用圓括號,這樣會看上去對設計師更友好一點,
同時要在心里記住這個表達式渲染出的是?常規?JavaScript:

for user in usersif user.role == 'admin'p #{user.name} is an admin else p= user.name 

和下面的使用了常規 JavaScript 的代碼是相等的:

for user in users- if (user.role == 'admin')p #{user.name} is an admin - else p= user.name 

Jade 同時支持?unless, 這和?if (!(expr))?是等價的:

for user in usersunless user.isAnonymousp| Click to viewa(href='/users/' + user.id)= user.name 

模板繼承

Jade 支持通過?block?和?extends?關鍵字來實現模板繼承。 一個塊就是一個 Jade 的 block ,它將在子模板中實現,同時是支持遞歸的。

Jade 塊如果沒有內容,Jade 會添加默認內容,下面的代碼默認會輸出?block scripts,?block content, 和?block foot.

htmlheadh1 My Site - #{title}block scripts script(src='/jquery.js') body block content block foot  #footer p some footer content 

現在我們來繼承這個布局,簡單創建一個新文件,像下面那樣直接使用?extends,給定路徑(可以選擇帶?.jade?擴展名或者不帶). 你可以定義一個或者更多的塊來覆蓋父級塊內容, 注意到這里的?foot?塊?沒有?定義,所以它還會輸出父級的 "some footer content"。

extends extend-layoutblock scriptsscript(src='/jquery.js')script(src='/pets.js')block contenth1= titleeach pet in petsinclude pet

同樣可以在一個子塊里添加塊,就像下面實現的塊?content?里又定義了兩個可以被實現的塊?sidebar?和?primary,或者子模板直接實現?content

extends regular-layoutblock content.sidebar block sidebar p nothing .primary block primary p nothing 

前置、追加代碼塊

Jade允許你?替換?(默認)、?前置?和?追加?blocks. 比如,假設你希望在?所有?頁面的頭部都加上默認的腳本,你可以這么做:

htmlheadblock headscript(src='/vendor/jquery.js')script(src='/vendor/caustic.js')bodyblock content

現在假設你有一個Javascript游戲的頁面,你希望在默認的腳本之外添加一些游戲相關的腳本,你可以直接append上代碼塊:

extends layoutblock append headscript(src='/vendor/three.js')script(src='/game.js')

使用?block append?或?block prepend?時?block?是可選的:

extends layoutappend headscript(src='/vendor/three.js')script(src='/game.js')

包含

Includes 允許你靜態包含一段 Jade, 或者別的存放在單個文件中的東西比如 CSS, HTML 非常常見的例子是包含頭部和頁腳。 假設我們有一個下面目錄結構的文件夾:

./layout.jade
./includes/./head.jade./tail.jade

下面是?layout.jade?的內容:

htmlinclude includes/head  bodyh1 My Site p Welcome to my super amazing site. include includes/foot 

這兩個包含?includes/head?和?includes/foot?都會讀取相對于給?layout.jade?參數filename?的路徑的文件, 這是一個絕對路徑,不用擔心Express幫你搞定這些了。Include 會解析這些文件,并且插入到已經生成的語法樹中,然后渲染為你期待的內容:

<html><head><title>My Site</title> <script src="/javascripts/jquery.js"> </script><script src="/javascripts/app.js"></script> </head> <body> <h1>My Site</h1> <p>Welcome to my super lame site.</p> <div id="footer"> <p>Copyright>(c) foobar</p> </div> </body> </html> 

前面已經提到,include?可以包含比如 HTML 或者 CSS 這樣的內容。給定一個擴展名后,Jade 不會把這個文件當作一個 Jade 源代碼,并且會把它當作一個普通文本包含進來:

htmlhead//- css and js have simple filters that wrap them in<style> and <script> tags, respectivelyinclude stylesheet.cssinclude script.js body //- "markdown" files will use the "markdown" filter to convert Markdown to HTML include introduction.markdown //- html files have no filter and are included verbatim include content.html 

Include 也可以接受塊內容,給定的塊將會附加到包含文件?最后?的塊里。 舉個例子,head.jade?包含下面的內容:

headscript(src='/jquery.js')

我們可以像下面給include head添加內容, 這里是添加兩個腳本.

htmlinclude headscript(src='/foo.js')script(src='/bar.js')bodyh1 test

在被包含的模板中,你也可以使用yield語句。yield語句允許你明確地標明include的代碼塊的放置位置。比如,假設你希望把代碼塊放在scripts之前,而不是附加在scripts之后:

headyieldscript(src='/jquery.js')script(src='/jquery.ui.js')

由于被包含的Jade會按字面解析并合并到AST中,詞法范圍的變量的效果和直接寫在同一個文件中的相同。這就意味著include可以用作partial的替代,例如,假設我們有一個引用了user變量的user.jade`文件:

h1= user.name
p= user.occupation

接著,當我們迭代users的時候,只需簡單地加上include user。因為在循環中user變量已經被定義了,被包含的模板可以訪問它。

users = [{ name: 'Tobi', occupation: 'Ferret' }]each user in users .user include user 

以上代碼會生成:

<div class="user"><h1>Tobi</h1> <p>Ferret</p> </div> 

user.jade引用了user變量,如果我們希望使用一個不同的變量user,那么我們可以直接定義一個新變量user = person,如下所示:

each person in users.useruser = personinclude user

Mixins

Mixins 在編譯的模板里會被 Jade 轉換為普通的 JavaScript 函數。 Mixins 可以帶參數,但不是必需的:

mixin listulli foo li bar li baz 

使用不帶參數的 mixin 看上去非常簡單,在一個塊外:

h2 Groceries
mixin list

Mixins 也可以帶一個或者多個參數,參數就是普通的 JavaScript 表達式,比如下面的例子:

mixin pets(pets)ul.pets- each pet in pets li= pet mixin profile(user) .user h2= user.name mixin pets(user.pets) 

會輸出像下面的 HTML:

<div class="user"><h2>tj</h2> <ul class="pets"> <li>tobi</li> <li>loki</li> <li>jane</li> <li>manny</li> </ul> </div> 

產生輸出

假設我們有下面的 Jade 源碼:

- var title = 'yay'
h1.title #{title}
p Just an example

當?compileDebug?選項不是?false, Jade 會編譯時會把函數里加上?__.lineno = n;, 這個參數會在編譯出錯時傳遞給?rethrow(), 而這個函數會在 Jade 初始輸出時給出一個有用的錯誤信息。

function anonymous(locals) { var __ = { lineno: 1, input: "- var title = 'yay'\nh1.title #{title}\np Just an example", filename: "testing/test.js" }; var rethrow = jade.rethrow; try { var attrs = jade.attrs, escape = jade.escape; var buf = []; with (locals || {}) { var interp; __.lineno = 1; var title = 'yay' __.lineno = 2; buf.push('<h1'); buf.push(attrs({ "class": ('title') })); buf.push('>'); buf.push('' + escape((interp = title) == null ? '' : interp) + ''); buf.push('</h1>'); __.lineno = 3; buf.push('<p>'); buf.push('Just an example'); buf.push('</p>'); } return buf.join(""); } catch (err) { rethrow(err, __.input, __.filename, __.lineno); } } 

當?compileDebug?參數是?false, 這個參數會被去掉,這樣對于輕量級的瀏覽器端模板是非常有用的。結合 Jade 的參數和當前源碼庫里的?./runtime.js?文件,你可以通過?toString()?來編譯模板而不需要在瀏覽器端運行整個 Jade 庫,這樣可以提高性能,也可以減少載入的 JavaScript 數量。

function anonymous(locals) { var attrs = jade.attrs, escape = jade.escape; var buf = []; with (locals || {}) { var interp; var title = 'yay' buf.push('<h1'); buf.push(attrs({ "class": ('title') })); buf.push('>'); buf.push('' + escape((interp = title) == null ? '' : interp) + ''); buf.push('</h1>'); buf.push('<p>'); buf.push('Just an example'); buf.push('</p>'); } return buf.join(""); } 

Makefile 的一個例子

通過執行?make, 下面的 Makefile 例子可以把?pages/*.jade?編譯為?pages/*.html?。

JADE = $(shell find pages/*.jade)
HTML = $(JADE:.jade=.html)all: $(HTML)%.html: %.jade jade < $< --path $< > $@ clean: rm -f $(HTML) .PHONY: clean 

這個可以和?watch(1)?命令起來產生像下面的行為:

$ watch make

命令行的 Jade


使用: jade [options] [dir|file ...]選項:-h, --help 輸出幫助信息-v, --version 輸出版本號-o, --out <dir> 輸出編譯后的 HTML 到 <dir>-O, --obj <str> JavaScript 選項-p, --path <path> 在處理 stdio 時,查找包含文件時的查找路徑-P, --pretty 格式化 HTML 輸出-c, --client 編譯瀏覽器端可用的 runtime.js-D, --no-debug 關閉編譯的調試選項(函數會更小)-w, --watch 監視文件改變自動刷新編譯結果Examples: # 編譯整個目錄 $ jade templates # 生成 {foo,bar}.html $ jade {foo,bar}.jade # 在標準IO下使用jade $ jade < my.jade > my.html # 在標準IO下使用jade, 同時指定用于查找包含的文件 $ jade < my.jade -p my.jade > my.html # 在標準IO下使用jade $ echo "h1 Jade!" | jade # foo, bar 目錄渲染到 /tmp $ jade foo bar --out /tmp

注意: 從?v0.31.0?的?-o?選項已經指向?--out,?-O?相應做了交換

教程

  • cssdeck interactive?Jade syntax tutorial
  • cssdeck interactive?Jade logic tutorial

許可

Jade使用MIT許可證。

項目主頁

jade-lang.com

轉載于:https://www.cnblogs.com/zhangycun/p/10304209.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280543.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280543.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280543.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

詐騙者如何偽造電子郵件地址,以及如何分辨

Consider this a public service announcement: Scammers can forge email addresses. Your email program may say a message is from a certain email address, but it may be from another address entirely. 考慮這是一項公共服務公告&#xff1a;詐騙者可以偽造電子郵件地…

如何對整個 WPF 應用程序進行灰度

如何對整個 WPF 應用程序進行灰度控件名&#xff1a;GrayscaleEffect作 者&#xff1a;WPFDevelopersOrg - 驚鏵原文鏈接[1]&#xff1a;https://github.com/WPFDevelopersOrg/WPFDevelopers 簡易源碼[2]框架使用.NET40&#xff1b;Visual Studio 2019;如果要實現灰度第一反是…

django19:項目開發流程

參考&#xff1a;https://www.bilibili.com/video/BV1QE41147hU?p831&spm_id_frompageDriver

React Native - FlexBox彈性盒模型

FlexBox布局 1. 什么是FlexBox布局? 彈性盒模型(The Flexible Box Module),又叫FlexBox,意為"彈性布局",旨在通過彈性的方式來對齊和分布容器中內容的空間,使其能適應不同屏幕,為盒模型提供最大的靈活性. ??Flex布局主要思想是: 讓容器有能力讓其子項目能夠改變其…

java虛擬機讀寫其他進程的數據

在java中&#xff0c;process類提供了如下3個方法&#xff0c;用于讓程序和其他子進程進行通信。 InputStream getErrorStream&#xff08;&#xff09;&#xff1a;獲取子進程的錯誤流。 InputStream getInputStream&#xff08;&#xff09;&#xff1a;獲取子進程的輸入流。…

release8_如何在Windows 8 Release Preview中將Chrome用作Metro瀏覽器

release8Windows 8 allows third-party browser to replace Internet Explorer in the Metro environment — except on Windows RT. You can use Google Chrome in Metro today, and Firefox for Metro is on the way. Windows 8允許第三方瀏覽器在Metro環境中替換Internet Ex…

html jQuery/bootstrap通過網絡bootcdn導入連接

網絡連接網址 https://www.bootcdn.cn/ <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"utf-8"><title>title</title><!-- Bootstrap --><link href"https://cdn.bootcdn.net/ajax/libs/twi…

Python深入類和對象

一. 鴨子類型和多態 1.什么是鴨子類型&#xff1a; 在程序設計中&#xff0c;鴨子類型&#xff08;英語&#xff1a;Duck typing&#xff09;是動態類型和某些靜態語言的一種對象推斷風格。"鴨子類型"像多態一樣工作&#xff0c;但是沒有繼承。“鴨子類型”的語言是這…

linux中/usr下文件權限修改setuid導致的問題

2019獨角獸企業重金招聘Python工程師標準>>> 在Ubuntu系統中因為一些原因我使用如下命令修改了/usr目錄的擁有者權限&#xff1a; chown -R root:root /usr結果直接導致系統無法正常啟動&#xff0c;通過跟蹤系統啟動日志/var/log/syslog找到如下失敗原因&#xff1…

[轉載]unix環境高級編程備忘:理解保存的設置用戶ID,設置用戶ID位,有效用戶ID,實際用戶ID...

轉載自http://www.cnblogs.com/stemon/p/5287631.html 一、基本概念 實際用戶ID(RUID)&#xff1a;用于標識一個系統中用戶是誰&#xff0c;一般是在登錄之后&#xff0c;就被唯一的確定&#xff0c;就是登錄的用戶的uid。 有效用戶ID(EUID)&#xff1a;用于系統決定用戶對系統…

django20:BBS網頁設計/注冊功能/驗證碼代碼

表設計 注冊功能 """ 1.注冊功能需要forms組件 不同功能&#xff0c;可單獨一個py文件2.利用forms組件渲染前端標簽1.利用ajax提交2.forms組件獲取用戶數據的數據。$(#form).serializeArray()獲取forms標簽所有用戶普通鍵值對的數據3. 手動渲染頭像label里面內…

用最少的代碼打造一個Mini版的gRPC框架

在《用最少的代碼模擬gRPC四種消息交換模式》中&#xff0c;我使用很簡單的代碼模擬了gRPC四種消息交換模式&#xff08;Unary、Client Streaming、Server Streaming和Duplex Streaming&#xff09;&#xff0c;現在我們更近一步&#xff0c;試著使用極簡的方式打造一個gRPC框架…

Windows 10的下一個更新將在您觀看視頻時隱藏通知

Windows 10’s Focus Assist feature temporarily hides incoming notifications. In Windows 10’s next update, Focus Assist can activate when you’re using any full-screen app, whether that’s YouTube in a browser, Netflix, or a desktop video player like VLC. …

Ubuntu安裝Samba文件共享服務器(NAS)

終于有點時間來解決下家中NAS需求了。一般自制NAS&#xff0c;只有選Samba。速度比FTP快&#xff0c;便利性比Windows文件夾共享好&#xff0c;設置多等等。 ?參考&#xff1a;samba簡介 安裝Samba $ sudo apt-get update $ sudo apt-get install samba samba-common-bin 核心…

剛畢業的ERP實施顧問做甲方

我剛畢業進入了一家小公司做ERP實施顧問&#xff0c;是一個臺灣的ERP軟件&#xff0c;就簡單培訓了一天&#xff0c;第二天就進入一家客戶公司解決問題&#xff0c;軟件都還沒有熟悉呢&#xff0c;更別說業務流程了&#xff0c;一天下來&#xff0c;人家員工問一個問題我記下來…

django21:admin后臺管理\media配置\圖片防盜鏈\暴露后端資源\路由分發\時間分類

admin后臺管理 創建超級用戶 createsuperuser 1.到應用下的admin.py注冊模型表 from django.contrib import admin from blog import models # Register your models here.admin.site.register(models.UserInfo) admin.site.register(models.Article) admin.site.register(m…

Flask博客開發——Tinymce編輯器

之前Flask博客的文本編輯器比較簡陋&#xff0c;這里為博客添加個優雅易用的Tinymce文本編輯器。 github見&#xff1a;https://github.com/ikheu/my_flasky 1 項目中添加Tinymce 下載好Tinymce包以及語言包&#xff0c;并添加到項目中。添加到項目的方法&#xff0c;參考了這篇…

Go開發Struct轉換成map兩種方式比較

最近做Go開發的時候接觸到了一個新的orm第三方框架gorose&#xff0c;在使用的過程中&#xff0c;發現沒有類似beego進行直接對struct結構進行操作的方法&#xff0c;有部分API是通過map進行數據庫相關操作&#xff0c;那么就需要我們把struct轉化成map&#xff0c;下面是是我嘗…

Hello, Raspberry Pi.

1.概要最近在研究自動升級開源項目的時候偶然想到IoT領域的自動升級&#xff0c;突然想起2016年買的樹莓派&#xff08;Raspberry Pi&#xff09;。那就分享一下如何入門樹莓派的教程&#xff0c;我當時一共買了兩塊一款是Raspberry Pi 3b&#xff08;2016年價格259元去年以抽獎…

supersu_SuperSU已從Play商店中刪除,這是替代使用的方法

supersuSuperSU has long been a staple in the rooted Android community. For years, the process for getting a rooted handset was: unlock the bootloader, flash a custom recovery, install SuperSU. That’s just how it was. 長期以來&#xff0c;SuperSU一直是扎根于…