216 Commits

Author SHA1 Message Date
Copilot
4079a64a88 修复 PHP 8.5 中 curl_close() 弃用警告 (#1924)
* Initial plan

* 移除 curl_close() 调用以修复 PHP 8.5 弃用警告

Co-authored-by: joyqi <59437+joyqi@users.noreply.github.com>

* 使用 PHP 版本检查兼容 PHP 7.4 的 curl_close 处理

Co-authored-by: joyqi <59437+joyqi@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: joyqi <59437+joyqi@users.noreply.github.com>
2025-11-27 11:37:42 +08:00
猫东东
9364388035 修复 PHP 8.4+ 中 PDO::MYSQL_ATTR_USE_BUFFERED_QUERY 的弃用警告 (#1922) 2025-11-27 09:05:18 +08:00
Luffy
7a3c86a110 Support connect to mysql using socket (#1749)
* Support connect to mysql using socket

* pgsql can also use unix_socket

fix Deprecated: pg_escape_string(): Automatic fetching of PostgreSQL connection

* Update install.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update var/Typecho/Db/Adapter/Mysqli.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Fix quoteValue method to correctly escape single quotes in strings

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-20 23:55:43 +08:00
Luffy
15967ea059 Fix login failed when username contains @ (#1894)
* Fix login failed when username contains @

* Update var/Widget/User.php

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-20 17:17:31 +08:00
Luffy
570f982709 Add 'NOT' to query keywords (#1903) 2025-11-19 22:28:13 +08:00
Luffy
6dbcdf7eae Fix explicitly declare nullable type for $rules parameter (#1908) 2025-08-08 12:09:21 +08:00
joyqi
5e7e10969e fix default theme's i18n problem https://github.com/typecho/languages/issues/49 2025-08-05 11:01:31 +08:00
joyqi
3d261e08b9 fix: don't send ping back to self 2025-08-01 18:04:18 +08:00
joyqi
546470b2de update hyperdown 2025-07-04 15:10:18 +08:00
joyqi
23cdc89441 fix #1882 (#1883) 2025-06-27 11:12:45 +08:00
Luffy
d9d0be334d Update canonical link condition (#1881) 2025-06-11 16:39:39 +08:00
joyqi
ba4e4134ad fix form validate error 2025-06-05 15:10:47 +08:00
joyqi
7ef2c08a96 fix validate error 2025-06-05 15:09:03 +08:00
joyqi
db8a3f7f3e fix nullable parameter error 2025-06-05 14:34:22 +08:00
joyqi
5ef475b73f feat: validate via regexp (#1877) 2025-05-12 23:40:38 +08:00
joyqi
917a763811 Feat/improve styles (#1868)
* improve css

* fix table

* fix write page

* improve header nav

* fix menu

* fix menu

* fix menu

* add flex grid system

* fix

* fix flex

* fix draft version

* using main html element to replace div

* improve css

* add input type number

* fix custom-fields

* fix screen
2025-05-09 16:12:56 +08:00
Robert Silén
50d572a0af Add MariaDB to README.md (#1827) 2025-02-19 10:50:05 +08:00
Luffy
752fc6b0ad Fix missing nameExists and mailExists (#1854) 2025-02-03 10:47:29 +08:00
Luffy
95f6e7b4f5 Remove debug output from category selection in Archive widget (#1852) 2025-02-03 10:40:12 +08:00
Pomelo_Official
67a830f86b fix typo "稍侯" to "稍候" (#1850)
fix typo "稍侯" to "稍候"
2025-01-31 13:35:15 +08:00
Luffy
8ff55f5266 Fix #1846 (#1847) 2025-01-14 21:56:48 +08:00
joyqi
8035b22347 fix #1843 (#1844)
* fix #1843
Remove categroy name-exists detecting

* detect category-exists only in the same level
2025-01-13 16:48:46 +08:00
joyqi
b989f24c5b Fix/1754 (#1842)
* add deprecated methods

* fix #1754
2025-01-11 17:51:29 +08:00
joyqi
23724c4193 fix #1830 (#1841) 2025-01-10 14:53:47 +08:00
joyqi
6ddf1c1a23 fix #1816 (#1839)
* fix #1816

* fix call stack

* fix typo error
2025-01-07 19:42:15 +08:00
Luffy
7d51b210c9 Fix manage comments failed (#1838) 2025-01-04 12:45:16 +08:00
Mr. Chip
91876b42aa Fix: fix preg_match parameter#2 $subject is null deprecated issue (#1798) 2024-09-23 10:49:47 +08:00
Luffy
5783cb0d01 fix sendPingHandle warning (#1808) 2024-09-23 10:48:19 +08:00
ZShijun
87d479dd57 Update Login.php (#1804)
修复勾选下次自动登录,但重启浏览器不生效的bug
2024-09-11 10:59:32 +08:00
Luffy
ef9ef2ce45 Require PHP 7.4.0 or higher (#1785) 2024-07-24 15:51:19 +08:00
陆之岇
31f5192c9d Fix timezone error in XmlRpc (#1758)
Signed-off-by: Kraity <kraity@krait.cn>
2024-06-20 11:22:51 +08:00
Luffy
4ce9cdefc2 Fix TypeError: Typed property Typecho\Feed::$subTitle must be string (#1779) 2024-06-12 10:47:06 +08:00
Luffy
0b0476e565 Fix missing WidgetException error message (#1730) 2024-04-19 12:11:39 +08:00
Fen
71c6381b15 fix: nav menu active style (#1752) 2024-03-29 11:38:30 +08:00
Fen
fa107ffa51 update picocss to 2.0 (#1751) 2024-03-28 15:37:19 +08:00
Luffy
d84e261f7b Fix missing get date (#1740) 2024-02-28 10:57:47 +08:00
Luffy
3933a23ad7 Fix assign null to property Widget\Archive::$archiveKeywords (#1738)
* Fix assign null to property Widget\Archive::$archiveKeywords

* Fix
2024-02-26 11:52:17 +08:00
fen
0a40b1e7ee improve: comment color 2024-01-29 16:32:38 +08:00
Lu Fei
bda7541682 Limit build execution (#1723) 2024-01-29 12:05:30 +08:00
joyqi
f3a5336c1a Remove comment link if status is not approved (#1712)
* remove comment link if status is not approved

* fix stack

* fix: remove link in admin panel when comment status is not approved

* fix: comments page nav

* fix comment redirect url

* fix comment anchor

* fix waiting comment display

* fix: convert waiting to unapproved
2024-01-25 14:24:47 +08:00
Lu Fei
d1e961af90 Upgrade actions/checkout to v4 (#1718) 2024-01-24 02:18:19 +08:00
joyqi
e3bdef645d fix: remove unnecessary DOCTYPE tags (#1715) 2024-01-23 18:30:17 +08:00
joyqi
de53b64880 fix: remove special chars (#1716) 2024-01-23 18:29:59 +08:00
joyqi
d0b62eabe9 fix: xmlrpc message args (#1714) 2024-01-22 14:36:10 +08:00
Fen
99ffd36648 Fix/classic22 (#1708)
* fix: use prefers-color-scheme control dark mode

* update color
2024-01-15 10:56:47 +08:00
电脑星人
4028d7d160 fix: getHeader for Content-Type & Content-Length (#1703)
* fix: Request::getHeader for Content-Type & Content-Length

* fix: get content-type through native api

---------

Co-authored-by: joyqi <joyqi@users.noreply.github.com>
2024-01-13 22:11:38 +08:00
joyqi
a30a6c122d fix: choose the correct key when setting widget value (#1702) 2024-01-10 15:37:05 +08:00
Fen
0d28025bf4 update issue template 2024-01-10 12:58:20 +08:00
Fen
8b75782619 update issue template (#1700) 2024-01-10 12:45:24 +08:00
Fen
c5ab9295f0 Fix/classic 22 (#1698)
* style: move customize color to theme.css
2024-01-09 16:33:40 +08:00
Lu Fei
c816efa26e fix trim error (#1697) 2024-01-09 14:56:25 +08:00
joyqi
7115a30301 fix attachment handle (#1696)
* fix #1694

* fix array dump

* add toColumn method
2024-01-09 14:31:15 +08:00
LibXZR
db5d8694c4 Fix unable to show attachment parent in manage-medias (#1693) 2024-01-08 22:56:39 +08:00
Fen
2051c040ec Fix/classic 22 (#1690)
* fix: auto dark mode

* improve: pagenav style, theme color

* improve: color schema name

* fix: icon color

* improve: page navigation style
2024-01-07 13:47:59 +08:00
joyqi
13282b5b84 fix undefined array key (#1688)
* fix undefined array key

* fix: change security email
2024-01-07 11:38:39 +08:00
Fen
af281422d3 update theme classic-22 color schema (#1689)
* fix: auto dark mode

* improve: pagenav style, theme color

* improve: color schema name

* fix: icon color
2024-01-07 00:39:10 +08:00
LibXZR
68026e0fbc Fix unable to preview revisions (#1687)
* Fix unable to preview revisions

* Improve revision preview fix

Co-authored-by: joyqi <joyqi@users.noreply.github.com>

---------

Co-authored-by: joyqi <joyqi@users.noreply.github.com>
2024-01-06 23:33:11 +08:00
joyqi
a9fa990124 replace str compare (#1685) 2024-01-06 12:20:41 +08:00
Lu Fei
9635a7a0ba Optimize applySlug (#1684)
* Optimize applySlug

* optimize code

* fix: more rigorous judgment

* improve slug generating

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
2024-01-05 15:55:34 +08:00
Lu Fei
9396eef2f9 Remove useless code (#1683) 2024-01-05 11:27:13 +08:00
Fen
cec6b9c62b update theme classic-22 (#1682)
* Add feed widget

* add feed render

* Add CommentPage widget

* New theme (#1390)

* 调整忽略目录

* add theme

* fix theme scss build

Co-authored-by: fen <f3nb0x@gmail.com>

* s/is_writeable/is_writable/g

* New upgrade method

* merge new fixes from master

* add pgsql ssl mode support (ref #1600) (#1623)

* Feat/code refactor (#1626)

* remove all magic methods, add type for class properties

* refactor codes

* fix all

* refactor code

* fix type

* fix all

* fix request is method

* fix all

* fix router

* fix get page

* fix 1.3.0 upgrade

* [feat] support high resolution avatar

* fix types in i18n component

* Implement Ctrl+S or Command+S for save draft (#1628)

* Implement Ctrl+S or Command+S for save draft

* rename

* add Typecho.savePost

* fix upload file size

* add new uploader

* replace new uploader

* fix textarea change

* fix preview

* refactor post edit

* fix issue

* fix page edit

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* fix #1632

* Add svg to image types

* Feat/tree pages (#1646)

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Support IDN (#1629)

* Support IDN

* use js

* Optimize code

* Optimize code

* fix URL script

* remove unnecessary use

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* fix input element

* fix #1651, close #1653

* Use json instead of serialize (#1624)

* Use json instead of serialize

* Fix Upgrade code

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Fix typo

* remove proxy methods

* remove unnecessary useage

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* Fix Prevent XSS vulnerability in default theme (#1654)

* Fix Prevent XSS vulnerability in default theme

* Update var/Typecho/Db/Adapter/Pdo.php

* fix the getter

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* add throwCallback to widget response

* fix: cut down fields when selecting recent posts

* fix typo errors

* fix typo errors

* fix http client cookie

* add throw finish

* fix theme lang

* fix default theme

* fix query

* add open graph and twitter card support
add canonical link

* fix canonical link meta

* fix theme classic-22

* remove unnecessary scss file when packaging

* init plugin signal

* improve: remove feather-icon js file

* fix: typo

* improve: post detail layout

* fix tags saving

* improve: nav search

* fix: theme screenshot

* fix: theme page layout

* remove php 7.2/7.3 env

* feat: pull request auto merge

* fix permission

* improve: comment style

* fix: search result

* improve: show site description in homepage title

---------

Co-authored-by: joyqi <magike.net@gmail.com>
Co-authored-by: joyqi <joyqi@users.noreply.github.com>
Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: Lu Fei <52o@qq52o.cn>
2024-01-05 00:11:38 +08:00
joyqi
f23e825b95 fix router 2024-01-04 23:13:16 +08:00
joyqi
1c3b86fc22 fix #1679 (#1680)
Detect the insertion point of reply form automatically.
2024-01-04 22:47:15 +08:00
Fen
540dbb3b21 Create SECURITY.md 2024-01-04 17:12:29 +08:00
joyqi
81ad2232bf fix #1671 (#1678) 2024-01-04 11:13:36 +08:00
Lu Fei
d520a556cf fix style error for code (#1677) 2024-01-02 13:47:29 +08:00
joyqi
77aebcbd0e fix #1674 (#1676) 2024-01-02 11:16:44 +08:00
LibXZR
f3299ecb8a Fix broken link when paging by category or tags (#1673) 2024-01-01 18:34:20 +08:00
joyqi
b88a733dc0 Dev (#1670)
* Add feed widget

* add feed render

* Add CommentPage widget

* New theme (#1390)

* 调整忽略目录

* add theme

* fix theme scss build

Co-authored-by: fen <f3nb0x@gmail.com>

* s/is_writeable/is_writable/g

* New upgrade method

* merge new fixes from master

* add pgsql ssl mode support (ref #1600) (#1623)

* Feat/code refactor (#1626)

* remove all magic methods, add type for class properties

* refactor codes

* fix all

* refactor code

* fix type

* fix all

* fix request is method

* fix all

* fix router

* fix get page

* fix 1.3.0 upgrade

* [feat] support high resolution avatar

* fix types in i18n component

* Implement Ctrl+S or Command+S for save draft (#1628)

* Implement Ctrl+S or Command+S for save draft

* rename

* add Typecho.savePost

* fix upload file size

* add new uploader

* replace new uploader

* fix textarea change

* fix preview

* refactor post edit

* fix issue

* fix page edit

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* fix #1632

* Add svg to image types

* Feat/tree pages (#1646)

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Support IDN (#1629)

* Support IDN

* use js

* Optimize code

* Optimize code

* fix URL script

* remove unnecessary use

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* fix input element

* fix #1651, close #1653

* Use json instead of serialize (#1624)

* Use json instead of serialize

* Fix Upgrade code

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Fix typo

* remove proxy methods

* remove unnecessary useage

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* Fix Prevent XSS vulnerability in default theme (#1654)

* Fix Prevent XSS vulnerability in default theme

* Update var/Typecho/Db/Adapter/Pdo.php

* fix the getter

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* add throwCallback to widget response

* fix: cut down fields when selecting recent posts

* fix typo errors

* fix typo errors

* fix http client cookie

* add throw finish

* fix theme lang

* fix default theme

* fix query

* add open graph and twitter card support
add canonical link

* fix canonical link meta

* fix theme classic-22

* remove unnecessary scss file when packaging

* init plugin signal

* improve: remove feather-icon js file

* fix: typo

* improve: post detail layout

* fix tags saving

* improve: nav search

* fix: theme screenshot

* fix: theme page layout

* remove php 7.2/7.3 env

* feat: pull request auto merge

* fix permission

---------

Co-authored-by: fen <f3nb0x@gmail.com>
Co-authored-by: Lu Fei <52o@qq52o.cn>
2023-12-31 17:13:56 +08:00
jrotty
746667a8e6 删除多余无用js (#1668)
看了下默认主题没有引用任何js,这个应该是多余的
2023-12-31 17:05:45 +08:00
joyqi
6232de74e9 Merge pull request branch automatically (#1669)
* Add feed widget

* add feed render

* Add CommentPage widget

* New theme (#1390)

* 调整忽略目录

* add theme

* fix theme scss build

Co-authored-by: fen <f3nb0x@gmail.com>

* s/is_writeable/is_writable/g

* New upgrade method

* merge new fixes from master

* add pgsql ssl mode support (ref #1600) (#1623)

* Feat/code refactor (#1626)

* remove all magic methods, add type for class properties

* refactor codes

* fix all

* refactor code

* fix type

* fix all

* fix request is method

* fix all

* fix router

* fix get page

* fix 1.3.0 upgrade

* [feat] support high resolution avatar

* fix types in i18n component

* Implement Ctrl+S or Command+S for save draft (#1628)

* Implement Ctrl+S or Command+S for save draft

* rename

* add Typecho.savePost

* fix upload file size

* add new uploader

* replace new uploader

* fix textarea change

* fix preview

* refactor post edit

* fix issue

* fix page edit

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* fix #1632

* Add svg to image types

* Feat/tree pages (#1646)

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Support IDN (#1629)

* Support IDN

* use js

* Optimize code

* Optimize code

* fix URL script

* remove unnecessary use

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* fix input element

* fix #1651, close #1653

* Use json instead of serialize (#1624)

* Use json instead of serialize

* Fix Upgrade code

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Fix typo

* remove proxy methods

* remove unnecessary useage

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* Fix Prevent XSS vulnerability in default theme (#1654)

* Fix Prevent XSS vulnerability in default theme

* Update var/Typecho/Db/Adapter/Pdo.php

* fix the getter

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* add throwCallback to widget response

* fix: cut down fields when selecting recent posts

* fix typo errors

* fix typo errors

* fix http client cookie

* add throw finish

* fix theme lang

* fix default theme

* fix query

* add open graph and twitter card support
add canonical link

* fix canonical link meta

* fix theme classic-22

* remove unnecessary scss file when packaging

* init plugin signal

* improve: remove feather-icon js file

* fix: typo

* improve: post detail layout

* fix tags saving

* improve: nav search

* fix: theme screenshot

* fix: theme page layout

* remove php 7.2/7.3 env

* feat: pull request auto merge

---------

Co-authored-by: fen <f3nb0x@gmail.com>
Co-authored-by: Lu Fei <52o@qq52o.cn>
2023-12-31 17:04:45 +08:00
Lu Fei
e306960db4 Fix installation failure (#1664)
* Fix installation failure

* fix missing secret

* Apply suggestions from code review
2023-12-31 16:10:05 +08:00
joyqi
3caebb3b20 v1.3.0 (#1661)
* Add feed widget

* add feed render

* Add CommentPage widget

* New theme (#1390)

* 调整忽略目录

* add theme

* fix theme scss build

Co-authored-by: fen <f3nb0x@gmail.com>

* s/is_writeable/is_writable/g

* New upgrade method

* merge new fixes from master

* add pgsql ssl mode support (ref #1600) (#1623)

* Feat/code refactor (#1626)

* remove all magic methods, add type for class properties

* refactor codes

* fix all

* refactor code

* fix type

* fix all

* fix request is method

* fix all

* fix router

* fix get page

* fix 1.3.0 upgrade

* [feat] support high resolution avatar

* fix types in i18n component

* Implement Ctrl+S or Command+S for save draft (#1628)

* Implement Ctrl+S or Command+S for save draft

* rename

* add Typecho.savePost

* fix upload file size

* add new uploader

* replace new uploader

* fix textarea change

* fix preview

* refactor post edit

* fix issue

* fix page edit

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* fix #1632

* Add svg to image types

* Feat/tree pages (#1646)

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Support IDN (#1629)

* Support IDN

* use js

* Optimize code

* Optimize code

* fix URL script

* remove unnecessary use

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* fix input element

* fix #1651, close #1653

* Use json instead of serialize (#1624)

* Use json instead of serialize

* Fix Upgrade code

* add tree trait

* finish category tree trait

* support select fields

* fix select fields

* refactor admin trait

* fix draft status

* Add new contents type "revision"

* minor refactor

* add more tree view abstracts

* add tree trait to pages

* get ready for tree view pages

* improve page edit

* fix revision

* fix slug

* add router params delegate

* fix params delegate

* fix

* fix

* fix all

* fix all

* fix tree

* fix page link

* fix feed

* fix page

* fix permalink

* fix permalink input

* fix offset query

* Fix typo

* remove proxy methods

* remove unnecessary useage

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
Co-authored-by: joyqi <magike.net@gmail.com>

* Fix Prevent XSS vulnerability in default theme (#1654)

* Fix Prevent XSS vulnerability in default theme

* Update var/Typecho/Db/Adapter/Pdo.php

* fix the getter

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>

* add throwCallback to widget response

* fix: cut down fields when selecting recent posts

* fix typo errors

* fix typo errors

* fix http client cookie

* add throw finish

* fix theme lang

* fix default theme

* fix query

* add open graph and twitter card support
add canonical link

* fix canonical link meta

* fix theme classic-22

* remove unnecessary scss file when packaging

* init plugin signal

* improve: remove feather-icon js file

* fix: typo

* improve: post detail layout

* fix tags saving

* improve: nav search

* fix: theme screenshot

* fix: theme page layout

* remove php 7.2/7.3 env

---------

Co-authored-by: fen <f3nb0x@gmail.com>
Co-authored-by: Lu Fei <52o@qq52o.cn>
2023-12-30 23:02:25 +08:00
insomnux
43c54328f7 gettext for installation comment (#1643)
Co-authored-by: insomnux <insomnux@insomnus.info>
2023-10-31 11:30:54 +08:00
joyqi
99212ec787 fix #1635 (#1636) 2023-10-03 11:14:04 +08:00
Lu Fei
5f52c1e25b Fix null argument issue (#1633) 2023-10-03 11:12:46 +08:00
jrotty
272fc8b3e1 增加邮箱也可以登陆的提示 (#1631)
😭用了八年,今天翻代码才知道也可以用邮箱登陆
2023-09-29 15:12:11 +08:00
Losses Don
e143be0036 fix: Fix #1597 (#1598) 2023-09-22 10:54:38 +08:00
joyqi
91ae56484d fix the source to get content type (#1622) 2023-09-22 10:50:39 +08:00
Lu Fei
9910a9cddc Optimize checkVersion,feed code (#1605) 2023-09-22 10:49:51 +08:00
Jealous
666619538a Fix typo (#1612) 2023-09-21 22:48:27 +08:00
Kent Liao
9d1b01a873 fix: adding checkbox options after theme initialization cannot be saved. (#1591)
* fix: adding checkbox options after theme initialization cannot be saved.

* chore: Use isset to determine if an option exists
2023-06-14 08:58:27 +08:00
logdd
206880ba71 重复执行判断的优化 (#1586)
使用$isNamespace变量,避免重复判断
2023-06-05 15:15:24 +08:00
joyqi
c1753aa04e improve release ci, upload built asset after new release published. (#1576) 2023-05-17 11:35:18 +08:00
joyqi
6f19a24aa3 fix #1574 (#1575)
* split multiple values

* add a new field type 'json' to handle complex situation

* fix json input display
2023-05-16 21:45:41 +08:00
沈唁
c725fec12e Add a prompt message for manual database creation (#1348)
* Optimize for no database during install

* change tips
2023-05-16 14:33:26 +08:00
joyqi
596d117210 fix: when setting CheckBox's default value to null [ref #1568] 2023-05-16 12:33:49 +08:00
joyqi
0433a11c0a escape mail string before output 2023-05-15 22:35:25 +08:00
joyqi
98e4c1d16d fix url validate 2023-05-15 21:44:12 +08:00
joyqi
7a41f0d013 fix email validate 2023-05-15 19:55:36 +08:00
Ryan Lieu
c9de1b3b01 fix php 8.1 Deprecated: htmlspecialchars(): Passing null to parameter #1 (#1570)
* Fix multiple calls returning the same object

* fix: strtolower() passing null to parameter #1 ($string) of type string is deprecated

* fix: php 8.1 Deprecated: htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated
2023-05-15 18:30:44 +08:00
Patrick SAMA
83d4d020ed Fix an XSS vulnerability in v1.2.1-rc (#1561)
* fix #1560

* Update var/Typecho/Validate.php

Co-authored-by: 沈唁 <52o@qq52o.cn>

---------

Co-authored-by: joyqi <joyqi@users.noreply.github.com>
Co-authored-by: 沈唁 <52o@qq52o.cn>
2023-05-15 18:29:47 +08:00
Ryan Lieu
01100c9a4a Fix: php 8.1 strtolower not allow null value (#1559) 2023-04-14 11:45:09 +08:00
沈唁
daef17d7eb Support ssl for pdo_mysql and mysqli (#1525)
* Support ssl for pdo_mysql and mysqli

* Improve config name for mysql ssl mode, and fix some minor bugs.

* Fix typo

---------

Co-authored-by: joyqi <joyqi@segmentfault.com>
2023-03-29 14:33:23 +08:00
joyqi
65f5974e17 Replace the protocol of backend remote checking url from http to https. 2023-03-28 12:07:33 +08:00
Zero King
f6e1232db8 Use https links (#1280) 2023-03-28 11:57:45 +08:00
joyqi
b989459d87 fix #1545 and close #1547 2023-03-28 11:36:01 +08:00
joyqi
a609b149e9 fix #1539 2023-03-03 16:37:32 +08:00
joyqi
f9ede542c9 fix #1535 2023-02-21 17:43:20 +08:00
沈唁
16d21f03ef Fix htmlspecialchars error for feed (#1522) 2023-01-11 00:45:28 +08:00
Zero King
8437eac420 Fix unsafe use of jQuery .html() (#1382) 2022-10-29 23:54:13 +08:00
joyqi
f0bf9d770d update readme 2022-10-25 14:53:09 +08:00
沈唁
e05ebe442e Fix #1495 (#1496)
Argument 1 passed to Utils\AutoP::parse() must be of the type string, null given
2022-09-22 10:25:18 +08:00
沈唁
17d9dcfa17 Fix comments feed jump error (#1491) 2022-08-15 07:24:43 +08:00
沈唁
2014be4cd3 Adjust style of edit comments (#1483)
* Adjust style of edit comments

Fix #1481

* update

* update
2022-08-01 14:56:22 +08:00
沈唁
d15fc14463 Fix use SQLite error of windows install (#1471) 2022-07-20 00:20:25 +08:00
Ryan Lieu
f07b57fe20 Fix multiple calls returning the same object (#1478) 2022-07-15 11:19:18 +08:00
沈唁
c03ee2c8be Fix the error of getting request parameters (#1464) 2022-06-21 13:59:53 +08:00
Kane
4095850140 Minor update (#1460)
- 后台上传设置增加 avif 类型
- 后台 Avatar 头像支持原生懒加载
2022-06-14 18:57:07 +08:00
Kane
7f7b24d28f Minor update (#1451)
* Update

- 更新 Windows 和 Linux 系统中文本编辑器样式问题(为代码块中添加中文后备字体修正样式)

* Update

- 缩略图支持识别 avif 图片(具体可参考https://en.wikipedia.org/wiki/AVIF
2022-06-07 18:08:24 +08:00
joyqi
1d0e253281 Fix page draft publish 2022-06-01 23:50:36 +08:00
沈唁
88c3bfe13f Fix #1449 (#1450) 2022-05-30 11:11:44 +08:00
沈唁
59a5c8d14d Fix category creation error when using xmlrpc (#1443)
* Fix category creation error when using xmlrpc

* Add use Typecho\Request
2022-05-23 10:44:59 +08:00
joyqi
3119c05e2c fix #1441, fix #1442 2022-05-17 10:24:56 +08:00
joyqi
05e20c0ae5 Fix themeUrl format 2022-05-13 00:46:12 +08:00
沈唁
7279d4832d Fix missing change themeUrl (#1431)
* Fix missing change themeUrl

* Use options themeUrl method
2022-05-13 00:26:10 +08:00
沈唁
ac33000ad0 Add admin/footer.php begin plugin (#1426) 2022-05-07 16:33:00 +08:00
MBRjun Duplicate
02937dc51c Fix QUIC/https Mixed Content (#1423) 2022-05-04 09:31:59 +08:00
jrotty
437d296af5 修复管理员进入其他用户文章列表时显示所有文章的bug (#1415)
* 修复管理员进入其他用户文章列表时显示所有文章的bug

bug描述:当管理员在文章管理页面,点击所有查看所有文章后,再通过这个页面进入作者文章管理页面时,仍会显示所有文章而不是当前作者的文章

* Update manage-users.php

* Fix missing manage-posts

Co-authored-by: sy-records <52o@qq52o.cn>
2022-04-29 10:53:05 +08:00
沈唁
f31e6daf7b Fix notice not clear (#1416) 2022-04-26 10:29:26 +08:00
jrotty
f8a9d95e43 修正注释 (#1411)
* 修正注释

* 修正注释
2022-04-23 18:00:02 +08:00
jrotty
0fbb1aaea5 模板缩略图支持识别webp图片后缀 (#1403)
* 模板缩略图支持识别webp图片后缀

* Update Contents.php

Co-authored-by: 沈唁 <52o@qq52o.cn>
2022-04-15 13:51:06 +08:00
Valpha
9fd02529b1 Update write-js.php (#1400)
Add 'allow-same-origin' into sandbox's attrs to fix that the article preview page does not match the real page.
2022-04-15 13:50:13 +08:00
沈唁
3512fd41bf Enhancement of Typecho\Cookie (#1399) 2022-04-14 15:49:04 +08:00
joyqi
997aa607ac fix words 2022-04-07 11:28:28 +08:00
沈唁
3b03e0267b Update admin welcome tip (#1389) 2022-04-07 11:26:02 +08:00
joyqi
61606a9069 fix #1380 2022-04-05 22:53:39 +08:00
joyqi
34e5bf2861 fix #1375 2022-04-04 00:01:33 +08:00
沈唁
c78f7fda68 Fix pgsql reset id error (#1369) 2022-04-02 21:27:31 +08:00
joyqi
7ebfe82de1 fix #1361 2022-04-02 18:10:28 +08:00
joyqi
004db7c056 Move language build trigger from workflows/dev to workflows/release. 2022-04-02 16:41:37 +08:00
joyqi
d4068b1661 fix #1363, close #1364
Add json request & response. Perform async service via json request.
2022-04-02 15:33:17 +08:00
joyqi
d77a1ecad7 Delete config.inc.sqlite.php 2022-04-01 16:55:08 +08:00
joyqi
ded268ef59 Pr/1344 (#1360)
* Add missing theme action

* Fix typo

* Optimize code

* Optimize code

* Update themes.php

* Simpler missing theme judgement

Co-authored-by: sy-records <52o@qq52o.cn>
2022-04-01 16:50:23 +08:00
joyqi
142a615feb Merge branch 'master' of github.com:typecho/typecho 2022-04-01 15:25:28 +08:00
joyqi
c30b67d18d Update .gitignore
update gitignore
2022-04-01 15:25:10 +08:00
毛线
2db893e802 Update install.php (#1357)
修复宝塔面板的网站目录带.导致db路径校验不通过的问题
2022-04-01 14:07:08 +08:00
沈唁
2f3e15dfb8 Fix checkVersion (#1356) 2022-04-01 11:12:54 +08:00
沈唁
4be93f2741 Fix missing mysqli_connect_errno (#1346) 2022-03-28 12:11:24 +08:00
joyqi
6100695d87 fix db exception 2022-03-25 15:31:57 +08:00
fen
0bdf8721e1 add ignore 2022-03-25 12:08:22 +08:00
沈唁
ce7af58367 Optimize code (#1342) 2022-03-24 17:46:03 +08:00
joyqi
1b673e06ff fix typecho/Dockerfile#9 2022-03-22 14:24:14 +08:00
joyqi
0edb48fae0 fix #1335, close #1337 2022-03-16 21:05:22 +08:00
沈唁
17fcb2f08b Fix undefined Typecho\Db\Adapter_Exception (#1334) 2022-03-15 16:09:32 +08:00
joyqi
5f943d48b5 fix #1329 2022-02-25 21:16:12 +08:00
joyqi
b23277267a fix #1328 2022-02-24 23:21:35 +08:00
沈唁
b0d78a81dc Fix #1326 (#1327) 2022-02-21 21:51:13 +08:00
沈唁
f34d14280d Fix compatibility with PHP 8.1 (#1324)
* Fix compatibility with PHP 8.1

PHP Deprecated:  htmlspecialchars(): Passing null to parameter #1 ($string) of type string is deprecated in typecho/var/Widget/Archive.php on line 1292

* Fix login

* Fix write

* Fix manage

* Fix PHP Deprecated
2022-02-15 11:10:47 +08:00
沈唁
13dc5e87dd Fix #1322 (#1323)
Great work!
2022-02-15 11:10:15 +08:00
沈唁
0b021e5e7d Fix broken extends.typecho.org link (#1315)
close #857
2022-02-09 11:41:35 +08:00
joyqi
00c75d2f75 fix version compare 2022-01-30 00:30:28 +08:00
joyqi
1eedc481ad fix #1295, ref #1297 2022-01-29 17:46:48 +08:00
joyqi
75899e287d fix #1268 2022-01-28 23:58:31 +08:00
jiayx
047bd17f19 Fixes for PHP 8.1 compatibility (#1293)
* Fixes for PHP 8.1 compatibility

* Fixes for PHP 8.1 compatibility

* 优化写法

* remove mixed type

* fix nullable column

* fix query filter

* recover

* recover fileds

* recover

* Update Text.php

* Update Text.php

Co-authored-by: joyqi <joyqi@users.noreply.github.com>
2022-01-28 23:51:24 +08:00
joyqi
9c075dcdf0 fix #1279 2022-01-13 14:04:58 +08:00
joyqi
157fc05265 fix #1268 2021-12-13 11:58:35 +08:00
joyqi
c047669900 fix #1257 2021-12-06 22:09:17 +08:00
joyqi
eee0228fed Refactor HttpClient, fix #1246 2021-11-18 00:20:24 +08:00
joyqi
389b46635e fix client 2021-11-17 18:34:01 +08:00
joyqi
919911e288 fix redirect 2021-11-17 00:33:05 +08:00
joyqi
dd4bf889de fix #1222 2021-11-04 16:37:29 +08:00
joyqi
0dcf45a152 fix #1220 2021-10-30 00:02:41 +08:00
joyqi
ceaa545c7d fix #1212 2021-10-28 19:53:18 +08:00
joyqi
01d9d0c3f5 fix #1207 2021-10-28 12:04:00 +08:00
joyqi
6b46dd9c50 Merge branch 'master' of github.com:typecho/typecho 2021-10-21 22:09:05 +08:00
joyqi
cb4457ab52 fix #1201 2021-10-21 22:08:53 +08:00
joyqi
8a57b91343 fix #1203 2021-10-21 18:49:05 +08:00
joyqi
c66b6e20ec fix #1187 2021-10-21 11:10:34 +08:00
joyqi
b33a9c4d02 ref https://github.com/typecho/Dockerfile/issues/1 2021-10-13 18:34:46 +08:00
joyqi
cac1c650a1 fix #1196 2021-10-13 16:31:15 +08:00
joyqi
42e192340d fix #1194 2021-10-13 15:50:40 +08:00
joyqi
b677f7db92 Merge branch 'master' of github.com:typecho/typecho 2021-10-13 14:33:43 +08:00
joyqi
2fbc56dead ref https://github.com/typecho/Dockerfile/issues/1 2021-10-13 14:33:28 +08:00
joyqi
d174cc5732 update hyperdown 2021-09-30 01:06:14 +08:00
joyqi
5557f6dd91 fix clear 2021-09-29 17:10:34 +08:00
joyqi
42fe6f7bf5 fix #1191 2021-09-26 16:15:17 +08:00
joyqi
1f1019ba5b fix #1189 2021-09-23 11:29:10 +08:00
joyqi
13d18e02cc Create CODE_OF_CONDUCT.md 2021-09-17 21:59:56 +08:00
joyqi
e46acd815d improve cli install 2021-09-17 15:15:54 +08:00
joyqi
432b69f70d fix install detect & error display 2021-09-17 15:06:05 +08:00
joyqi
0e750771ae fix service 2021-09-16 21:54:49 +08:00
joyqi
fc9aaf66f3 Use TypechoPlugin\ for plugin namespace 2021-09-16 17:53:59 +08:00
joyqi
ec495d7e24 Add magic method to native request object 2021-09-16 17:05:43 +08:00
joyqi
f6b02ebe24 fix port number 2021-09-16 15:42:17 +08:00
joyqi
64b8e68688 fix #1178, change directory permission from 0777 to 0755 2021-09-15 14:59:08 +08:00
joyqi
4e5b88821d fix #1179 2021-09-15 14:33:23 +08:00
joyqi
a003cffbbb fix radio & checkbox vertical alignment. 2021-09-15 14:15:06 +08:00
joyqi
7ef5fcabd5 fix pingback & request 2021-09-15 01:25:36 +08:00
joyqi
3c4a0022c3 fix pingback 2021-09-15 00:31:13 +08:00
joyqi
780c3b61f4 fix ci build 2021-09-14 22:21:51 +08:00
joyqi
1d21ecac16 fix zip 2021-09-14 21:48:43 +08:00
joyqi
2d777ec061 fix tar 2021-09-14 21:39:06 +08:00
joyqi
5d20d57be9 fix #1173 2021-09-14 00:24:56 +08:00
joyqi
3f14d6e138 fix 2021-09-12 18:09:37 +08:00
joyqi
1ee18ad532 fix #1160 2021-09-11 01:06:54 +08:00
joyqi
419183ae2f fix #1167 2021-09-10 23:09:59 +08:00
joyqi
0916631ae2 fix #1165 2021-09-10 17:36:52 +08:00
joyqi
4186cdec6a fix #1164 2021-09-10 14:52:55 +08:00
joyqi
cbb270ea89 fix backup recover error 2021-09-10 11:47:55 +08:00
joyqi
d839f390ee fix #1163, fix #1164 2021-09-10 11:26:04 +08:00
joyqi
26e8077e0a fix alias 2021-09-10 02:28:15 +08:00
joyqi
b5167dbe5d fix #1158 2021-09-10 02:22:45 +08:00
joyqi
a1bf3d037b fix #1162 2021-09-09 20:18:11 +08:00
joyqi
ed30a99655 fix request response error 2021-09-09 20:08:04 +08:00
joyqi
bf2cb07e4b fix #1160 2021-09-09 18:20:30 +08:00
joyqi
729dcf729a fix #1160 2021-09-09 17:45:15 +08:00
joyqi
58cb9105d4 fix #1157 2021-09-09 15:06:05 +08:00
joyqi
eb77897ab6 fix #1159 2021-09-09 14:09:19 +08:00
joyqi
4ad930a31d Merge branch 'master' of github.com:typecho/typecho 2021-09-09 11:41:39 +08:00
joyqi
fa222ba7a2 fix #1157 2021-09-09 11:41:17 +08:00
joyqi
519e84e74c fix #1156 2021-09-09 00:16:07 +08:00
joyqi
57106d85c9 fix requestUri 2021-09-08 22:33:26 +08:00
joyqi
a4883be588 fix #1155 2021-09-08 22:18:11 +08:00
joyqi
96eb56fc35 fix #1154 2021-09-08 21:47:54 +08:00
joyqi
a3d698c09e fix actions 2021-09-08 16:36:56 +08:00
276 changed files with 13141 additions and 30672 deletions

View File

@@ -1,14 +0,0 @@
### 1. 该问题的重现步骤是什么?
### 2. 你期待的结果是什么?实际看到的又是什么?
### 3. 问题出现的环境
- 操作系统版本:
- Apache/NGINX 版本:
- 数据库版本:
- PHP 版本:
- Typecho 版本:
- 浏览器版本:
[//]: # (如有图片请附上截图)

42
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,42 @@
---
name: 上报 BUG
about: 报告问题,帮助改进项目
title: ''
labels: bug
assignees: ''
---
## 描述这个 Bug
简明扼要地描述错误是什么。
### 复现方式
复现的步骤:
1. 前往 '...'
2. 点击 '....'
3. 滚动到 '....'
4. 看到错误
### 期望的结果
简明扼要地描述你期望看到的结果。
### 截图
如果可以的话,请添加截图或视频以帮助解释你的问题。
### 平台
- 操作系统版本:
- Apache/Nginx 版本:
- 数据库版本:
- PHP 版本:
- Typecho 版本:
- 浏览器版本:

5
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: 论坛支持
url: https://forum.typecho.org/
about: 交流使用心得,使用模板插件,寻求帮助等等

View File

@@ -0,0 +1,23 @@
---
name: 提改进建议
about: 提出改进建议,改进项目现有功能
title: ''
labels: enhancement
assignees: ''
---
## 你的改进是否与某个问题有关?请描述
简明扼要地描述问题产生的原因。例如:当 [...] 时,我总是很困惑。
## 描述你想要的解决方案
简明扼要地描述你希望的解决方案。
## 描述你考虑过的替代方案
简明扼要地描述你考虑过的任何替代解决方案或功能。

View File

@@ -0,0 +1,23 @@
---
name: 新功能提议
about: 为项目提出一个想法或可能的新功能
title: ''
labels: feature
assignees: ''
---
## 你的想法是否与某个问题有关?请描述
简明扼要地描述问题产生的原因。例如:当 [...] 时,我总是很困惑。
## 描述你想要的解决方案
简明扼要地描述你希望的解决方案。
## 描述你考虑过的替代方案
简明扼要地描述你考虑过的任何替代解决方案或功能。

View File

@@ -0,0 +1,7 @@
Fixes #
## Proposed Changes
-
-
-

View File

@@ -12,14 +12,14 @@ jobs:
php:
name: PHP ${{ matrix.php }} Tests
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'skip ci')"
if: ${{ !contains(github.event.head_commit.message, 'skip ci') }}
strategy:
fail-fast: false
matrix:
php: ['7.2', '7.3', '7.4', '8.0']
php: ['7.4', '8.0', '8.1', '8.2']
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Setup PHP only
uses: shivammathur/setup-php@v2
with:
@@ -30,31 +30,29 @@ jobs:
build:
name: Typecho Build
runs-on: ubuntu-latest
if: "!contains(github.event.head_commit.message, 'skip ci') && github.event_name != 'pull_request'"
if: ${{ !contains(github.event.head_commit.message, 'skip ci') && github.event_name != 'pull_request' && github.repository == 'typecho/typecho' }}
needs:
- php
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install tree
run: sudo apt-get -y install tree
uses: actions/checkout@v4
- name: Build
run: |
mkdir build
cp -r LICENSE.txt index.php install.php admin install usr var build/
mkdir build/usr/uploads/
chmod 777 build/usr/uploads/
chmod 755 build/usr/uploads/
rm -rf build/admin/src
tree -d build
rm -rf build/usr/themes/classic-22/static/scss
cd build && zip -q -r typecho.zip * && mv typecho.zip ../ && cd -
- name: Upload a Build Artifact
uses: actions/upload-artifact@v2
uses: WebFreak001/deploy-nightly@v1.1.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
name: typecho
path: ./build/
- name: Trigger build
run: |
curl -XPOST -H "Authorization: token ${{ secrets.WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github.everest-preview+json" \
-H "Content-Type: application/json" \
https://api.github.com/repos/typecho/languages/actions/workflows/update.yml/dispatches --data '{"ref": "master"}'
upload_url: https://uploads.github.com/repos/typecho/typecho/releases/49532662/assets{?name,label}
release_id: 49532662
asset_path: ./typecho.zip
asset_name: typecho.zip
asset_content_type: application/zip
max_releases: 1

View File

@@ -0,0 +1,36 @@
name: Typecho Hotfix Merge
on:
pull_request:
types:
- closed
- labeled
branches:
- master
jobs:
auto-merge:
if: github.event.action == 'closed' && github.event.pull_request.merged == true && startsWith(github.event.pull_request.head.ref, 'fix/')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Merge to dev branch
uses: devmasx/merge-branch@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
from_branch: ${{ github.event.pull_request.head.ref }}
target_branch: dev
label-merge:
if: github.event.action == 'labeled' && !startsWith(github.event.pull_request.head.ref, 'fix/')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Merge to dev branch
uses: devmasx/merge-branch@master
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
label_name: 'merge-to-dev'
target_branch: dev

View File

@@ -1,39 +1,33 @@
name: Typecho Build Release Ci
on:
push:
tags:
- 'v*'
release:
types: [published]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Build
run: |
mkdir build
cp -r LICENSE.txt index.php install.php admin install usr var build/
mkdir build/usr/uploads/
chmod 777 build/usr/uploads/
chmod 755 build/usr/uploads/
rm -rf build/admin/src
zip -q -r typecho.zip ./build
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: ${{ github.ref }}
draft: true
prerelease: false
rm -rf build/usr/themes/classic-22/static/scss
cd build && zip -q -r typecho.zip * && mv typecho.zip ../ && cd -
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: shogo82148/actions-upload-release-asset@v1
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
upload_url: ${{ github.event.release.upload_url }}
asset_path: ./typecho.zip
asset_name: typecho.zip
asset_content_type: application/zip
- name: Trigger language build
run: |
curl -XPOST -H "Authorization: token ${{ secrets.WORKFLOW_TOKEN }}" \
-H "Accept: application/vnd.github.everest-preview+json" \
-H "Content-Type: application/json" \
https://api.github.com/repos/typecho/languages/actions/workflows/update.yml/dispatches --data '{"ref": "master"}'

18
.gitignore vendored
View File

@@ -24,12 +24,14 @@
*.sublime*
.sass-cache
config.rb
/config.inc.php
/usr/uploads/
/usr/*.db
/usr/plugins/
!/usr/plugins/HelloWorld
/usr/themes/
!/usr/themes/default
prepros.config
config.inc.*
usr/uploads/
usr/*.db
usr/plugins/
!usr/plugins/HelloWorld
usr/themes/*
!usr/themes/default
!usr/themes/classic-22
node_modules/
/tools/tmp/
tools/tmp/

0
.gitmodules vendored
View File

128
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
admin@typecho.org.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

37
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,37 @@
Contributing to Typecho
=======================
Thanks for considering contributing to Typecho! There are many ways to contribute to Typecho, and we appreciate all of them.
## Reporting Bugs
If you find a bug in the source code, you can help us by [submitting an issue](https://github.com/typecho/typecho/issues)
to our [GitHub Repository](https://github.com/typecho/typecho). Even better, you can submit a Pull Request with a fix.
## Contributing Code
If you would like to contribute code to Typecho, please read the following guidelines:
* [Code of Conduct](CODE_OF_CONDUCT.md)
* [Contributing Guide](CONTRIBUTING.md)
* [Coding Style Guide](CODING_STYLE.md)
## Translations
Please see [TRANSLATION](https://github.com/typecho/languages) for details.
## Plugin Development
Please see [Plugin Development](http://docs.typecho.org/plugins) for details.
## Theme Development
Please see [Theme Development](http://docs.typecho.org/themes) for details.
## Community
* [Telegram Channel](https://t.me/typechodev)
* [Homepage](http://typecho.org/)
* [Documents](http://docs.typecho.org/)
* [Community](http://forum.typecho.org/)
* [Download](http://typecho.org/download)

View File

@@ -1,19 +1,30 @@
Typecho Blogging Platform
=========================
Typecho is a PHP Blogging Platform. Simple and Powerful.
Typecho is a PHP-based blog software and is designed to be the most powerful blog engine in the world.
Typecho is released under the GNU General Public License 2.0.
#### Telegram Channel
https://t.me/typechodev
## Main Features
#### Homepage
http://typecho.org/
* Multiple databases support (MariaDB, MySQL, SQLite, PostgreSQL)
* Markdown Support
* Plugin Support
* Theme Support
* Custom Fields
* Custom Pages
#### Documents
http://docs.typecho.org/
## Requirements
#### Community
http://forum.typecho.org/
* PHP 7.4.0 or higher
* Database (MariaDB, MySQL, SQLite, PostgreSQL)
* MariaDB or MySQL 5.5.3 or higher
* SQLite 3.7.11 or higher
* PostgreSQL 9.1 or higher
#### Download
http://typecho.org/download
## Screenshots
![Typecho](https://typecho.org/usr/themes/bluecode/img/screenshot/st1.png)
## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

3
SECURITY.md Normal file
View File

@@ -0,0 +1,3 @@
# Security Policy
Vulnerabilities can be reported by emailing security@typecho.org

View File

@@ -10,7 +10,7 @@ $actionUrl = $security->getTokenUrl(
$backupFiles = \Widget\Backup::alloc()->listFiles();
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
@@ -31,7 +31,7 @@ $backupFiles = \Widget\Backup::alloc()->listFiles();
<div id="backup-secondary" class="col-mb-12 col-tb-4" role="form">
<h3><?php _e('恢复数据'); ?></h3>
<ul class="typecho-option-tabs clearfix">
<ul class="typecho-option-tabs">
<li class="active w-50"><a href="#from-upload"><?php _e('上传'); ?></a></li>
<li class="w-50"><a href="#from-server"><?php _e('从服务器'); ?></a></li>
</ul>
@@ -79,11 +79,12 @@ $backupFiles = \Widget\Backup::alloc()->listFiles();
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';
include 'common-js.php';
include 'form-js.php';
?>
<script>
$('#backup-secondary .typecho-option-tabs li').click(function() {

View File

@@ -4,7 +4,7 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
@@ -13,7 +13,7 @@ include 'menu.php';
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -13,7 +13,9 @@
noticeType : $.cookie(prefix + '__typecho_notice_type'),
highlight : $.cookie(prefix + '__typecho_notice_highlight')
},
path = '<?php echo \Typecho\Cookie::getPath(); ?>';
path = '<?php echo \Typecho\Cookie::getPath(); ?>',
domain = '<?php echo \Typecho\Cookie::getDomain(); ?>',
secure = <?php echo json_encode(\Typecho\Cookie::getSecure()); ?>;
if (!!cookies.notice && 'success|notice|error'.indexOf(cookies.noticeType) >= 0) {
var head = $('.typecho-head-nav'),
@@ -23,31 +25,10 @@
if (head.length > 0) {
p.insertAfter(head);
offset = head.outerHeight();
} else {
p.prependTo(document.body);
}
function checkScroll () {
if ($(window).scrollTop() >= offset) {
p.css({
'position' : 'fixed',
'top' : 0
});
} else {
p.css({
'position' : 'absolute',
'top' : offset
});
}
}
$(window).scroll(function () {
checkScroll();
});
checkScroll();
p.slideDown(function () {
var t = $(this), color = '#C6D880';
@@ -63,47 +44,16 @@
});
});
$.cookie(prefix + '__typecho_notice', null, {path : path});
$.cookie(prefix + '__typecho_notice_type', null, {path : path});
$.cookie(prefix + '__typecho_notice', null, {path : path, domain: domain, secure: secure});
$.cookie(prefix + '__typecho_notice_type', null, {path : path, domain: domain, secure: secure});
}
if (cookies.highlight) {
$('#' + cookies.highlight).effect('highlight', 1000);
$.cookie(prefix + '__typecho_notice_highlight', null, {path : path});
$.cookie(prefix + '__typecho_notice_highlight', null, {path : path, domain: domain, secure: secure});
}
})();
// 导航菜单 tab 聚焦时展开下拉菜单
const menuBar = $('.menu-bar').click(function () {
const nav = $(this).next('#typecho-nav-list');
if (!$(this).toggleClass('focus').hasClass('focus')) {
nav.removeClass('expanded noexpanded');
}
});
$('.main, .typecho-foot').on('click touchstart', function () {
if (menuBar.hasClass('focus')) {
menuBar.trigger('click');
}
});
$('#typecho-nav-list ul.root').each(function () {
const ul = $(this), nav = ul.parent();
ul.on('click touchend', '.parent a', function (e) {
nav.removeClass('noexpanded').addClass('expanded');
if ($(window).width() < 576 && e.type == 'click') {
return false;
}
}).find('.child')
.append($('<li class="return"><a><?php _e('返回'); ?></a></li>').click(function () {
nav.removeClass('expanded').addClass('noexpanded');
return false;
}));
});
if ($('.typecho-login').length == 0) {
$('a').each(function () {
var t = $(this), href = t.attr('href');
@@ -118,10 +68,6 @@
.attr('rel', 'noopener noreferrer');
});
}
$('.main form').submit(function () {
$('button[type=submit]', this).attr('disabled', 'disabled');
});
});
})();
</script>

View File

@@ -15,7 +15,7 @@ if (!defined('__TYPECHO_ROOT_DIR__') && !@include_once __DIR__ . '/../config.inc
\Widget\Init::alloc();
/** 注册一个初始化插件 */
\Typecho\Plugin::factory('admin/common.php')->begin();
\Typecho\Plugin::factory('admin/common.php')->call('begin');
\Widget\Options::alloc()->to($options);
\Widget\User::alloc()->to($user);

View File

@@ -1,13 +1,13 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<div class="typecho-foot" role="contentinfo">
<footer class="typecho-foot" role="contentinfo">
<div class="copyright">
<a href="http://typecho.org" class="i-logo-s">Typecho</a>
<p><?php _e('由 <a href="http://typecho.org">%s</a> 强力驱动, 版本 %s', $options->software, $options->version); ?></p>
<a href="https://typecho.org" class="i-logo-s">Typecho</a>
<p><?php _e('由 <a href="https://typecho.org">%s</a> 强力驱动, 版本 %s', $options->software, $options->version); ?></p>
</div>
<nav class="resource">
<a href="http://docs.typecho.org"><?php _e('帮助文档'); ?></a> &bull;
<a href="http://forum.typecho.org"><?php _e('支持论坛'); ?></a> &bull;
<a href="https://docs.typecho.org"><?php _e('帮助文档'); ?></a> &bull;
<a href="https://forum.typecho.org"><?php _e('支持论坛'); ?></a> &bull;
<a href="https://github.com/typecho/typecho/issues"><?php _e('报告错误'); ?></a> &bull;
<a href="http://extends.typecho.org"><?php _e('资源下载'); ?></a>
<a href="https://typecho.org/download"><?php _e('资源下载'); ?></a>
</nav>
</div>
</footer>

File diff suppressed because one or more lines are too long

View File

@@ -1,24 +1 @@
h1 { text-align: center; }
details summary { cursor: pointer; }
@keyframes fadein { from { opacity: 0; }
to { opacity: 1; } }
.fresh .keep-word { display: none; }
.keep .fresh-word { display: none; }
form > .message { display: none; padding: 20px; border-radius: 5px; }
.message textarea { width: 100%; height: 200px; resize: none; margin: 10px 0; }
.message.fade { display: block; animation: fadein .5s linear; }
.message *:last-child { margin-bottom: 0; }
.message p { margin-top: 10px; }
.message p button { margin-left: 5px; }
.message p button:first-child { margin-left: 0; }
h1{text-align:center}details summary{cursor:pointer}@keyframes fadein{from{opacity:0}to{opacity:1}}.fresh .keep-word{display:none}.keep .fresh-word{display:none}form>.message{display:none;padding:20px;border-radius:5px}.message textarea{width:100%;height:200px;resize:none;margin:10px 0}.message.fade{display:block;animation:fadein .5s linear}.message *:last-child{margin-bottom:0}.message p{margin-top:10px}.message p button{margin-left:5px}.message p button:first-child{margin-left:0}

View File

@@ -11,6 +11,7 @@
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
-moz-text-size-adjust: 100%; /* 2 */
}
/* Sections

File diff suppressed because one or more lines are too long

View File

@@ -2,47 +2,33 @@
<script>
$(document).ready(function () {
// 自定义字段
$('#custom-field-expand').click(function() {
var btn = $('i', this);
if (btn.hasClass('i-caret-right')) {
btn.removeClass('i-caret-right').addClass('i-caret-down');
} else {
btn.removeClass('i-caret-down').addClass('i-caret-right');
}
$(this).parent().toggleClass('fold');
return false;
});
function attachDeleteEvent (el) {
$('button.btn-xs', el).click(function () {
if (confirm('<?php _e('确认要删除此字段吗?'); ?>')) {
$(this).parents('tr').fadeOut(function () {
$(this).parents('li').fadeOut(function () {
$(this).remove();
});
$(this).parents('form').trigger('field');
$(this).parents('form').trigger('change');
}
});
}
$('#custom-field table tbody tr').each(function () {
$('#custom-field .fields .field').each(function () {
attachDeleteEvent(this);
});
$('#custom-field button.operate-add').click(function () {
var html = '<tr><td><input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" class="text-s w-100"></td>'
+ '<td><select name="fieldTypes[]" id="">'
var html = '<li class="field"><div class="field-name"><input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" pattern="^[_a-zA-Z][_a-zA-Z0-9]*$" oninput="this.reportValidity()" class="text-s w-100">'
+ '<select name="fieldTypes[]" id="">'
+ '<option value="str"><?php _e('字符'); ?></option>'
+ '<option value="int"><?php _e('整数'); ?></option>'
+ '<option value="float"><?php _e('小数'); ?></option>'
+ '</select></td>'
+ '<td><textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" class="text-s w-100" rows="2"></textarea></td>'
+ '<td><button type="button" class="btn btn-xs"><?php _e('删除'); ?></button></td></tr>',
el = $(html).hide().appendTo('#custom-field table tbody').fadeIn();
$(':input', el).bind('input change', function () {
$(this).parents('form').trigger('field');
});
+ '<option value="json"><?php _e('JSON 结构'); ?></option>'
+ '</select></div>'
+ '<div class="field-value"><textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" class="text-s w-100" rows="2"></textarea>'
+ '<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button></div></li>',
el = $(html).hide().appendTo('#custom-field .fields').fadeIn();
attachDeleteEvent(el);
});

View File

@@ -3,32 +3,23 @@
$fields = isset($post) ? $post->getFieldItems() : $page->getFieldItems();
$defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaultFieldItems();
?>
<section id="custom-field"
class="typecho-post-option<?php if (empty($defaultFields) && empty($fields)): ?> fold<?php endif; ?>">
<label id="custom-field-expand" class="typecho-label"><a href="##"><i
class="i-caret-right"></i> <?php _e('自定义字段'); ?></a></label>
<table class="typecho-list-table mono">
<colgroup>
<col width="25%"/>
<col width="10%"/>
<col width="55%"/>
<col width="10%"/>
</colgroup>
<details id="custom-field"
class="typecho-post-option" <?php if (!empty($defaultFields) || !empty($fields)): ?>open<?php endif; ?>>
<summary><?php _e('自定义字段'); ?></summary>
<ul class="fields mono">
<?php foreach ($defaultFields as $field): ?>
<?php [$label, $input] = $field; ?>
<tr>
<td><?php $label->render(); ?></td>
<td colspan="3"><?php $input->render(); ?></td>
</tr>
<li class="field">
<div class="field-name"><?php $label->render(); ?></div>
<div class="field-value"><?php $input->render(); ?></div>
</li>
<?php endforeach; ?>
<?php foreach ($fields as $field): ?>
<tr>
<td>
<li class="field">
<div class="field-name">
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
<input type="text" name="fieldNames[]" value="<?php echo htmlspecialchars($field['name']); ?>"
id="fieldname" class="text-s w-100">
</td>
<td>
id="fieldname" pattern="^[_a-zA-Z][_a-zA-Z0-9]*$" oninput="this.reportValidity()" class="text-s w-100">
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
<select name="fieldTypes[]" id="fieldtype">
<option
@@ -37,46 +28,45 @@ $defaultFields = isset($post) ? $post->getDefaultFieldItems() : $page->getDefaul
value="int"<?php if ('int' == $field['type']): ?> selected<?php endif; ?>><?php _e('整数'); ?></option>
<option
value="float"<?php if ('float' == $field['type']): ?> selected<?php endif; ?>><?php _e('小数'); ?></option>
<option
value="json"<?php if ('json' == $field['type']): ?> selected<?php endif; ?>><?php _e('JSON 结构'); ?></option>
</select>
</td>
<td>
</div>
<div class="field-value">
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
<textarea name="fieldValues[]" id="fieldvalue" class="text-s w-100"
rows="2"><?php echo htmlspecialchars($field[$field['type'] . '_value']); ?></textarea>
</td>
<td>
rows="2"><?php echo htmlspecialchars($field[($field['type'] == 'json' ? 'str' : $field['type']) . '_value']); ?></textarea>
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
</td>
</tr>
</div>
</li>
<?php endforeach; ?>
<?php if (empty($defaultFields) && empty($fields)): ?>
<tr>
<td>
<li class="field">
<div class="field-name">
<label for="fieldname" class="sr-only"><?php _e('字段名称'); ?></label>
<input type="text" name="fieldNames[]" placeholder="<?php _e('字段名称'); ?>" id="fieldname"
class="text-s w-100">
</td>
<td>
class="text-s w-100" pattern="^[_a-zA-Z][_a-zA-Z0-9]*$" oninput="this.reportValidity()">
<label for="fieldtype" class="sr-only"><?php _e('字段类型'); ?></label>
<select name="fieldTypes[]" id="fieldtype">
<option value="str"><?php _e('字符'); ?></option>
<option value="int"><?php _e('整数'); ?></option>
<option value="float"><?php _e('小数'); ?></option>
<option value="json"><?php _e('JSON 结构'); ?></option>
</select>
</td>
<td>
</div>
<div class="field-value">
<label for="fieldvalue" class="sr-only"><?php _e('字段值'); ?></label>
<textarea name="fieldValues[]" placeholder="<?php _e('字段值'); ?>" id="fieldvalue"
class="text-s w-100" rows="2"></textarea>
</td>
<td>
<button type="button" class="btn btn-xs"><?php _e('删除'); ?></button>
</td>
</tr>
</div>
</li>
<?php endif; ?>
</table>
<div class="description clearfix">
</ul>
<div class="add">
<button type="button" class="btn btn-xs operate-add"><?php _e('+添加字段'); ?></button>
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="http://docs.typecho.org/help/custom-fields">帮助文档</a>'); ?>
<div class="description kit-hidden-mb">
<?php _e('自定义字段可以扩展你的模板功能, 使用方法参见 <a href="https://docs.typecho.org/help/custom-fields">帮助文档</a>'); ?>
</div>
</div>
</section>
</details>

View File

@@ -1,17 +1,44 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php $content = !empty($post) ? $post : $page; if ($options->markdown): ?>
<?php $content = !empty($post) ? $post : $page; ?>
<script>
(function () {
$('#text').on('change', function (e) {
e.preventDefault();
e.stopPropagation();
}).on('input', function () {
$(this).parents('form').trigger('write');
});
})();
</script>
<?php if (!$options->markdown): ?>
<script>
(function () {
const textarea = $('#text');
// 原始的插入图片和文件
Typecho.insertFileToEditor = function (file, url, isImage) {
const sel = textarea.getSelection(),
html = isImage ? '<img src="' + url + '" alt="' + file + '" />'
: '<a href="' + url + '">' + file + '</a>',
offset = (sel ? sel.start : 0) + html.length;
textarea.replaceSelection(html);
textarea.setSelection(offset, offset);
};
})();
</script>
<?php else: ?>
<script src="<?php $options->adminStaticUrl('js', 'hyperdown.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'pagedown.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'paste.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'purify.js'); ?>"></script>
<script>
$(document).ready(function () {
var textarea = $('#text'),
isFullScreen = false,
const textarea = $('#text'),
toolbar = $('<div class="editor" id="wmd-button-bar" />').insertBefore(textarea.parent()),
preview = $('<div id="wmd-preview" class="wmd-hidetab" />').insertAfter('.editor');
let isFullScreen = false;
var options = {}, isMarkdown = <?php echo intval($content->isMarkdown || !$content->have()); ?>;
const options = {}, isMarkdown = <?php echo json_encode(!$content->have() || $content->isMarkdown); ?>;
options.strings = {
bold: '<?php _e('加粗'); ?> <strong> Ctrl+B',
@@ -59,13 +86,13 @@ $(document).ready(function () {
help: '<?php _e('Markdown语法帮助'); ?>'
};
var converter = new HyperDown(),
const converter = new HyperDown(),
editor = new Markdown.Editor(converter, '', options);
// 自动跟随
converter.enableHtml(true);
converter.enableLine(true);
reloadScroll = scrollableEditor(textarea, preview);
const reloadScroll = scrollableEditor(textarea, preview);
// 修正白名单
converter.hook('makeHtml', function (html) {
@@ -82,7 +109,7 @@ $(document).ready(function () {
// 替换block
html = html.replace(/<(iframe|embed)\s+([^>]*)>/ig, function (all, tag, src) {
if (src[src.length - 1] == '/') {
if (src[src.length - 1] === '/') {
src = src.substring(0, src.length - 1);
}
@@ -94,25 +121,26 @@ $(document).ready(function () {
});
editor.hooks.chain('onPreviewRefresh', function () {
var images = $('img', preview), count = images.length;
const images = $('img', preview);
let count = images.length;
if (count == 0) {
if (count === 0) {
reloadScroll(true);
} else {
images.bind('load error', function () {
count --;
if (count == 0) {
if (count === 0) {
reloadScroll(true);
}
});
}
});
<?php \Typecho\Plugin::factory('admin/editor-js.php')->markdownEditor($content); ?>
<?php \Typecho\Plugin::factory('admin/editor-js.php')->call('markdownEditor', $content); ?>
var th = textarea.height(), ph = preview.height(),
uploadBtn = $('<button type="button" id="btn-fullscreen-upload" class="btn btn-link">'
let th = textarea.height(), ph = preview.height();
const uploadBtn = $('<button type="button" id="btn-fullscreen-upload" class="btn btn-link">'
+ '<i class="i-upload"><?php _e('附件'); ?></i></button>')
.prependTo('.submit .right')
.click(function() {
@@ -129,7 +157,7 @@ $(document).ready(function () {
th = textarea.height();
ph = preview.height();
$(document.body).addClass('fullscreen');
var h = $(window).height() - toolbar.outerHeight();
const h = $(window).height() - toolbar.outerHeight();
textarea.css('height', h);
preview.css('height', h);
@@ -139,7 +167,7 @@ $(document).ready(function () {
editor.hooks.chain('enterFullScreen', function () {
$(document.body).addClass('fullscreen');
var h = window.screen.height - toolbar.outerHeight();
const h = window.screen.height - toolbar.outerHeight();
textarea.css('height', h);
preview.css('height', h);
isFullScreen = true;
@@ -156,19 +184,23 @@ $(document).ready(function () {
textarea.trigger('input');
});
editor.hooks.chain('save', function () {
Typecho.savePost();
});
function initMarkdown() {
editor.run();
var imageButton = $('#wmd-image-button'),
const imageButton = $('#wmd-image-button'),
linkButton = $('#wmd-link-button');
Typecho.insertFileToEditor = function (file, url, isImage) {
var button = isImage ? imageButton : linkButton;
const button = isImage ? imageButton : linkButton;
options.strings[isImage ? 'imagename' : 'linkname'] = file;
button.trigger('click');
var checkDialog = setInterval(function () {
let checkDialog = setInterval(function () {
if ($('.wmd-prompt-dialog').length > 0) {
$('.wmd-prompt-dialog input').val(url).select();
clearInterval(checkDialog);
@@ -177,12 +209,12 @@ $(document).ready(function () {
}, 10);
};
Typecho.uploadComplete = function (file) {
Typecho.insertFileToEditor(file.title, file.url, file.isImage);
Typecho.uploadComplete = function (attachment) {
Typecho.insertFileToEditor(attachment.title, attachment.url, attachment.isImage);
};
// 编辑预览切换
var edittab = $('.editor').prepend('<div class="wmd-edittab"><a href="#wmd-editarea" class="active"><?php _e('撰写'); ?></a><a href="#wmd-preview"><?php _e('预览'); ?></a></div>'),
const edittab = $('.editor').append('<div class="wmd-edittab"><a href="#wmd-editarea" class="active"><?php _e('撰写'); ?></a><a href="#wmd-preview"><?php _e('预览'); ?></a></div>'),
editarea = $(textarea.parent()).attr("id", "wmd-editarea");
$(".wmd-edittab a").click(function() {
@@ -190,11 +222,11 @@ $(document).ready(function () {
$(this).addClass("active");
$("#wmd-editarea, #wmd-preview").addClass("wmd-hidetab");
var selected_tab = $(this).attr("href"),
const selected_tab = $(this).attr("href"),
selected_el = $(selected_tab).removeClass("wmd-hidetab");
// 预览时隐藏编辑器按钮
if (selected_tab == "#wmd-preview") {
if (selected_tab === "#wmd-preview") {
$("#wmd-button-row").addClass("wmd-visualhide");
} else {
$("#wmd-button-row").removeClass("wmd-visualhide");
@@ -207,21 +239,30 @@ $(document).ready(function () {
});
// 剪贴板复制图片
textarea.pastableTextarea().on('pasteImage', function (e, data) {
var name = data.name ? data.name.replace(/[\(\)\[\]\*#!]/g, '') : (new Date()).toISOString().replace(/\..+$/, '');
if (!name.match(/\.[a-z0-9]{2,}$/i)) {
var ext = data.blob.type.split('/').pop();
name += '.' + ext;
}
textarea.bind('paste', function (e) {
const items = (e.clipboardData || e.originalEvent.clipboardData).items;
Typecho.uploadFile(new File([data.blob], name), name);
for (const item of items) {
if (item.kind === 'file') {
const file = item.getAsFile();
if (file.size > 0) {
if (!file.name) {
file.name = (new Date()).toISOString().replace(/\..+$/, '')
+ '.' + file.type.split('/').pop();
}
Typecho.uploadFile(file);
}
}
}
});
}
if (isMarkdown) {
initMarkdown();
} else {
var notice = $('<div class="message notice"><?php _e('这篇文章不是由Markdown语法创建的, 继续使用Markdown编辑它吗?'); ?> '
const notice = $('<div class="message notice"><?php _e('这篇文章不是由Markdown语法创建的, 继续使用Markdown编辑它吗?'); ?> '
+ '<button class="btn btn-xs primary yes"><?php _e('是'); ?></button> '
+ '<button class="btn btn-xs no"><?php _e('否'); ?></button></div>')
.hide().insertBefore(textarea).slideDown();

View File

@@ -3,7 +3,7 @@
include 'common.php';
$panel = $request->get('panel');
$panelTable = unserialize($options->panelTable);
$panelTable = $options->panelTable;
if (!isset($panelTable['file']) || !in_array(urlencode($panel), $panelTable['file'])) {
throw new \Typecho\Plugin\Exception(_t('页面不存在'), 404);

View File

@@ -1,23 +1,18 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php
if (isset($post) && $post instanceof \Typecho\Widget && $post->have()) {
$fileParentContent = $post;
} elseif (isset($page) && $page instanceof \Typecho\Widget && $page->have()) {
$fileParentContent = $page;
}
$phpMaxFilesize = function_exists('ini_get') ? trim(ini_get('upload_max_filesize')) : '0';
$phpMaxFilesize = function_exists('ini_get') ? trim(ini_get('upload_max_filesize')) : 0;
if (preg_match("/^([0-9]+)([a-z]{1,2})?$/i", $phpMaxFilesize, $matches)) {
$size = intval($matches[1]);
$unit = $matches[2] ?? 'b';
if (preg_match("/^([0-9]+)([a-z]{1,2})$/i", $phpMaxFilesize, $matches)) {
$phpMaxFilesize = strtolower($matches[1] . $matches[2] . (1 == strlen($matches[2]) ? 'b' : ''));
$phpMaxFilesize = round($size * pow(1024, stripos('bkmgtpezy', $unit[0])));
}
?>
<script src="<?php $options->adminStaticUrl('js', 'moxie.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'plupload.js'); ?>"></script>
<script>
$(document).ready(function() {
function updateAttacmentNumber () {
function updateAttachmentNumber () {
var btn = $('#tab-files-btn'),
balloon = $('.balloon', btn),
count = $('#file-list li .insert').length;
@@ -29,24 +24,40 @@ $(document).ready(function() {
}
balloon.html(count);
} else if (0 == count && balloon.length > 0) {
} else if (0 === count && balloon.length > 0) {
balloon.remove();
}
}
$('.upload-area').bind({
dragenter : function () {
updateAttachmentNumber();
const uploadUrl = $('.upload-area').bind({
dragenter : function (e) {
$(this).parent().addClass('drag');
},
dragover : function (e) {
e.stopPropagation();
e.preventDefault();
$(this).parent().addClass('drag');
},
drop : function () {
drop : function (e) {
e.stopPropagation();
e.preventDefault();
$(this).parent().removeClass('drag');
const files = e.originalEvent.dataTransfer.files;
if (files.length === 0) {
return;
}
for (const file of files) {
Typecho.uploadFile(file);
}
},
dragend : function () {
$(this).parent().removeClass('drag');
},
@@ -54,31 +65,44 @@ $(document).ready(function() {
dragleave : function () {
$(this).parent().removeClass('drag');
}
}).data('url');
const btn = $('.upload-file');
const fileInput = $('<input type="file" name="file" />').hide().insertAfter(btn);
btn.click(function () {
fileInput.click();
return false;
});
updateAttacmentNumber();
fileInput.change(function () {
if (this.files.length === 0) {
return;
}
Typecho.uploadFile(this.files[0]);
});
function fileUploadStart (file) {
$('<li id="' + file.id + '" class="loading">'
+ file.name + '</li>').appendTo('#file-list');
}
function fileUploadError (error) {
var file = error.file, code = error.code, word;
function fileUploadError (type, file) {
let word = '<?php _e('上传出现错误'); ?>';
switch (code) {
case plupload.FILE_SIZE_ERROR:
switch (type) {
case 'size':
word = '<?php _e('文件大小超过限制'); ?>';
break;
case plupload.FILE_EXTENSION_ERROR:
case 'type':
word = '<?php _e('文件扩展名不被支持'); ?>';
break;
case plupload.FILE_DUPLICATE_ERROR:
case 'duplicate':
word = '<?php _e('文件已经上传过'); ?>';
break;
case plupload.HTTP_ERROR:
case 'network':
default:
word = '<?php _e('上传出现错误'); ?>';
break;
}
@@ -94,104 +118,91 @@ $(document).ready(function() {
li.effect('highlight', {color : '#FBC2C4'}, 2000, function () {
$(this).remove();
});
// fix issue #341
this.removeFile(file);
}
var completeFile = null;
function fileUploadComplete (id, url, data) {
var li = $('#' + id).removeClass('loading').data('cid', data.cid)
.data('url', data.url)
.data('image', data.isImage)
.html('<input type="hidden" name="attachment[]" value="' + data.cid + '" />'
+ '<a class="insert" target="_blank" href="###" title="<?php _e('点击插入文件'); ?>">' + data.title + '</a><div class="info">' + data.bytes
function fileUploadComplete (file, attachment) {
const li = $('#' + file.id).removeClass('loading').data('cid', attachment.cid)
.data('url', attachment.url)
.data('image', attachment.isImage)
.html('<input type="hidden" name="attachment[]" value="' + attachment.cid + '" />'
+ '<a class="insert" target="_blank" href="###" title="<?php _e('点击插入文件'); ?>">'
+ attachment.title + '</a><div class="info">' + attachment.bytes
+ ' <a class="file" target="_blank" href="<?php $options->adminUrl('media.php'); ?>?cid='
+ data.cid + '" title="<?php _e('编辑'); ?>"><i class="i-edit"></i></a>'
+ attachment.cid + '" title="<?php _e('编辑'); ?>"><i class="i-edit"></i></a>'
+ ' <a class="delete" href="###" title="<?php _e('删除'); ?>"><i class="i-delete"></i></a></div>')
.effect('highlight', 1000);
attachInsertEvent(li);
attachDeleteEvent(li);
updateAttacmentNumber();
updateAttachmentNumber();
if (!completeFile) {
completeFile = data;
}
Typecho.uploadComplete(attachment);
}
var uploader = null, tabFilesEl = $('#tab-files').bind('init', function () {
uploader = new plupload.Uploader({
browse_button : $('.upload-file').get(0),
url : '<?php $security->index('/action/upload'
. (isset($fileParentContent) ? '?cid=' . $fileParentContent->cid : '')); ?>',
runtimes : 'html5,flash,html4',
flash_swf_url : '<?php $options->adminStaticUrl('js', 'Moxie.swf'); ?>',
drop_element : $('.upload-area').get(0),
filters : {
max_file_size : '<?php echo $phpMaxFilesize ?>',
mime_types : [{'title' : '<?php _e('允许上传的文件'); ?>', 'extensions' : '<?php echo implode(',', $options->allowedAttachmentTypes); ?>'}],
prevent_duplicates : true
},
Typecho.uploadFile = (function () {
const types = '<?php echo json_encode($options->allowedAttachmentTypes); ?>';
const maxSize = <?php echo $phpMaxFilesize ?>;
const queue = [];
let index = 0;
init : {
FilesAdded : function (up, files) {
for (var i = 0; i < files.length; i ++) {
fileUploadStart(files[i]);
}
const getUrl = function () {
const url = new URL(uploadUrl);
const cid = $('input[name=cid]').val();
completeFile = null;
uploader.start();
},
url.searchParams.append('cid', cid);
return url.toString();
};
UploadComplete : function () {
if (completeFile) {
Typecho.uploadComplete(completeFile);
}
},
const upload = function () {
const file = queue.shift();
FileUploaded : function (up, file, result) {
if (200 == result.status) {
var data = $.parseJSON(result.response);
if (data) {
fileUploadComplete(file.id, data[0], data[1]);
uploader.removeFile(file);
return;
}
}
fileUploadError.call(uploader, {
code : plupload.HTTP_ERROR,
file : file
});
},
Error : function (up, error) {
fileUploadError.call(uploader, error);
}
}
});
uploader.init();
});
Typecho.uploadFile = function (file, name) {
if (!uploader) {
$('#tab-files-btn').parent().trigger('click');
}
var timer = setInterval(function () {
if (!uploader) {
if (!file) {
return;
}
clearInterval(timer);
timer = null;
const data = new FormData();
data.append('file', file);
uploader.addFile(file, name);
}, 50);
};
fetch(getUrl(), {
method: 'POST',
body: data
}).then(function (response) {
if (response.ok) {
return response.json();
} else {
throw new Error(response.statusText);
}
}).then(function (data) {
if (data) {
const [_, attachment] = data;
fileUploadComplete(file, attachment);
upload();
} else {
throw new Error('no data');
}
}).catch(function (error) {
fileUploadError('network', file);
upload();
});
};
return function (file) {
file.id = 'upload-' + (index++);
if (file.size > maxSize) {
return fileUploadError('size', file);
}
const match = file.name.match(/\.([a-z0-9]+)$/i);
if (!match || types.indexOf(match[1].toLowerCase()) < 0) {
return fileUploadError('type', file);
}
queue.push(file);
fileUploadStart(file);
upload();
};
})();
function attachInsertEvent (el) {
$('.insert', el).click(function () {
@@ -211,7 +222,7 @@ $(document).ready(function() {
function () {
$(el).fadeOut(function () {
$(this).remove();
updateAttacmentNumber();
updateAttachmentNumber();
});
});
}

View File

@@ -3,9 +3,9 @@
<?php
if (isset($post) || isset($page)) {
$cid = isset($post) ? $post->cid : $page->cid;
if ($cid) {
\Widget\Contents\Related::alloc(['parentId' => $cid])->to($attachment);
\Widget\Contents\Attachment\Related::alloc(['parentId' => $cid])->to($attachment);
} else {
\Widget\Contents\Attachment\Unattached::alloc()->to($attachment);
}
@@ -13,7 +13,9 @@ if (isset($post) || isset($page)) {
?>
<div id="upload-panel" class="p">
<div class="upload-area" draggable="true"><?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?></div>
<div class="upload-area" data-url="<?php $security->index('/action/upload'); ?>">
<?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?>
</div>
<ul id="file-list">
<?php while ($attachment->next()): ?>
<li data-cid="<?php $attachment->cid(); ?>" data-url="<?php echo $attachment->attachment->url; ?>" data-image="<?php echo $attachment->attachment->isImage ? 1 : 0; ?>"><input type="hidden" name="attachment[]" value="<?php $attachment->cid(); ?>" />

View File

@@ -1,6 +1,7 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php \Typecho\Plugin::factory('admin/footer.php')->call('begin'); ?>
</body>
</html>
<?php
/** 注册一个结束插件 */
\Typecho\Plugin::factory('admin/footer.php')->end();
\Typecho\Plugin::factory('admin/footer.php')->call('end');

View File

@@ -2,25 +2,50 @@
<script>
(function () {
$(document).ready(function () {
var error = $('.typecho-option .error:first');
const error = $('.typecho-option .error:first');
if (error.length > 0) {
$('html,body').scrollTop(error.parents('.typecho-option').offset().top);
}
$('form').submit(function () {
if (this.submitted) {
$('.main form').submit(function () {
const self = $(this);
if (self.hasClass('submitting')) {
return false;
} else {
this.submitted = true;
$('button[type=submit]', this).attr('disabled', 'disabled');
self.addClass('submitting');
}
}).on('submitted', function () {
$('button[type=submit]', this).removeAttr('disabled');
$(this).removeClass('submitting');
});
$('label input[type=text]').click(function (e) {
var check = $('#' + $(this).parents('label').attr('for'));
const check = $('#' + $(this).parents('label').attr('for'));
check.prop('checked', true);
return false;
});
$('.main form input[type="url"]').each(function () {
const self = $(this);
const input = $('<input type="hidden" />').attr('name', self.attr('name'));
function setInput() {
const url = self.val();
try {
const urlObj = new URL(url);
input.val(urlObj.toString());
} catch {
// ignore
}
}
self.removeAttr('name').after(input).on('input', setInput);
setInput();
});
});
})();
</script>

View File

@@ -8,7 +8,7 @@ $header = '<link rel="stylesheet" href="' . $options->adminStaticUrl('css', 'nor
<link rel="stylesheet" href="' . $options->adminStaticUrl('css', 'style.css', true) . '">';
/** 注册一个初始化插件 */
$header = \Typecho\Plugin::factory('admin/header.php')->header($header);
$header = \Typecho\Plugin::factory('admin/header.php')->filter('header', $header);
?><!DOCTYPE HTML>
<html>

View File

@@ -5,7 +5,7 @@ include 'menu.php';
$stat = \Widget\Stat::alloc();
?>
<div class="main">
<main class="main">
<div class="container typecho-dashboard">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main">
@@ -14,7 +14,7 @@ $stat = \Widget\Stat::alloc();
$stat->myPublishedPostsNum, $stat->myPublishedCommentsNum, $stat->categoriesNum); ?>
<br><?php _e('点击下面的链接快速开始:'); ?></p>
<ul id="start-link" class="clearfix">
<ul id="start-link">
<?php if ($user->pass('contributor', true)): ?>
<li><a href="<?php $options->adminUrl('write-post.php'); ?>"><?php _e('撰写新文章'); ?></a></li>
<?php if ($user->pass('editor', true) && 'on' == $request->get('__typecho_all_comments') && $stat->waitingCommentsNum > 0): ?>
@@ -102,7 +102,7 @@ $stat = \Widget\Stat::alloc();
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
admin/js/jquery.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -4,7 +4,7 @@ include 'common.php';
if ($user->hasLogin()) {
$response->redirect($options->adminUrl);
}
$rememberName = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_name'));
$rememberName = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_name', ''));
\Typecho\Cookie::delete('__typecho_remember_name');
$bodyClass = 'body-100';
@@ -13,22 +13,24 @@ include 'header.php';
?>
<div class="typecho-login-wrap">
<div class="typecho-login">
<h1><a href="http://typecho.org" class="i-logo">Typecho</a></h1>
<h1><a href="https://typecho.org" class="i-logo">Typecho</a></h1>
<form action="<?php $options->loginAction(); ?>" method="post" name="login" role="form">
<p>
<label for="name" class="sr-only"><?php _e('用户名'); ?></label>
<input type="text" id="name" name="name" value="<?php echo $rememberName; ?>" placeholder="<?php _e('用户名'); ?>" class="text-l w-100" autofocus />
<label for="name" class="sr-only"><?php _e('用户名或邮箱'); ?></label>
<input type="text" id="name" name="name" value="<?php echo $rememberName; ?>" placeholder="<?php _e('用户名或邮箱'); ?>" class="text-l w-100" autofocus />
</p>
<p>
<label for="password" class="sr-only"><?php _e('密码'); ?></label>
<input type="password" id="password" name="password" class="text-l w-100" placeholder="<?php _e('密码'); ?>" />
<input type="password" id="password" name="password" class="text-l w-100" placeholder="<?php _e('密码'); ?>" required />
</p>
<p class="submit">
<button type="submit" class="btn btn-l w-100 primary"><?php _e('登录'); ?></button>
<input type="hidden" name="referer" value="<?php echo htmlspecialchars($request->get('referer')); ?>" />
<input type="hidden" name="referer" value="<?php echo $request->filter('html')->get('referer'); ?>" />
</p>
<p>
<label for="remember"><input type="checkbox" name="remember" class="checkbox" value="1" id="remember" /> <?php _e('下次自动登录'); ?></label>
<label for="remember">
<input<?php if(\Typecho\Cookie::get('__typecho_remember_remember')): ?> checked<?php endif; ?> type="checkbox" name="remember" class="checkbox" value="1" id="remember" /> <?php _e('下次自动登录'); ?>
</label>
</p>
</form>

View File

@@ -6,7 +6,7 @@ include 'menu.php';
\Widget\Metas\Category\Admin::alloc()->to($categories);
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main manage-metas">
@@ -14,7 +14,7 @@ include 'menu.php';
<div class="col-mb-12" role="main">
<form method="post" name="manage_categories" class="operate-form">
<div class="typecho-list-operate clearfix">
<div class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
@@ -44,77 +44,74 @@ include 'menu.php';
</div>
</div>
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="20" class="kit-hidden-mb"/>
<col width=""/>
<col width="15%" class="kit-hidden-mb"/>
<col width="25%"/>
<col width="15%"/>
<col width="10%" class="kit-hidden-mb"/>
</colgroup>
<thead>
<tr class="nodrag">
<th class="kit-hidden-mb"></th>
<th><?php _e('名称'); ?></th>
<th><?php _e('子分类'); ?></th>
<th class="kit-hidden-mb"><?php _e('缩略名'); ?></th>
<th></th>
<th class="kit-hidden-mb"><?php _e('文章数'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($categories->have()): ?>
<?php while ($categories->next()): ?>
<tr id="mid-<?php $categories->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox"
value="<?php $categories->mid(); ?>"
name="mid[]"/></td>
<td>
<a href="<?php $options->adminUrl('category.php?mid=' . $categories->mid); ?>"><?php $categories->name(); ?></a>
<a href="<?php $categories->permalink(); ?>"
title="<?php _e('浏览 %s', $categories->name); ?>"><i class="i-exlink"></i></a>
</td>
<td>
<table class="typecho-list-table">
<colgroup>
<col width="3%" class="kit-hidden-mb"/>
<col width=""/>
<col width="15%" class="kit-hidden-mb"/>
<col width="20%"/>
<col width="15%"/>
<col width="15%" class="kit-hidden-mb"/>
</colgroup>
<thead>
<tr class="nodrag">
<th class="kit-hidden-mb"></th>
<th><?php _e('名称'); ?></th>
<th><?php _e('子分类'); ?></th>
<th class="kit-hidden-mb"><?php _e('缩略名'); ?></th>
<th></th>
<th class="kit-hidden-mb"><?php _e('文章数'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($categories->have()): ?>
<?php while ($categories->next()): ?>
<tr id="mid-<?php $categories->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox"
value="<?php $categories->mid(); ?>"
name="mid[]"/></td>
<td>
<a href="<?php $options->adminUrl('category.php?mid=' . $categories->mid); ?>"><?php $categories->name(); ?></a>
<a href="<?php $categories->permalink(); ?>"
title="<?php _e('浏览 %s', $categories->name); ?>"><i class="i-exlink"></i></a>
</td>
<td>
<?php if (count($categories->children) > 0): ?>
<a href="<?php $options->adminUrl('manage-categories.php?parent=' . $categories->mid); ?>"><?php echo _n('一个分类', '%d个分类', count($categories->children)); ?></a>
<?php else: ?>
<a href="<?php $options->adminUrl('category.php?parent=' . $categories->mid); ?>"><?php echo _e('新增'); ?></a>
<?php endif; ?>
</td>
<td class="kit-hidden-mb"><?php $categories->slug(); ?></td>
<td>
<?php if ($options->defaultCategory == $categories->mid): ?>
<?php _e('默认'); ?>
<?php else: ?>
<a class="hidden-by-mouse"
href="<?php $security->index('/action/metas-category-edit?do=default&mid=' . $categories->mid); ?>"
title="<?php _e('设为默认'); ?>"><?php _e('默认'); ?></a>
<?php endif; ?>
</td>
<td class="kit-hidden-mb"><a
class="balloon-button left size-<?php echo \Typecho\Common::splitByCount($categories->count, 1, 10, 20, 50, 100); ?>"
href="<?php $options->adminUrl('manage-posts.php?category=' . $categories->mid); ?>"><?php $categories->count(); ?></a>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何分类'); ?></h6>
<?php if (count($categories->children) > 0): ?>
<a href="<?php $options->adminUrl('manage-categories.php?parent=' . $categories->mid); ?>"><?php echo _n('一个分类', '%d个分类', count($categories->children)); ?></a>
<?php else: ?>
<a href="<?php $options->adminUrl('category.php?parent=' . $categories->mid); ?>"><?php echo _e('新增'); ?></a>
<?php endif; ?>
</td>
<td class="kit-hidden-mb"><?php $categories->slug(); ?></td>
<td>
<?php if ($options->defaultCategory == $categories->mid): ?>
<?php _e('默认'); ?>
<?php else: ?>
<a class="hidden-by-mouse"
href="<?php $security->index('/action/metas-category-edit?do=default&mid=' . $categories->mid); ?>"
title="<?php _e('设为默认'); ?>"><?php _e('默认'); ?></a>
<?php endif; ?>
</td>
<td class="kit-hidden-mb"><a
class="balloon-button left size-<?php echo \Typecho\Common::splitByCount($categories->count, 1, 10, 20, 50, 100); ?>"
href="<?php $options->adminUrl('manage-posts.php?category=' . $categories->mid); ?>"><?php $categories->count(); ?></a>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6" class="none"><?php _e('没有任何分类'); ?></td>
</tr>
<?php endif; ?>
</tbody>
</table>
</form>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -7,23 +7,17 @@ $stat = \Widget\Stat::alloc();
$comments = \Widget\Comments\Admin::alloc();
$isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Typecho\Cookie::get('__typecho_all_comments'));
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<div class="clearfix">
<ul class="typecho-option-tabs right">
<?php if($user->pass('editor', true) && !isset($request->cid)): ?>
<li class="<?php if($isAllComments): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_comments=on'); ?>"><?php _e('所有'); ?></a></li>
<li class="<?php if(!$isAllComments): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_comments=off'); ?>"><?php _e('我的'); ?></a></li>
<?php endif; ?>
</ul>
<div class="typecho-list-operate">
<ul class="typecho-option-tabs">
<li<?php if(!isset($request->status) || 'approved' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php'
. (isset($request->cid) ? '?cid=' . $request->cid : '')); ?>"><?php _e('已通过'); ?></a></li>
. (isset($request->cid) ? '?cid=' . $request->filter('encode')->cid : '')); ?>"><?php _e('已通过'); ?></a></li>
<li<?php if('waiting' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php?status=waiting'
. (isset($request->cid) ? '&cid=' . $request->cid : '')); ?>"><?php _e('待审核'); ?>
. (isset($request->cid) ? '&cid=' . $request->filter('encode')->cid : '')); ?>"><?php _e('待审核'); ?>
<?php if(!$isAllComments && $stat->myWaitingCommentsNum > 0 && !isset($request->cid)): ?>
<span class="balloon"><?php $stat->myWaitingCommentsNum(); ?></span>
<?php elseif($isAllComments && $stat->waitingCommentsNum > 0 && !isset($request->cid)): ?>
@@ -33,7 +27,7 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
<?php endif; ?>
</a></li>
<li<?php if('spam' == $request->get('status')): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('manage-comments.php?status=spam'
. (isset($request->cid) ? '&cid=' . $request->cid : '')); ?>"><?php _e('垃圾'); ?>
. (isset($request->cid) ? '&cid=' . $request->filter('encode')->cid : '')); ?>"><?php _e('垃圾'); ?>
<?php if(!$isAllComments && $stat->mySpamCommentsNum > 0 && !isset($request->cid)): ?>
<span class="balloon"><?php $stat->mySpamCommentsNum(); ?></span>
<?php elseif($isAllComments && $stat->spamCommentsNum > 0 && !isset($request->cid)): ?>
@@ -43,50 +37,54 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
<?php endif; ?>
</a></li>
</ul>
<?php if($user->pass('editor', true) && !isset($request->cid)): ?>
<ul class="typecho-option-tabs">
<li class="<?php if($isAllComments): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_comments=on'); ?>"><?php _e('所有'); ?></a></li>
<li class="<?php if(!$isAllComments): ?> current<?php endif; ?>"><a href="<?php echo $request->makeUriByRequest('__typecho_all_comments=off'); ?>"><?php _e('我的'); ?></a></li>
</ul>
<?php endif; ?>
</div>
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $security->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $security->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
<?php if('spam' == $request->get('status')): ?>
<button lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></button>
<?php endif; ?>
</div>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $security->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $security->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
<?php if('spam' == $request->get('status')): ?>
<button lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></button>
<?php endif; ?>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords || '' != $request->category): ?>
<a href="<?php $options->adminUrl('manage-comments.php'
. (isset($request->status) || isset($request->cid) ? '?' .
(isset($request->status) ? 'status=' . htmlspecialchars($request->get('status')) : '') .
(isset($request->cid) ? (isset($request->status) ? '&' : '') . 'cid=' . htmlspecialchars($request->get('cid')) : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo htmlspecialchars($request->keywords); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<?php if(isset($request->status)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('status')); ?>" name="status" />
<?php endif; ?>
<?php if(isset($request->cid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('cid')); ?>" name="cid" />
<?php endif; ?>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords || '' != $request->category): ?>
<a href="<?php $options->adminUrl('manage-comments.php'
. (isset($request->status) || isset($request->cid) ? '?' .
(isset($request->status) ? 'status=' . $request->filter('encode')->status : '') .
(isset($request->cid) ? (isset($request->status) ? '&' : '') . 'cid=' . $request->filter('encode')->cid : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>" value="<?php echo $request->filter('html')->keywords; ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<?php if(isset($request->status)): ?>
<input type="hidden" value="<?php echo $request->filter('html')->status; ?>" name="status" />
<?php endif; ?>
<?php if(isset($request->cid)): ?>
<input type="hidden" value="<?php echo $request->filter('html')->cid; ?>" name="cid" />
<?php endif; ?>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
<form method="post" name="manage_comments" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="3%" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb" />
<col width="6%" class="kit-hidden" />
<col width="20%"/>
<col width="71%"/>
</colgroup>
@@ -117,10 +115,10 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
<td valign="top" class="kit-hidden-mb">
<input type="checkbox" value="<?php $comments->coid(); ?>" name="coid[]"/>
</td>
<td valign="top" class="kit-hidden-mb">
<td valign="top" class="kit-hidden">
<div class="comment-avatar">
<?php if ('comment' == $comments->type): ?>
<?php $comments->gravatar(40); ?>
<?php $comments->gravatar(40, null, true); ?>
<?php endif; ?>
<?php if ('comment' != $comments->type): ?>
<?php _e('引用'); ?>
@@ -131,7 +129,7 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
<div class="comment-meta">
<strong class="comment-author"><?php $comments->author(true); ?></strong>
<?php if($comments->mail): ?>
<br /><span><a href="mailto:<?php $comments->mail(); ?>"><?php $comments->mail(); ?></a></span>
<br /><span><a href="<?php $comments->mail(true); ?>"><?php $comments->mail(); ?></a></span>
<?php endif; ?>
<?php if($comments->ip): ?>
<br /><span><?php $comments->ip(); ?></span>
@@ -175,46 +173,43 @@ $isAllComments = ('on' == $request->get('__typecho_all_comments') || 'on' == \Ty
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="4"><h6 class="typecho-list-table-title"><?php _e('没有评论') ?></h6></td>
<td colspan="4" class="none"><?php _e('没有评论') ?></td>
</tr>
<?php endif; ?>
</tbody>
</table><!-- end .typecho-list-table -->
</div><!-- end .typecho-table-wrap -->
<?php if(isset($request->cid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('cid')); ?>" name="cid" />
<input type="hidden" value="<?php echo $request->filter('html')->cid; ?>" name="cid" />
<?php endif; ?>
</form><!-- end .operate-form -->
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $security->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $security->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
<?php if('spam' == $request->get('status')): ?>
<button lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></button>
<?php endif; ?>
</div>
</div>
<?php if($comments->have()): ?>
<ul class="typecho-pager">
<?php $comments->pageNav(); ?>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox" class="typecho-table-select-all" /></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a href="<?php $security->index('/action/comments-edit?do=approved'); ?>"><?php _e('通过'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=waiting'); ?>"><?php _e('待审核'); ?></a></li>
<li><a href="<?php $security->index('/action/comments-edit?do=spam'); ?>"><?php _e('标记垃圾'); ?></a></li>
<li><a lang="<?php _e('你确认要删除这些评论吗?'); ?>" href="<?php $security->index('/action/comments-edit?do=delete'); ?>"><?php _e('删除'); ?></a></li>
</ul>
<?php if('spam' == $request->get('status')): ?>
<button lang="<?php _e('你确认要删除所有垃圾评论吗?'); ?>" class="btn btn-s btn-warn btn-operate" href="<?php $security->index('/action/comments-edit?do=delete-spam'); ?>"><?php _e('删除所有垃圾评论'); ?></button>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
</div>
</div>
<?php if($comments->have()): ?>
<ul class="typecho-pager">
<?php $comments->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
</main>
<?php
include 'copyright.php';
include 'common-js.php';
@@ -279,10 +274,12 @@ $(document).ready(function () {
form.submit(function () {
var t = $(this), tr = t.parents('tr'),
reply = $('<div class="comment-reply-content"></div>').insertAfter($('.comment-content', tr));
reply.html('<p>' + textarea.val() + '</p>');
var html = DOMPurify.sanitize(textarea.val(), {USE_PROFILES: {html: true}});
reply.html('<p>' + html + '</p>');
$.post(t.attr('action'), t.serialize(), function (o) {
reply.html(o.comment.content)
var html = DOMPurify.sanitize(o.comment.content, {USE_PROFILES: {html: true}});
reply.html(html)
.effect('highlight');
}, 'json');
@@ -340,7 +337,7 @@ $(document).ready(function () {
}
});
var html = '<strong class="comment-author">'
var unsafeHTML = '<strong class="comment-author">'
+ (comment.url ? '<a target="_blank" href="' + comment.url + '">'
+ comment.author + '</a>' : comment.author) + '</strong>'
+ ('comment' != comment.type ? '<small><?php _e('引用'); ?></small>' : '')
@@ -348,13 +345,16 @@ $(document).ready(function () {
+ comment.mail + '</a></span>' : '')
+ (comment.ip ? '<br /><span>' + comment.ip + '</span>' : '');
var html = DOMPurify.sanitize(unsafeHTML, {USE_PROFILES: {html: true}});
var content = DOMPurify.sanitize(comment.text, {USE_PROFILES: {html: true}});
$('.comment-meta', oldTr).html(html)
.effect('highlight');
$('.comment-content', oldTr).html('<p>' + comment.text + '</p>');
$('.comment-content', oldTr).html('<p>' + content + '</p>');
oldTr.data('comment', comment);
$.post(t.attr('action'), comment, function (o) {
$('.comment-content', oldTr).html(o.comment.content)
var content = DOMPurify.sanitize(o.comment.content, {USE_PROFILES: {html: true}});
$('.comment-content', oldTr).html('<p>' + content + '</p>')
.effect('highlight');
}, 'json');

View File

@@ -6,135 +6,128 @@ include 'menu.php';
$stat = \Widget\Stat::alloc();
$attachments = \Widget\Contents\Attachment\Admin::alloc();
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>"
href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
<button class="btn btn-s btn-warn btn-operate"
href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>"
lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
</div>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords): ?>
<a href="<?php $options->adminUrl('manage-medias.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords); ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
<form method="post" name="manage_medias" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table draggable">
<colgroup>
<col width="20" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="30%"/>
<col width="" class="kit-hidden-mb"/>
<col width="30%" class="kit-hidden-mb"/>
<col width="16%"/>
</colgroup>
<thead>
<tr>
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('文件名'); ?></th>
<th class="kit-hidden-mb"><?php _e('上传者'); ?></th>
<th class="kit-hidden-mb"><?php _e('所属文章'); ?></th>
<th><?php _e('发布日期'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($attachments->have()): ?>
<?php while ($attachments->next()): ?>
<?php $mime = \Typecho\Common::mimeIconType($attachments->attachment->mime); ?>
<tr id="<?php $attachments->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox"
value="<?php $attachments->cid(); ?>"
name="cid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-comments.php?cid=' . $attachments->cid); ?>"
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($attachments->commentsNum, 1, 10, 20, 50, 100); ?>"><?php $attachments->commentsNum(); ?></a>
</td>
<td>
<i class="mime-<?php echo $mime; ?>"></i>
<a href="<?php $options->adminUrl('media.php?cid=' . $attachments->cid); ?>"><?php $attachments->title(); ?></a>
<a href="<?php $attachments->permalink(); ?>"
title="<?php _e('浏览 %s', $attachments->title); ?>"><i
class="i-exlink"></i></a>
</td>
<td class="kit-hidden-mb"><?php $attachments->author(); ?></td>
<td class="kit-hidden-mb">
<?php if ($attachments->parentPost->cid): ?>
<a href="<?php $options->adminUrl('write-' . (0 === strpos($attachments->parentPost->type, 'post') ? 'post' : 'page') . '.php?cid=' . $attachments->parentPost->cid); ?>"><?php $attachments->parentPost->title(); ?></a>
<?php else: ?>
<span class="description"><?php _e('未归档'); ?></span>
<?php endif; ?>
</td>
<td><?php $attachments->dateWord(); ?></td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何文件'); ?></h6>
</td>
</tr>
<?php endif; ?>
</tbody>
</table><!-- end .typecho-list-table -->
</div><!-- end .typecho-table-wrap -->
</form><!-- end .operate-form -->
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>"
href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
</div>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>"
href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
<button class="btn btn-s btn-warn btn-operate"
href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>"
lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
</div>
<?php if ($attachments->have()): ?>
<ul class="typecho-pager">
<?php $attachments->pageNav(); ?>
</ul>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords): ?>
<a href="<?php $options->adminUrl('manage-medias.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo $request->filter('html')->keywords; ?>"<?php if ('' == $request->keywords): ?> onclick="value='';name='keywords';" <?php else: ?> name="keywords"<?php endif; ?>/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
<form method="post" name="manage_medias" class="operate-form">
<table class="typecho-list-table draggable">
<colgroup>
<col width="3%" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="30%"/>
<col width="" class="kit-hidden-mb"/>
<col width="30%" class="kit-hidden-mb"/>
<col width="16%"/>
</colgroup>
<thead>
<tr>
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('文件名'); ?></th>
<th class="kit-hidden-mb"><?php _e('上传者'); ?></th>
<th class="kit-hidden-mb"><?php _e('所属文章'); ?></th>
<th><?php _e('发布日期'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($attachments->have()): ?>
<?php while ($attachments->next()): ?>
<?php $mime = \Typecho\Common::mimeIconType($attachments->attachment->mime); ?>
<tr id="<?php $attachments->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox"
value="<?php $attachments->cid(); ?>"
name="cid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-comments.php?cid=' . $attachments->cid); ?>"
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($attachments->commentsNum, 1, 10, 20, 50, 100); ?>"><?php $attachments->commentsNum(); ?></a>
</td>
<td>
<i class="mime-<?php echo $mime; ?>"></i>
<a href="<?php $options->adminUrl('media.php?cid=' . $attachments->cid); ?>"><?php $attachments->title(); ?></a>
<a href="<?php $attachments->permalink(); ?>"
title="<?php _e('浏览 %s', $attachments->title); ?>"><i
class="i-exlink"></i></a>
</td>
<td class="kit-hidden-mb"><?php $attachments->author(); ?></td>
<td class="kit-hidden-mb">
<?php if ($attachments->parentPost->cid): ?>
<a href="<?php $options->adminUrl('write-' . (0 === strpos($attachments->parentPost->type, 'post') ? 'post' : 'page') . '.php?cid=' . $attachments->parentPost->cid); ?>"><?php $attachments->parentPost->title(); ?></a>
<?php else: ?>
<span class="description"><?php _e('未归档'); ?></span>
<?php endif; ?>
</td>
<td><?php $attachments->dateWord(); ?></td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6" class="none"><?php _e('没有任何文件'); ?></td>
</tr>
<?php endif; ?>
</tbody>
</table><!-- end .typecho-list-table -->
</form><!-- end .operate-form -->
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文件吗?'); ?>"
href="<?php $security->index('/action/contents-attachment-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
</div>
<button class="btn btn-s btn-warn btn-operate"
href="<?php $security->index('/action/contents-attachment-edit?do=clear'); ?>"
lang="<?php _e('您确认要清理未归档的文件吗?'); ?>"><?php _e('清理未归档文件'); ?></button>
</div>
<?php if ($attachments->have()): ?>
<ul class="typecho-pager">
<?php $attachments->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div>
</div><!-- end .typecho-page-main -->
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -6,125 +6,129 @@ include 'menu.php';
$stat = \Widget\Stat::alloc();
$pages = \Widget\Contents\Page\Admin::alloc();
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些页面吗?'); ?>"
href="<?php $security->index('/action/contents-page-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-page-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-page-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
</li>
</ul>
</div>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些页面吗?'); ?>"
href="<?php $security->index('/action/contents-page-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-page-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-page-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
</li>
</ul>
</div>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords): ?>
<a href="<?php $options->adminUrl('manage-pages.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords"/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
<div class="search" role="search">
<?php $pages->backLink(); ?>
<?php if ('' != $request->keywords): ?>
<a href="<?php $options->adminUrl('manage-pages.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo $request->filter('html')->keywords; ?>" name="keywords"/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
<form method="post" name="manage_pages" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="20" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="30%"/>
<col width="30%"/>
<col width="" class="kit-hidden-mb"/>
<col width="16%"/>
</colgroup>
<thead>
<tr class="nodrag">
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('标题'); ?></th>
<th><?php _e('缩略名'); ?></th>
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
<th><?php _e('日期'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($pages->have()): ?>
<?php while ($pages->next()): ?>
<tr id="<?php $pages->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $pages->cid(); ?>"
name="cid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-comments.php?cid=' . $pages->cid); ?>"
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($pages->commentsNum, 1, 10, 20, 50, 100); ?>"
title="<?php $pages->commentsNum(); ?> <?php _e('评论'); ?>"><?php $pages->commentsNum(); ?></a>
</td>
<td>
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"><?php $pages->title(); ?></a>
<?php
if ($pages->hasSaved || 'page_draft' == $pages->type) {
echo '<em class="status">' . _t('草稿') . '</em>';
}
<table class="typecho-list-table">
<colgroup>
<col width="3%" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="42%"/>
<col width="18%"/>
<col width="" class="kit-hidden-mb"/>
<col width="16%"/>
</colgroup>
<thead>
<tr class="nodrag">
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('标题'); ?></th>
<th><?php _e('子页面'); ?></th>
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
<th><?php _e('日期'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($pages->have()): ?>
<?php while ($pages->next()): ?>
<tr id="<?php $pages->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $pages->cid(); ?>"
name="cid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-comments.php?cid=' . $pages->cid); ?>"
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($pages->commentsNum, 1, 10, 20, 50, 100); ?>"
title="<?php $pages->commentsNum(); ?> <?php _e('评论'); ?>"><?php $pages->commentsNum(); ?></a>
</td>
<td>
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"><?php $pages->title(); ?></a>
<?php
if ('page_draft' == $pages->type) {
echo '<em class="status">' . _t('草稿') . '</em>';
} elseif ($pages->revision) {
echo '<em class="status">' . _t('有修订版') . '</em>';
}
if ('hidden' == $pages->status) {
echo '<em class="status">' . _t('隐藏') . '</em>';
}
?>
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"
title="<?php _e('编辑 %s', htmlspecialchars($pages->title)); ?>"><i
class="i-edit"></i></a>
<?php if ('page_draft' != $pages->type): ?>
<a href="<?php $pages->permalink(); ?>"
title="<?php _e('浏览 %s', htmlspecialchars($pages->title)); ?>"><i
class="i-exlink"></i></a>
<?php endif; ?>
</td>
<td><?php $pages->slug(); ?></td>
<td class="kit-hidden-mb"><?php $pages->author(); ?></td>
<td>
<?php if ($pages->hasSaved): ?>
<span class="description">
<?php $modifyDate = new \Typecho\Date($pages->modified); ?>
<?php _e('保存于 %s', $modifyDate->word()); ?>
</span>
<?php else: ?>
<?php $pages->dateWord(); ?>
<?php endif; ?>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何页面'); ?></h6>
if ('hidden' == $pages->status) {
echo '<em class="status">' . _t('隐藏') . '</em>';
}
?>
<a href="<?php $options->adminUrl('write-page.php?cid=' . $pages->cid); ?>"
title="<?php _e('编辑 %s', htmlspecialchars($pages->title)); ?>"><i
class="i-edit"></i></a>
<?php if ('page_draft' != $pages->type): ?>
<a href="<?php $pages->permalink(); ?>"
title="<?php _e('浏览 %s', htmlspecialchars($pages->title)); ?>"><i
class="i-exlink"></i></a>
<?php endif; ?>
</td>
<td>
<?php if (count($pages->children) > 0): ?>
<a href="<?php $options->adminUrl('manage-pages.php?parent=' . $pages->cid); ?>"><?php echo _n('一个页面', '%d个页面', count($pages->children)); ?></a>
<?php else: ?>
<a href="<?php $options->adminUrl('write-page.php?parent=' . $pages->cid); ?>"><?php echo _e('新增'); ?></a>
<?php endif; ?>
</td>
<td class="kit-hidden-mb"><?php $pages->author(); ?></td>
<td>
<?php if ('page_draft' == $pages->type || $pages->revision): ?>
<span class="description">
<?php $modifyDate = new \Typecho\Date($pages->revision ? $pages->revision['modified'] : $pages->modified); ?>
<?php _e('保存于 %s', $modifyDate->word()); ?>
</span>
<?php else: ?>
<?php $pages->dateWord(); ?>
<?php endif; ?>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div><!-- end .typecho-table-wrap -->
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6" class="none"><?php _e('没有任何页面'); ?></td>
</tr>
<?php endif; ?>
</tbody>
</table>
</form><!-- end .operate-form -->
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
</main>
<?php
include 'copyright.php';
@@ -132,7 +136,7 @@ include 'common-js.php';
include 'table-js.php';
?>
<?php if (!isset($request->status) || 'publish' == $request->get('status')): ?>
<?php if (!$request->is('keywords')): ?>
<script type="text/javascript">
(function () {
$(document).ready(function () {

View File

@@ -7,30 +7,20 @@ $stat = \Widget\Stat::alloc();
$posts = \Widget\Contents\Post\Admin::alloc();
$isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == \Typecho\Cookie::get('__typecho_all_posts'));
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<div class="clearfix">
<ul class="typecho-option-tabs right">
<?php if ($user->pass('editor', true) && !isset($request->uid)): ?>
<li class="<?php if ($isAllPosts): ?> current<?php endif; ?>"><a
href="<?php echo $request->makeUriByRequest('__typecho_all_posts=on'); ?>"><?php _e('所有'); ?></a>
</li>
<li class="<?php if (!$isAllPosts): ?> current<?php endif; ?>"><a
href="<?php echo $request->makeUriByRequest('__typecho_all_posts=off'); ?>"><?php _e('我的'); ?></a>
</li>
<?php endif; ?>
</ul>
<div class="typecho-list-operate">
<ul class="typecho-option-tabs">
<li<?php if (!isset($request->status) || 'all' == $request->get('status')): ?> class="current"<?php endif; ?>>
<a href="<?php $options->adminUrl('manage-posts.php'
. (isset($request->uid) ? '?uid=' . $request->uid : '')); ?>"><?php _e('可用'); ?></a>
. (isset($request->uid) ? '?uid=' . $request->filter('encode')->uid : '')); ?>"><?php _e('可用'); ?></a>
</li>
<li<?php if ('waiting' == $request->get('status')): ?> class="current"<?php endif; ?>><a
href="<?php $options->adminUrl('manage-posts.php?status=waiting'
. (isset($request->uid) ? '&uid=' . $request->uid : '')); ?>"><?php _e('待审核'); ?>
. (isset($request->uid) ? '&uid=' . $request->filter('encode')->uid : '')); ?>"><?php _e('待审核'); ?>
<?php if (!$isAllPosts && $stat->myWaitingPostsNum > 0 && !isset($request->uid)): ?>
<span class="balloon"><?php $stat->myWaitingPostsNum(); ?></span>
<?php elseif ($isAllPosts && $stat->waitingPostsNum > 0 && !isset($request->uid)): ?>
@@ -41,7 +31,7 @@ $isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == \Typecho\
</a></li>
<li<?php if ('draft' == $request->get('status')): ?> class="current"<?php endif; ?>><a
href="<?php $options->adminUrl('manage-posts.php?status=draft'
. (isset($request->uid) ? '&uid=' . $request->uid : '')); ?>"><?php _e('草稿'); ?>
. (isset($request->uid) ? '&uid=' . $request->filter('encode')->uid : '')); ?>"><?php _e('草稿'); ?>
<?php if (!$isAllPosts && $stat->myDraftPostsNum > 0 && !isset($request->uid)): ?>
<span class="balloon"><?php $stat->myDraftPostsNum(); ?></span>
<?php elseif ($isAllPosts && $stat->draftPostsNum > 0 && !isset($request->uid)): ?>
@@ -51,204 +41,208 @@ $isAllPosts = ('on' == $request->get('__typecho_all_posts') || 'on' == \Typecho\
<?php endif; ?>
</a></li>
</ul>
<?php if ($user->pass('editor', true) && !isset($request->uid)): ?>
<ul class="typecho-option-tabs">
<li class="<?php if ($isAllPosts): ?> current<?php endif; ?>"><a
href="<?php echo $request->makeUriByRequest('__typecho_all_posts=on&page=1'); ?>"><?php _e('所有'); ?></a>
</li>
<li class="<?php if (!$isAllPosts): ?> current<?php endif; ?>"><a
href="<?php echo $request->makeUriByRequest('__typecho_all_posts=off&page=1'); ?>"><?php _e('我的'); ?></a>
</li>
</ul>
<?php endif; ?>
</div>
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>"
href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>"
href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
<?php if ($user->pass('editor', true)): ?>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
</li>
<?php if ($user->pass('editor', true)): ?>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=waiting'); ?>"><?php _e('标记为<strong>%s</strong>', _t('待审核')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=private'); ?>"><?php _e('标记为<strong>%s</strong>', _t('私密')); ?></a>
</li>
<?php endif; ?>
</ul>
</div>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=waiting'); ?>"><?php _e('标记为<strong>%s</strong>', _t('待审核')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=private'); ?>"><?php _e('标记为<strong>%s</strong>', _t('私密')); ?></a>
</li>
<?php endif; ?>
</ul>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords || '' != $request->category): ?>
<a href="<?php $options->adminUrl('manage-posts.php'
. (isset($request->status) || isset($request->uid) ? '?' .
(isset($request->status) ? 'status=' . htmlspecialchars($request->get('status')) : '') .
(isset($request->uid) ? '?uid=' . htmlspecialchars($request->get('uid')) : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords"/>
<select name="category">
<option value=""><?php _e('所有分类'); ?></option>
<?php \Widget\Metas\Category\Rows::alloc()->to($category); ?>
<?php while ($category->next()): ?>
<option
value="<?php $category->mid(); ?>"<?php if ($request->get('category') == $category->mid): ?> selected="true"<?php endif; ?>><?php $category->name(); ?></option>
<?php endwhile; ?>
</select>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
<?php if (isset($request->uid)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('uid')); ?>"
name="uid"/>
<?php endif; ?>
<?php if (isset($request->status)): ?>
<input type="hidden" value="<?php echo htmlspecialchars($request->get('status')); ?>"
name="status"/>
<?php endif; ?>
</div>
</form>
</div><!-- end .typecho-list-operate -->
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords || '' != $request->category): ?>
<a href="<?php $options->adminUrl('manage-posts.php'
. (isset($request->status) || isset($request->uid) ? '?' .
(isset($request->status) ? 'status=' . $request->filter('encode')->status : '') .
(isset($request->uid) ? (isset($request->status) ? '&' : '') . 'uid=' . $request->filter('encode')->uid : '') : '')); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo $request->filter('html')->keywords; ?>" name="keywords"/>
<select name="category">
<option value=""><?php _e('所有分类'); ?></option>
<?php \Widget\Metas\Category\Rows::alloc()->to($category); ?>
<?php while ($category->next()): ?>
<option
value="<?php $category->mid(); ?>"<?php if ($request->get('category') == $category->mid): ?> selected="true"<?php endif; ?>><?php $category->name(); ?></option>
<?php endwhile; ?>
</select>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
<?php if (isset($request->uid)): ?>
<input type="hidden" value="<?php echo $request->filter('html')->uid; ?>"
name="uid"/>
<?php endif; ?>
<?php if (isset($request->status)): ?>
<input type="hidden" value="<?php echo $request->filter('html')->status; ?>"
name="status"/>
<?php endif; ?>
</div>
</form>
<form method="post" name="manage_posts" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="20" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="45%"/>
<col width="" class="kit-hidden-mb"/>
<col width="18%" class="kit-hidden-mb"/>
<col width="16%"/>
</colgroup>
<thead>
<tr>
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('标题'); ?></th>
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
<th class="kit-hidden-mb"><?php _e('分类'); ?></th>
<th><?php _e('日期'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($posts->have()): ?>
<?php while ($posts->next()): ?>
<tr id="<?php $posts->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $posts->cid(); ?>"
name="cid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-comments.php?cid=' . ($posts->parentId ? $posts->parentId : $posts->cid)); ?>"
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($posts->commentsNum, 1, 10, 20, 50, 100); ?>"
title="<?php $posts->commentsNum(); ?> <?php _e('评论'); ?>"><?php $posts->commentsNum(); ?></a>
</td>
<td>
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"><?php $posts->title(); ?></a>
<?php
if ($posts->hasSaved || 'post_draft' == $posts->type) {
echo '<em class="status">' . _t('草稿') . '</em>';
}
<table class="typecho-list-table">
<colgroup>
<col width="3%" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="45%"/>
<col width="" class="kit-hidden-mb"/>
<col width="18%" class="kit-hidden-mb"/>
<col width="16%"/>
</colgroup>
<thead>
<tr>
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('标题'); ?></th>
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
<th class="kit-hidden-mb"><?php _e('分类'); ?></th>
<th><?php _e('日期'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($posts->have()): ?>
<?php while ($posts->next()): ?>
<tr id="<?php $posts->theId(); ?>">
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $posts->cid(); ?>"
name="cid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-comments.php?cid=' . ($posts->parentId ? $posts->parentId : $posts->cid)); ?>"
class="balloon-button size-<?php echo \Typecho\Common::splitByCount($posts->commentsNum, 1, 10, 20, 50, 100); ?>"
title="<?php $posts->commentsNum(); ?> <?php _e('评论'); ?>"><?php $posts->commentsNum(); ?></a>
</td>
<td>
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"><?php $posts->title(); ?></a>
<?php
if ('post_draft' == $posts->type) {
echo '<em class="status">' . _t('草稿') . '</em>';
} elseif ($posts->revision) {
echo '<em class="status">' . _t('有修订版') . '</em>';
}
if ('hidden' == $posts->status) {
echo '<em class="status">' . _t('隐藏') . '</em>';
} elseif ('waiting' == $posts->status) {
echo '<em class="status">' . _t('待审核') . '</em>';
} elseif ('private' == $posts->status) {
echo '<em class="status">' . _t('私密') . '</em>';
} elseif ($posts->password) {
echo '<em class="status">' . _t('密码保护') . '</em>';
}
?>
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"
title="<?php _e('编辑 %s', htmlspecialchars($posts->title)); ?>"><i
class="i-edit"></i></a>
<?php if ('post_draft' != $posts->type): ?>
<a href="<?php $posts->permalink(); ?>"
title="<?php _e('浏览 %s', htmlspecialchars($posts->title)); ?>"><i
class="i-exlink"></i></a>
<?php endif; ?>
</td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-posts.php?uid=' . $posts->author->uid); ?>"><?php $posts->author(); ?></a>
</td>
<td class="kit-hidden-mb"><?php $categories = $posts->categories;
$length = count($categories); ?>
<?php foreach ($categories as $key => $val): ?>
<?php echo '<a href="';
$options->adminUrl('manage-posts.php?category=' . $val['mid']
. (isset($request->uid) ? '&uid=' . $request->uid : '')
. (isset($request->status) ? '&status=' . $request->status : ''));
echo '">' . $val['name'] . '</a>' . ($key < $length - 1 ? ', ' : ''); ?>
<?php endforeach; ?>
</td>
<td>
<?php if ($posts->hasSaved): ?>
<span class="description">
<?php $modifyDate = new \Typecho\Date($posts->modified); ?>
<?php _e('保存于 %s', $modifyDate->word()); ?>
</span>
<?php else: ?>
<?php $posts->dateWord(); ?>
<?php endif; ?>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6"><h6 class="typecho-list-table-title"><?php _e('没有任何文章'); ?></h6>
if ('hidden' == $posts->status) {
echo '<em class="status">' . _t('隐藏') . '</em>';
} elseif ('waiting' == $posts->status) {
echo '<em class="status">' . _t('待审核') . '</em>';
} elseif ('private' == $posts->status) {
echo '<em class="status">' . _t('私密') . '</em>';
} elseif ($posts->password) {
echo '<em class="status">' . _t('密码保护') . '</em>';
}
?>
<a href="<?php $options->adminUrl('write-post.php?cid=' . $posts->cid); ?>"
title="<?php _e('编辑 %s', htmlspecialchars($posts->title)); ?>"><i
class="i-edit"></i></a>
<?php if ('post_draft' != $posts->type): ?>
<a href="<?php $posts->permalink(); ?>"
title="<?php _e('浏览 %s', htmlspecialchars($posts->title)); ?>"><i
class="i-exlink"></i></a>
<?php endif; ?>
</td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-posts.php?__typecho_all_posts=off&uid=' . $posts->author->uid); ?>"><?php $posts->author(); ?></a>
</td>
<td class="kit-hidden-mb"><?php foreach($posts->categories as $index => $category): ?><!--
--><?php echo ($index > 0 ? ', ' : '') . '<a href="';
$options->adminUrl('manage-posts.php?category=' . $category['mid']
. (isset($request->uid) ? '&uid=' . $request->filter('encode')->uid : '')
. (isset($request->status) ? '&status=' . $request->filter('encode')->status : ''));
echo '">' . $category['name'] . '</a>'; ?><!--
--><?php endforeach; ?>
</td>
<td>
<?php if ('post_draft' == $posts->type || $posts->revision): ?>
<span class="description">
<?php $modifyDate = new \Typecho\Date($posts->revision ? $posts->revision['modified'] : $posts->modified); ?>
<?php _e('保存于 %s', $modifyDate->word()); ?>
</span>
<?php else: ?>
<?php $posts->dateWord(); ?>
<?php endif; ?>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="6" class="none"><?php _e('没有任何文章'); ?></td>
</tr>
<?php endif; ?>
</tbody>
</table>
</form><!-- end .operate-form -->
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>"
href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些文章吗?'); ?>"
href="<?php $security->index('/action/contents-post-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
<?php if ($user->pass('editor', true)): ?>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
</li>
<?php if ($user->pass('editor', true)): ?>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=publish'); ?>"><?php _e('标记为<strong>%s</strong>', _t('公开')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=waiting'); ?>"><?php _e('标记为<strong>%s</strong>', _t('待审核')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=private'); ?>"><?php _e('标记为<strong>%s</strong>', _t('私密')); ?></a>
</li>
<?php endif; ?>
</ul>
</div>
</div>
<?php if ($posts->have()): ?>
<ul class="typecho-pager">
<?php $posts->pageNav(); ?>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=waiting'); ?>"><?php _e('标记为<strong>%s</strong>', _t('待审核')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=hidden'); ?>"><?php _e('标记为<strong>%s</strong>', _t('隐藏')); ?></a>
</li>
<li>
<a href="<?php $security->index('/action/contents-post-edit?do=mark&status=private'); ?>"><?php _e('标记为<strong>%s</strong>', _t('私密')); ?></a>
</li>
<?php endif; ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
</div>
</div>
<?php if ($posts->have()): ?>
<ul class="typecho-pager">
<?php $posts->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -6,7 +6,7 @@ include 'menu.php';
\Widget\Metas\Tag\Admin::alloc()->to($tags);
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main manage-metas">
@@ -14,7 +14,7 @@ include 'menu.php';
<div class="col-mb-12 col-tb-8" role="main">
<form method="post" name="manage_tags" class="operate-form">
<div class="typecho-list-operate clearfix">
<div class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
@@ -39,8 +39,8 @@ include 'menu.php';
</div>
</div>
<ul class="typecho-list-notable tag-list clearfix">
<?php if ($tags->have()): ?>
<?php if ($tags->have()): ?>
<ul class="typecho-list-notable tag-list">
<?php while ($tags->next()): ?>
<li class="size-<?php $tags->split(5, 10, 20, 30); ?>" id="<?php $tags->theId(); ?>">
<input type="checkbox" value="<?php $tags->mid(); ?>" name="mid[]"/>
@@ -51,10 +51,12 @@ include 'menu.php';
class="i-edit"></i></a>
</li>
<?php endwhile; ?>
<?php else: ?>
<h6 class="typecho-list-table-title"><?php _e('没有任何标签'); ?></h6>
<?php endif; ?>
</ul>
</ul>
<?php else: ?>
<ul class="tag-list">
<li class="none"><?php _e('没有任何标签'); ?></li>
</ul>
<?php endif; ?>
<input type="hidden" name="do" value="delete"/>
</form>
@@ -64,7 +66,7 @@ include 'menu.php';
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -5,131 +5,125 @@ include 'menu.php';
$users = \Widget\Users\Admin::alloc();
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12 typecho-list">
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>"
href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
</div>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>"
href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords): ?>
<a href="<?php $options->adminUrl('manage-users.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo htmlspecialchars($request->keywords); ?>" name="keywords"/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
</div><!-- end .typecho-list-operate -->
</div>
<div class="search" role="search">
<?php if ('' != $request->keywords): ?>
<a href="<?php $options->adminUrl('manage-users.php'); ?>"><?php _e('&laquo; 取消筛选'); ?></a>
<?php endif; ?>
<input type="text" class="text-s" placeholder="<?php _e('请输入关键字'); ?>"
value="<?php echo $request->filter('html')->keywords; ?>" name="keywords"/>
<button type="submit" class="btn btn-s"><?php _e('筛选'); ?></button>
</div>
</form>
<form method="post" name="manage_users" class="operate-form">
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="20" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="30%"/>
<col width="" class="kit-hidden-mb"/>
<col width="25%" class="kit-hidden-mb"/>
<col width="15%"/>
</colgroup>
<thead>
<tr>
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('用户名'); ?></th>
<th class="kit-hidden-mb"><?php _e('昵称'); ?></th>
<th class="kit-hidden-mb"><?php _e('电子邮件'); ?></th>
<th><?php _e('用户组'); ?></th>
<table class="typecho-list-table">
<colgroup>
<col width="3%" class="kit-hidden-mb"/>
<col width="6%" class="kit-hidden-mb"/>
<col width="30%"/>
<col width="" class="kit-hidden-mb"/>
<col width="25%" class="kit-hidden-mb"/>
<col width="15%"/>
</colgroup>
<thead>
<tr>
<th class="kit-hidden-mb"></th>
<th class="kit-hidden-mb"></th>
<th><?php _e('用户名'); ?></th>
<th class="kit-hidden-mb"><?php _e('昵称'); ?></th>
<th class="kit-hidden-mb"><?php _e('电子邮件'); ?></th>
<th><?php _e('用户组'); ?></th>
</tr>
</thead>
<tbody>
<?php while ($users->next()): ?>
<tr id="user-<?php $users->uid(); ?>">
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $users->uid(); ?>"
name="uid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-posts.php?__typecho_all_posts=off&uid=' . $users->uid); ?>"
class="balloon-button left size-<?php echo \Typecho\Common::splitByCount($users->postsNum, 1, 10, 20, 50, 100); ?>"><?php $users->postsNum(); ?></a>
</td>
<td>
<a href="<?php $options->adminUrl('user.php?uid=' . $users->uid); ?>"><?php $users->name(); ?></a>
<a href="<?php $users->permalink(); ?>"
title="<?php _e('浏览 %s', $users->screenName); ?>"><i
class="i-exlink"></i></a>
</td>
<td class="kit-hidden-mb"><?php $users->screenName(); ?></td>
<td class="kit-hidden-mb"><?php if ($users->mail): ?><a
href="mailto:<?php $users->mail(); ?>"><?php $users->mail(); ?></a><?php else: _e('暂无'); endif; ?>
</td>
<td><?php switch ($users->group) {
case 'administrator':
_e('管理员');
break;
case 'editor':
_e('编辑');
break;
case 'contributor':
_e('贡献者');
break;
case 'subscriber':
_e('关注者');
break;
case 'visitor':
_e('访问者');
break;
default:
break;
} ?></td>
</tr>
</thead>
<tbody>
<?php while ($users->next()): ?>
<tr id="user-<?php $users->uid(); ?>">
<td class="kit-hidden-mb"><input type="checkbox" value="<?php $users->uid(); ?>"
name="uid[]"/></td>
<td class="kit-hidden-mb"><a
href="<?php $options->adminUrl('manage-posts.php?uid=' . $users->uid); ?>"
class="balloon-button left size-<?php echo \Typecho\Common::splitByCount($users->postsNum, 1, 10, 20, 50, 100); ?>"><?php $users->postsNum(); ?></a>
</td>
<td>
<a href="<?php $options->adminUrl('user.php?uid=' . $users->uid); ?>"><?php $users->name(); ?></a>
<a href="<?php $users->permalink(); ?>"
title="<?php _e('浏览 %s', $users->screenName); ?>"><i
class="i-exlink"></i></a>
</td>
<td class="kit-hidden-mb"><?php $users->screenName(); ?></td>
<td class="kit-hidden-mb"><?php if ($users->mail): ?><a
href="mailto:<?php $users->mail(); ?>"><?php $users->mail(); ?></a><?php else: _e('暂无'); endif; ?>
</td>
<td><?php switch ($users->group) {
case 'administrator':
_e('管理员');
break;
case 'editor':
_e('编辑');
break;
case 'contributor':
_e('贡献者');
break;
case 'subscriber':
_e('关注者');
break;
case 'visitor':
_e('访问者');
break;
default:
break;
} ?></td>
</tr>
<?php endwhile; ?>
</tbody>
</table><!-- end .typecho-list-table -->
</div><!-- end .typecho-table-wrap -->
<?php endwhile; ?>
</tbody>
</table><!-- end .typecho-list-table -->
</form><!-- end .operate-form -->
<div class="typecho-list-operate clearfix">
<form method="get">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>"
href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
</div>
</div>
<?php if ($users->have()): ?>
<ul class="typecho-pager">
<?php $users->pageNav(); ?>
<form method="get" class="typecho-list-operate">
<div class="operate">
<label><i class="sr-only"><?php _e('全选'); ?></i><input type="checkbox"
class="typecho-table-select-all"/></label>
<div class="btn-group btn-drop">
<button class="btn dropdown-toggle btn-s" type="button"><i
class="sr-only"><?php _e('操作'); ?></i><?php _e('选中项'); ?> <i
class="i-caret-down"></i></button>
<ul class="dropdown-menu">
<li><a lang="<?php _e('你确认要删除这些用户吗?'); ?>"
href="<?php $security->index('/action/users-edit?do=delete'); ?>"><?php _e('删除'); ?></a>
</li>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list-operate -->
</div>
</div>
<?php if ($users->have()): ?>
<ul class="typecho-pager">
<?php $users->pageNav(); ?>
</ul>
<?php endif; ?>
</form>
</div><!-- end .typecho-list -->
</div><!-- end .typecho-page-main -->
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -3,16 +3,10 @@ include 'common.php';
include 'header.php';
include 'menu.php';
$phpMaxFilesize = function_exists('ini_get') ? trim(ini_get('upload_max_filesize')) : 0;
if (preg_match("/^([0-9]+)([a-z]{1,2})$/i", $phpMaxFilesize, $matches)) {
$phpMaxFilesize = strtolower($matches[1] . $matches[2] . (1 == strlen($matches[2]) ? 'b' : ''));
}
$attachment = \Widget\Contents\Attachment\Edit::alloc();
\Widget\Contents\Attachment\Edit::alloc()->prepare()->to($attachment);
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main">
@@ -35,8 +29,9 @@ $attachment = \Widget\Contents\Attachment\Edit::alloc();
</p>
<div id="upload-panel" class="p">
<div class="upload-area"
draggable="true"><?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?></div>
<div class="upload-area" data-url="<?php $security->index('/action/upload?do=modify'); ?>">
<?php _e('拖放文件到这里<br>或者 %s选择文件上传%s', '<a href="###" class="upload-file">', '</a>'); ?>
</div>
<ul id="file-list"></ul>
</div>
</div>
@@ -45,14 +40,13 @@ $attachment = \Widget\Contents\Attachment\Edit::alloc();
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';
include 'common-js.php';
include 'file-upload-js.php';
?>
<script src="<?php $options->adminStaticUrl('js', 'moxie.js'); ?>"></script>
<script src="<?php $options->adminStaticUrl('js', 'plupload.js'); ?>"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#attachment-url').click(function () {
@@ -69,130 +63,16 @@ include 'common-js.php';
return false;
});
$('.upload-area').bind({
dragenter: function () {
$(this).parent().addClass('drag');
},
dragover: function (e) {
$(this).parent().addClass('drag');
},
drop: function () {
$(this).parent().removeClass('drag');
},
dragend: function () {
$(this).parent().removeClass('drag');
},
dragleave: function () {
$(this).parent().removeClass('drag');
}
});
function fileUploadStart(file) {
$('<ul id="file-list"></ul>').appendTo('#upload-panel');
$('<li id="' + file.id + '" class="loading">'
+ file.name + '</li>').prependTo('#file-list');
}
function fileUploadError(error) {
var file = error.file, code = error.code, word;
switch (code) {
case plupload.FILE_SIZE_ERROR:
word = '<?php _e('文件大小超过限制'); ?>';
break;
case plupload.FILE_EXTENSION_ERROR:
word = '<?php _e('文件扩展名不被支持'); ?>';
break;
case plupload.FILE_DUPLICATE_ERROR:
word = '<?php _e('文件已经上传过'); ?>';
break;
case plupload.HTTP_ERROR:
default:
word = '<?php _e('上传出现错误'); ?>';
break;
Typecho.uploadComplete = function (attachment) {
if (attachment.isImage) {
$('.typecho-attachment-photo').attr('src', attachment.url + '?' + Math.random());
}
var fileError = '<?php _e('%s 上传失败'); ?>'.replace('%s', file.name),
li, exist = $('#' + file.id);
if (exist.length > 0) {
li = exist.removeClass('loading').html(fileError);
} else {
$('<ul id="file-list"></ul>').appendTo('#upload-panel');
li = $('<li>' + fileError + '<br />' + word + '</li>').prependTo('#file-list');
}
li.effect('highlight', {color: '#FBC2C4'}, 2000, function () {
$(this).remove();
});
}
function fileUploadComplete(id, url, data) {
var img = $('.typecho-attachment-photo');
if (img.length > 0) {
img.get(0).src = '<?php $attachment->attachment->url(); ?>?' + Math.random();
}
$('#' + id).html('<?php _e('文件 %s 已经替换'); ?>'.replace('%s', data.title))
$('#file-list li').text('<?php _e('文件 %s 已经替换'); ?>'.replace('%s', attachment.title))
.effect('highlight', 1000, function () {
$(this).remove();
$('#file-list').remove();
});
}
var uploader = new plupload.Uploader({
browse_button: $('.upload-file').get(0),
url: '<?php $security->index('/action/upload?do=modify&cid=' . $attachment->cid); ?>',
runtimes: 'html5,flash,html4',
flash_swf_url: '<?php $options->adminStaticUrl('js', 'Moxie.swf'); ?>',
drop_element: $('.upload-area').get(0),
filters: {
max_file_size: '<?php echo $phpMaxFilesize ?>',
mime_types: [{
'title': '<?php _e('允许上传的文件'); ?>',
'extensions': '<?php $attachment->attachment->type(); ?>'
}],
prevent_duplicates: true
},
multi_selection: false,
init: {
FilesAdded: function (up, files) {
plupload.each(files, function (file) {
fileUploadStart(file);
});
uploader.start();
},
FileUploaded: function (up, file, result) {
if (200 == result.status) {
var data = $.parseJSON(result.response);
if (data) {
fileUploadComplete(file.id, data[0], data[1]);
return;
}
}
fileUploadError({
code: plupload.HTTP_ERROR,
file: file
});
},
Error: function (up, error) {
fileUploadError(error);
}
}
});
uploader.init();
};
});
</script>
<?php

View File

@@ -1,18 +1,22 @@
<?php if (!defined('__TYPECHO_ADMIN__')) exit; ?>
<div class="typecho-head-nav clearfix" role="navigation">
<button class="menu-bar"><?php _e('菜单'); ?></button>
<nav id="typecho-nav-list">
<?php $menu->output(); ?>
<header class="typecho-head-nav" role="navigation">
<nav>
<details class="menu-bar">
<summary><?php _e('菜单'); ?></summary>
</details>
<menu>
<?php $menu->output(); ?>
<li class="operate">
<?php \Typecho\Plugin::factory('admin/menu.php')->call('navBar'); ?><a title="<?php
if ($user->logged > 0) {
$logged = new \Typecho\Date($user->logged);
_e('最后登录: %s', $logged->word());
}
?>" href="<?php $options->adminUrl('profile.php'); ?>" class="author"><?php $user->screenName(); ?></a><a
class="exit" href="<?php $options->logoutUrl(); ?>"><?php _e('登出'); ?></a><a
href="<?php $options->siteUrl(); ?>"><?php _e('网站'); ?></a>
</li>
</menu>
</nav>
<div class="operate">
<?php \Typecho\Plugin::factory('admin/menu.php')->navBar(); ?><a title="<?php
if ($user->logged > 0) {
$logged = new \Typecho\Date($user->logged);
_e('最后登录: %s', $logged->word());
}
?>" href="<?php $options->adminUrl('profile.php'); ?>" class="author"><?php $user->screenName(); ?></a><a
class="exit" href="<?php $options->logoutUrl(); ?>"><?php _e('登出'); ?></a><a
href="<?php $options->siteUrl(); ?>"><?php _e('网站'); ?></a>
</div>
</div>
</header>

View File

@@ -4,7 +4,7 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
@@ -13,7 +13,7 @@ include 'menu.php';
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,7 +4,7 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
@@ -13,7 +13,7 @@ include 'menu.php';
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,7 +4,7 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
@@ -13,7 +13,7 @@ include 'menu.php';
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,7 +4,7 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
@@ -13,7 +13,7 @@ include 'menu.php';
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,7 +4,7 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
@@ -13,7 +13,7 @@ include 'menu.php';
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,26 +4,17 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<?php include 'theme-tabs.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12">
<ul class="typecho-option-tabs fix-tabs clearfix">
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a></li>
<?php if (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__): ?>
<li><a href="<?php $options->adminUrl('theme-editor.php'); ?>"><?php _e('编辑当前外观'); ?></a></li>
<?php endif; ?>
<li class="current"><a
href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
</ul>
</div>
<div class="col-mb-12 col-tb-8 col-tb-offset-2" role="form">
<?php \Widget\Themes\Config::alloc()->config()->render(); ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -1,8 +1,9 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php if (!defined('__TYPECHO_ADMIN__')) exit; ?>
<div class="typecho-page-title">
<h2><?php echo $menu->title; ?><?php
<h2><?php echo $menu->title; ?></h2>
<?php
if (!empty($menu->addLink)) {
echo "<a href=\"{$menu->addLink}\">" . _t("新增") . "</a>";
}
?></h2>
?>
</div>

View File

@@ -3,7 +3,7 @@ include 'common.php';
include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
@@ -11,120 +11,116 @@ include 'menu.php';
<?php \Widget\Plugins\Rows::allocWithAlias('activated', 'activated=1')->to($activatedPlugins); ?>
<?php if ($activatedPlugins->have() || !empty($activatedPlugins->activatedPlugins)): ?>
<h4 class="typecho-list-table-title"><?php _e('启用的插件'); ?></h4>
<div class="typecho-table-wrap">
<table class="typecho-list-table">
<colgroup>
<col width="25%"/>
<col width="45%"/>
<col width="8%" class="kit-hidden-mb"/>
<col width="10%" class="kit-hidden-mb"/>
<col width=""/>
</colgroup>
<thead>
<tr>
<th><?php _e('名称'); ?></th>
<th><?php _e('描述'); ?></th>
<th class="kit-hidden-mb"><?php _e('版本'); ?></th>
<th class="kit-hidden-mb"><?php _e('作'); ?></th>
<th><?php _e('操作'); ?></th>
<table class="typecho-list-table">
<colgroup>
<col width="25%"/>
<col width="45%"/>
<col width="8%" class="kit-hidden-mb"/>
<col width="10%" class="kit-hidden-mb"/>
<col width=""/>
</colgroup>
<thead>
<tr>
<th><?php _e('名称'); ?></th>
<th><?php _e('描述'); ?></th>
<th class="kit-hidden-mb"><?php _e('版本'); ?></th>
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
<th><?php _e('作'); ?></th>
</tr>
</thead>
<tbody>
<?php while ($activatedPlugins->next()): ?>
<tr id="plugin-<?php $activatedPlugins->name(); ?>">
<td><?php $activatedPlugins->title(); ?>
<?php if (!$activatedPlugins->dependence): ?>
<i class="i-delete"
title="<?php _e('%s 无法在此版本的typecho下正常工作', $activatedPlugins->title); ?>"></i>
<?php endif; ?>
</td>
<td><?php $activatedPlugins->description(); ?></td>
<td class="kit-hidden-mb"><?php $activatedPlugins->version(); ?></td>
<td class="kit-hidden-mb"><?php echo empty($activatedPlugins->homepage) ? $activatedPlugins->author : '<a href="' . $activatedPlugins->homepage
. '">' . $activatedPlugins->author . '</a>'; ?></td>
<td>
<?php if ($activatedPlugins->activate || $activatedPlugins->deactivate || $activatedPlugins->config || $activatedPlugins->personalConfig): ?>
<?php if ($activatedPlugins->config): ?>
<a href="<?php $options->adminUrl('options-plugin.php?config=' . $activatedPlugins->name); ?>"><?php _e('设置'); ?></a>
&bull;
<?php endif; ?>
<a lang="<?php _e('你确认要禁用插件 %s 吗?', $activatedPlugins->name); ?>"
href="<?php $security->index('/action/plugins-edit?deactivate=' . $activatedPlugins->name); ?>"><?php _e('禁用'); ?></a>
<?php else: ?>
<span class="important"><?php _e('即插即用'); ?></span>
<?php endif; ?>
</td>
</tr>
</thead>
<tbody>
<?php while ($activatedPlugins->next()): ?>
<tr id="plugin-<?php $activatedPlugins->name(); ?>">
<td><?php $activatedPlugins->title(); ?>
<?php if (!$activatedPlugins->dependence): ?>
<i class="i-delete"
title="<?php _e('%s 无法在此版本的typecho下正常工作', $activatedPlugins->title); ?>"></i>
<?php endif; ?>
</td>
<td><?php $activatedPlugins->description(); ?></td>
<td class="kit-hidden-mb"><?php $activatedPlugins->version(); ?></td>
<td class="kit-hidden-mb"><?php echo empty($activatedPlugins->homepage) ? $activatedPlugins->author : '<a href="' . $activatedPlugins->homepage
. '">' . $activatedPlugins->author . '</a>'; ?></td>
<td>
<?php if ($activatedPlugins->activate || $activatedPlugins->deactivate || $activatedPlugins->config || $activatedPlugins->personalConfig): ?>
<?php if ($activatedPlugins->config): ?>
<a href="<?php $options->adminUrl('options-plugin.php?config=' . $activatedPlugins->name); ?>"><?php _e('设置'); ?></a>
&bull;
<?php endif; ?>
<a lang="<?php _e('你确认要禁用插件 %s 吗?', $activatedPlugins->name); ?>"
href="<?php $security->index('/action/plugins-edit?deactivate=' . $activatedPlugins->name); ?>"><?php _e('禁用'); ?></a>
<?php else: ?>
<span class="important"><?php _e('即插即用'); ?></span>
<?php endif; ?>
<?php endwhile; ?>
<?php if (!empty($activatedPlugins->activatedPlugins)): ?>
<?php foreach ($activatedPlugins->activatedPlugins as $key => $val): ?>
<tr>
<td><?php echo $key; ?></td>
<td colspan="3"><span
class="warning"><?php _e('此插件文件已经损坏或者被不安全移除, 强烈建议你禁用它'); ?></span></td>
<td><a lang="<?php _e('你确认要禁用插件 %s 吗?', $key); ?>"
href="<?php $security->index('/action/plugins-edit?deactivate=' . $key); ?>"><?php _e('禁用'); ?></a>
</td>
</tr>
<?php endwhile; ?>
<?php endforeach; ?>
<?php endif; ?>
<?php if (!empty($activatedPlugins->activatedPlugins)): ?>
<?php foreach ($activatedPlugins->activatedPlugins as $key => $val): ?>
<tr>
<td><?php echo $key; ?></td>
<td colspan="3"><span
class="warning"><?php _e('此插件文件已经损坏或者被不安全移除, 强烈建议你禁用它'); ?></span></td>
<td><a lang="<?php _e('你确认要禁用插件 %s 吗?', $key); ?>"
href="<?php $security->index('/action/plugins-edit?deactivate=' . $key); ?>"><?php _e('禁用'); ?></a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</tbody>
</table>
<?php endif; ?>
<?php \Widget\Plugins\Rows::allocWithAlias('unactivated', 'activated=0')->to($deactivatedPlugins); ?>
<?php if ($deactivatedPlugins->have() || !$activatedPlugins->have()): ?>
<h4 class="typecho-list-table-title"><?php _e('禁用的插件'); ?></h4>
<div class="typecho-table-wrap">
<table class="typecho-list-table deactivate">
<colgroup>
<col width="25%"/>
<col width="45%"/>
<col width="8%" class="kit-hidden-mb"/>
<col width="10%" class="kit-hidden-mb"/>
<col width=""/>
</colgroup>
<thead>
<tr>
<th><?php _e('名称'); ?></th>
<th><?php _e('描述'); ?></th>
<th class="kit-hidden-mb"><?php _e('版本'); ?></th>
<th class="kit-hidden-mb"><?php _e('作'); ?></th>
<th class="typecho-radius-topright"><?php _e('操作'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($deactivatedPlugins->have()): ?>
<?php while ($deactivatedPlugins->next()): ?>
<tr id="plugin-<?php $deactivatedPlugins->name(); ?>">
<td><?php $deactivatedPlugins->title(); ?></td>
<td><?php $deactivatedPlugins->description(); ?></td>
<td class="kit-hidden-mb"><?php $deactivatedPlugins->version(); ?></td>
<td class="kit-hidden-mb"><?php echo empty($deactivatedPlugins->homepage) ? $deactivatedPlugins->author : '<a href="' . $deactivatedPlugins->homepage
. '">' . $deactivatedPlugins->author . '</a>'; ?></td>
<td>
<a href="<?php $security->index('/action/plugins-edit?activate=' . $deactivatedPlugins->name); ?>"><?php _e('启用'); ?></a>
</td>
</tr>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="5"><h6 class="typecho-list-table-title"><?php _e('没有安装插件'); ?></h6>
<table class="typecho-list-table deactivate">
<colgroup>
<col width="25%"/>
<col width="45%"/>
<col width="8%" class="kit-hidden-mb"/>
<col width="10%" class="kit-hidden-mb"/>
<col width=""/>
</colgroup>
<thead>
<tr>
<th><?php _e('名称'); ?></th>
<th><?php _e('描述'); ?></th>
<th class="kit-hidden-mb"><?php _e('版本'); ?></th>
<th class="kit-hidden-mb"><?php _e('作者'); ?></th>
<th class="typecho-radius-topright"><?php _e('作'); ?></th>
</tr>
</thead>
<tbody>
<?php if ($deactivatedPlugins->have()): ?>
<?php while ($deactivatedPlugins->next()): ?>
<tr id="plugin-<?php $deactivatedPlugins->name(); ?>">
<td><?php $deactivatedPlugins->title(); ?></td>
<td><?php $deactivatedPlugins->description(); ?></td>
<td class="kit-hidden-mb"><?php $deactivatedPlugins->version(); ?></td>
<td class="kit-hidden-mb"><?php echo empty($deactivatedPlugins->homepage) ? $deactivatedPlugins->author : '<a href="' . $deactivatedPlugins->homepage
. '">' . $deactivatedPlugins->author . '</a>'; ?></td>
<td>
<a href="<?php $security->index('/action/plugins-edit?activate=' . $deactivatedPlugins->name); ?>"><?php _e('启用'); ?></a>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
</div>
<?php endwhile; ?>
<?php else: ?>
<tr>
<td colspan="5"><h6 class="typecho-list-table-title"><?php _e('没有安装插件'); ?></h6>
</td>
</tr>
<?php endif; ?>
</tbody>
</table>
<?php endif; ?>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -6,12 +6,12 @@ include 'menu.php';
$stat = \Widget\Stat::alloc();
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main">
<div class="col-mb-12 col-tb-3">
<p><a href="http://gravatar.com/emails/"
<p><a href="https://gravatar.com/"
title="<?php _e('在 Gravatar 上修改头像'); ?>"><?php echo '<img class="profile-avatar" src="' . \Typecho\Common::gravatarUrl($user->mail, 220, 'X', 'mm', $request->isSecure()) . '" alt="' . $user->screenName . '" />'; ?></a>
</p>
<h2><?php $user->screenName(); ?></h2>
@@ -51,12 +51,12 @@ $stat = \Widget\Stat::alloc();
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';
include 'common-js.php';
include 'form-js.php';
\Typecho\Plugin::factory('admin/profile.php')->bottom();
\Typecho\Plugin::factory('admin/profile.php')->call('bottom');
include 'footer.php';
?>

View File

@@ -4,8 +4,8 @@ include 'common.php';
if ($user->hasLogin() || !$options->allowRegister) {
$response->redirect($options->siteUrl);
}
$rememberName = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_name'));
$rememberMail = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_mail'));
$rememberName = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_name', ''));
$rememberMail = htmlspecialchars(\Typecho\Cookie::get('__typecho_remember_mail', ''));
\Typecho\Cookie::delete('__typecho_remember_name');
\Typecho\Cookie::delete('__typecho_remember_mail');
@@ -15,7 +15,7 @@ include 'header.php';
?>
<div class="typecho-login-wrap">
<div class="typecho-login">
<h1><a href="http://typecho.org" class="i-logo">Typecho</a></h1>
<h1><a href="https://typecho.org" class="i-logo">Typecho</a></h1>
<form action="<?php $options->registerAction(); ?>" method="post" name="register" role="form">
<p>
<label for="name" class="sr-only"><?php _e('用户名'); ?></label>

View File

@@ -583,44 +583,46 @@
parseBlockTable(block, key, line, state, lines) {
var align, aligns, head, j, len, matches, row, rows;
if (!!(matches = line.match(/^((?:(?:(?:\||\+)(?:[ :]*\-+[ :]*)(?:\||\+))|(?:(?:[ :]*\-+[ :]*)(?:\||\+)(?:[ :]*\-+[ :]*))|(?:(?:[ :]*\-+[ :]*)(?:\||\+))|(?:(?:\||\+)(?:[ :]*\-+[ :]*)))+)$/))) {
if (this.isBlock('table')) {
block[3][0].push(block[3][2]);
block[3][2] += 1;
this.setBlock(key, block[3]);
} else {
head = 0;
if ((block == null) || block[0] !== 'normal' || lines[block[2]].match(/^\s*$/)) {
this.startBlock('table', key);
if (!!(matches = line.match(/^\s*(\|?[ :]*-{2,}[ :]*(?:[\|\+][ :]*-{2,}[ :]*)*\|?)\s*$/))) {
if (matches[1].indexOf('|') >= 0 || matches[1].indexOf('+') >= 0) {
if (this.isBlock('table')) {
block[3][0].push(block[3][2]);
block[3][2] += 1;
this.setBlock(key, block[3]);
} else {
head = 1;
this.backBlock(1, 'table');
}
if (matches[1][0] === '|') {
matches[1] = matches[1].substring(1);
if (matches[1][matches[1].length - 1] === '|') {
matches[1] = matches[1].substring(0, matches[1].length - 1);
head = 0;
if ((block == null) || block[0] !== 'normal' || lines[block[2]].match(/^\s*$/)) {
this.startBlock('table', key);
} else {
head = 1;
this.backBlock(1, 'table');
}
}
rows = matches[1].split(/\+|\|/);
aligns = [];
for (j = 0, len = rows.length; j < len; j++) {
row = rows[j];
align = 'none';
if (!!(matches = row.match(/^\s*(:?)\-+(:?)\s*$/))) {
if (!!matches[1] && !!matches[2]) {
align = 'center';
} else if (!!matches[1]) {
align = 'left';
} else if (!!matches[2]) {
align = 'right';
if (matches[1][0] === '|') {
matches[1] = matches[1].substring(1);
if (matches[1][matches[1].length - 1] === '|') {
matches[1] = matches[1].substring(0, matches[1].length - 1);
}
}
aligns.push(align);
rows = matches[1].split(/\+|\|/);
aligns = [];
for (j = 0, len = rows.length; j < len; j++) {
row = rows[j];
align = 'none';
if (!!(matches = row.match(/^\s*(:?)\-+(:?)\s*$/))) {
if (!!matches[1] && !!matches[2]) {
align = 'center';
} else if (!!matches[1]) {
align = 'left';
} else if (!!matches[2]) {
align = 'right';
}
}
aligns.push(align);
}
this.setBlock(key, [[head], aligns, head + 1]);
}
this.setBlock(key, [[head], aligns, head + 1]);
return false;
}
return false;
}
return true;
}
@@ -649,7 +651,7 @@
}
parseBlockShr(block, key, line) {
if (!!(line.match(/^(\* *){3,}\s*$/))) {
if (!!(line.match(/^\*{3,}\s*$/))) {
this.startBlock('hr', key).endBlock();
return false;
}
@@ -657,7 +659,7 @@
}
parseBlockDhr(block, key, line) {
if (!!(line.match(/^(- *){3,}\s*$/))) {
if (!!(line.match(/^-{3,}\s*$/))) {
this.startBlock('hr', key).endBlock();
return false;
}
@@ -819,7 +821,7 @@
}
parseList(lines, value, start) {
var html, j, key, l, last, len, len1, line, matches, row, rows, space, suffix, tab, type;
var html, j, key, l, last, len, len1, line, matches, olStart, row, rows, space, suffix, tab, type;
html = '';
[space, type, tab] = value;
rows = [];
@@ -829,9 +831,9 @@
line = lines[key];
if (matches = line.match(new RegExp(`^(\\s{${space}})((?:[0-9]+\\.?)|\\-|\\+|\\*)(\\s+)(.*)$`))) {
if (type === 'ol' && key === 0) {
start = parseInt(matches[2]);
if (start !== 1) {
suffix = ' start="' + start + '"';
olStart = parseInt(matches[2]);
if (olStart !== 1) {
suffix = ' start="' + olStart + '"';
}
}
rows.push([matches[4]]);

File diff suppressed because it is too large Load Diff

View File

@@ -1700,8 +1700,8 @@ else
// The default text that appears in the dialog input box when entering
// links.
var imageDefaultText = "http://";
var linkDefaultText = "http://";
var imageDefaultText = "https://";
var linkDefaultText = "https://";
// -------------------------------------------------------------------
// END OF YOUR CHANGES
@@ -1767,6 +1767,8 @@ else
hooks.addNoop("enterFakeFullScreen");
hooks.addNoop("exitFullScreen");
hooks.addNoop("save");
this.getConverter = function () { return markdownConverter; }
var that = this,
@@ -2880,8 +2882,8 @@ else
text = text.replace(/^http:\/\/(https?|ftp):\/\//, '$1://');
// fix issue #552
if (!/^(?:https?|ftp):\/\//.test(text) && !/^[_a-z0-9-]+:/i.test(text))
text = 'http://' + text;
// if (!/^(?:https?|ftp):\/\//.test(text) && !/^[_a-z0-9-]+:/i.test(text))
// text = 'http://' + text;
}
dialog.parentNode.removeChild(dialog);
@@ -3082,11 +3084,13 @@ else
doClick(buttons.undo);
}
break;
case "s":
hooks.save();
break;
default:
return;
}
if (key.preventDefault) {
key.preventDefault();
}

View File

@@ -1,443 +0,0 @@
// Generated by CoffeeScript 1.12.7
/*
paste.js is an interface to read data ( text / image ) from clipboard in different browsers. It also contains several hacks.
https://github.com/layerssss/paste.js
*/
(function() {
var $, Paste, createHiddenEditable, dataURLtoBlob, isFocusable;
$ = window.jQuery;
$.paste = function(pasteContainer) {
var pm;
if (typeof console !== "undefined" && console !== null) {
console.log("DEPRECATED: This method is deprecated. Please use $.fn.pastableNonInputable() instead.");
}
pm = Paste.mountNonInputable(pasteContainer);
return pm._container;
};
$.fn.pastableNonInputable = function() {
var el, j, len, ref;
ref = this;
for (j = 0, len = ref.length; j < len; j++) {
el = ref[j];
if (el._pastable || $(el).is('textarea, input:text, [contenteditable]')) {
continue;
}
Paste.mountNonInputable(el);
el._pastable = true;
}
return this;
};
$.fn.pastableTextarea = function() {
var el, j, len, ref;
ref = this;
for (j = 0, len = ref.length; j < len; j++) {
el = ref[j];
if (el._pastable || $(el).is(':not(textarea, input:text)')) {
continue;
}
Paste.mountTextarea(el);
el._pastable = true;
}
return this;
};
$.fn.pastableContenteditable = function() {
var el, j, len, ref;
ref = this;
for (j = 0, len = ref.length; j < len; j++) {
el = ref[j];
if (el._pastable || $(el).is(':not([contenteditable])')) {
continue;
}
Paste.mountContenteditable(el);
el._pastable = true;
}
return this;
};
dataURLtoBlob = function(dataURL, sliceSize) {
var b64Data, byteArray, byteArrays, byteCharacters, byteNumbers, contentType, i, m, offset, ref, slice;
if (sliceSize == null) {
sliceSize = 512;
}
if (!(m = dataURL.match(/^data\:([^\;]+)\;base64\,(.+)$/))) {
return null;
}
ref = m, m = ref[0], contentType = ref[1], b64Data = ref[2];
byteCharacters = atob(b64Data);
byteArrays = [];
offset = 0;
while (offset < byteCharacters.length) {
slice = byteCharacters.slice(offset, offset + sliceSize);
byteNumbers = new Array(slice.length);
i = 0;
while (i < slice.length) {
byteNumbers[i] = slice.charCodeAt(i);
i++;
}
byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray);
offset += sliceSize;
}
return new Blob(byteArrays, {
type: contentType
});
};
createHiddenEditable = function() {
return $(document.createElement('div')).attr('contenteditable', true).attr('aria-hidden', true).attr('tabindex', -1).css({
width: 1,
height: 1,
position: 'fixed',
left: -100,
overflow: 'hidden',
opacity: 1e-17
});
};
isFocusable = function(element, hasTabindex) {
var fieldset, focusableIfVisible, img, map, mapName, nodeName;
map = void 0;
mapName = void 0;
img = void 0;
focusableIfVisible = void 0;
fieldset = void 0;
nodeName = element.nodeName.toLowerCase();
if ('area' === nodeName) {
map = element.parentNode;
mapName = map.name;
if (!element.href || !mapName || map.nodeName.toLowerCase() !== 'map') {
return false;
}
img = $('img[usemap=\'#' + mapName + '\']');
return img.length > 0 && img.is(':visible');
}
if (/^(input|select|textarea|button|object)$/.test(nodeName)) {
focusableIfVisible = !element.disabled;
if (focusableIfVisible) {
fieldset = $(element).closest('fieldset')[0];
if (fieldset) {
focusableIfVisible = !fieldset.disabled;
}
}
} else if ('a' === nodeName) {
focusableIfVisible = element.href || hasTabindex;
} else {
focusableIfVisible = hasTabindex;
}
focusableIfVisible = focusableIfVisible || $(element).is('[contenteditable]');
return focusableIfVisible && $(element).is(':visible');
};
Paste = (function() {
Paste.prototype._target = null;
Paste.prototype._container = null;
Paste.mountNonInputable = function(nonInputable) {
var paste;
paste = new Paste(createHiddenEditable().appendTo(nonInputable), nonInputable);
$(nonInputable).on('click', (function(_this) {
return function(ev) {
if (!(isFocusable(ev.target, false) || window.getSelection().toString())) {
return paste._container.focus();
}
};
})(this));
paste._container.on('focus', (function(_this) {
return function() {
return $(nonInputable).addClass('pastable-focus');
};
})(this));
return paste._container.on('blur', (function(_this) {
return function() {
return $(nonInputable).removeClass('pastable-focus');
};
})(this));
};
Paste.mountTextarea = function(textarea) {
var ctlDown, paste, ref, ref1;
if ((typeof DataTransfer !== "undefined" && DataTransfer !== null ? DataTransfer.prototype : void 0) && ((ref = Object.getOwnPropertyDescriptor) != null ? (ref1 = ref.call(Object, DataTransfer.prototype, 'items')) != null ? ref1.get : void 0 : void 0)) {
return this.mountContenteditable(textarea);
}
paste = new Paste(createHiddenEditable().insertBefore(textarea), textarea);
ctlDown = false;
$(textarea).on('keyup', function(ev) {
var ref2;
if ((ref2 = ev.keyCode) === 17 || ref2 === 224) {
ctlDown = false;
}
return null;
});
$(textarea).on('keydown', function(ev) {
var ref2;
if ((ref2 = ev.keyCode) === 17 || ref2 === 224) {
ctlDown = true;
}
if ((ev.ctrlKey != null) && (ev.metaKey != null)) {
ctlDown = ev.ctrlKey || ev.metaKey;
}
if (ctlDown && ev.keyCode === 86) {
paste._textarea_focus_stolen = true;
paste._container.focus();
paste._paste_event_fired = false;
setTimeout((function(_this) {
return function() {
if (!paste._paste_event_fired) {
$(textarea).focus();
return paste._textarea_focus_stolen = false;
}
};
})(this), 1);
}
return null;
});
$(textarea).on('paste', (function(_this) {
return function() {};
})(this));
$(textarea).on('focus', (function(_this) {
return function() {
if (!paste._textarea_focus_stolen) {
return $(textarea).addClass('pastable-focus');
}
};
})(this));
$(textarea).on('blur', (function(_this) {
return function() {
if (!paste._textarea_focus_stolen) {
return $(textarea).removeClass('pastable-focus');
}
};
})(this));
$(paste._target).on('_pasteCheckContainerDone', (function(_this) {
return function() {
$(textarea).focus();
return paste._textarea_focus_stolen = false;
};
})(this));
return $(paste._target).on('pasteText', (function(_this) {
return function(ev, data) {
var content, curEnd, curStart;
curStart = $(textarea).prop('selectionStart');
curEnd = $(textarea).prop('selectionEnd');
content = $(textarea).val();
$(textarea).val("" + content.slice(0, curStart) + data.text + content.slice(curEnd));
$(textarea)[0].setSelectionRange(curStart + data.text.length, curStart + data.text.length);
return $(textarea).trigger('change');
};
})(this));
};
Paste.mountContenteditable = function(contenteditable) {
var paste;
paste = new Paste(contenteditable, contenteditable);
$(contenteditable).on('focus', (function(_this) {
return function() {
return $(contenteditable).addClass('pastable-focus');
};
})(this));
return $(contenteditable).on('blur', (function(_this) {
return function() {
return $(contenteditable).removeClass('pastable-focus');
};
})(this));
};
function Paste(_container, _target) {
this._container = _container;
this._target = _target;
this._container = $(this._container);
this._target = $(this._target).addClass('pastable');
this._container.on('paste', (function(_this) {
return function(ev) {
var _i, clipboardData, file, fileType, item, j, k, l, len, len1, len2, pastedFilename, reader, ref, ref1, ref2, ref3, ref4, stringIsFilename, text;
_this.originalEvent = (ev.originalEvent !== null ? ev.originalEvent : null);
_this._paste_event_fired = true;
if (((ref = ev.originalEvent) != null ? ref.clipboardData : void 0) != null) {
clipboardData = ev.originalEvent.clipboardData;
if (clipboardData.items) {
pastedFilename = null;
_this.originalEvent.pastedTypes = [];
ref1 = clipboardData.items;
for (j = 0, len = ref1.length; j < len; j++) {
item = ref1[j];
if (item.type.match(/^text\/(plain|rtf|html)/)) {
_this.originalEvent.pastedTypes.push(item.type);
}
}
ref2 = clipboardData.items;
for (_i = k = 0, len1 = ref2.length; k < len1; _i = ++k) {
item = ref2[_i];
if (item.type.match(/^image\//)) {
reader = new FileReader();
reader.onload = function(event) {
return _this._handleImage(event.target.result, _this.originalEvent, pastedFilename);
};
try {
reader.readAsDataURL(item.getAsFile());
} catch (error) {}
ev.preventDefault();
break;
}
if (item.type === 'text/plain') {
if (_i === 0 && clipboardData.items.length > 1 && clipboardData.items[1].type.match(/^image\//)) {
stringIsFilename = true;
fileType = clipboardData.items[1].type;
}
item.getAsString(function(string) {
if (stringIsFilename) {
pastedFilename = string;
return _this._target.trigger('pasteText', {
text: string,
isFilename: true,
fileType: fileType,
originalEvent: _this.originalEvent
});
} else {
return _this._target.trigger('pasteText', {
text: string,
originalEvent: _this.originalEvent
});
}
});
}
if (item.type === 'text/rtf') {
item.getAsString(function(string) {
return _this._target.trigger('pasteTextRich', {
text: string,
originalEvent: _this.originalEvent
});
});
}
if (item.type === 'text/html') {
item.getAsString(function(string) {
return _this._target.trigger('pasteTextHtml', {
text: string,
originalEvent: _this.originalEvent
});
});
}
}
} else {
if (-1 !== Array.prototype.indexOf.call(clipboardData.types, 'text/plain')) {
text = clipboardData.getData('Text');
setTimeout(function() {
return _this._target.trigger('pasteText', {
text: text,
originalEvent: _this.originalEvent
});
}, 1);
}
_this._checkImagesInContainer(function(src) {
return _this._handleImage(src, _this.originalEvent);
});
}
}
if (clipboardData = window.clipboardData) {
if ((ref3 = (text = clipboardData.getData('Text'))) != null ? ref3.length : void 0) {
setTimeout(function() {
_this._target.trigger('pasteText', {
text: text,
originalEvent: _this.originalEvent
});
return _this._target.trigger('_pasteCheckContainerDone');
}, 1);
} else {
ref4 = clipboardData.files;
for (l = 0, len2 = ref4.length; l < len2; l++) {
file = ref4[l];
_this._handleImage(URL.createObjectURL(file), _this.originalEvent);
}
_this._checkImagesInContainer(function(src) {});
}
}
return null;
};
})(this));
}
Paste.prototype._handleImage = function(src, e, name) {
var loader;
if (src.match(/^webkit\-fake\-url\:\/\//)) {
return this._target.trigger('pasteImageError', {
message: "You are trying to paste an image in Safari, however we are unable to retieve its data."
});
}
this._target.trigger('pasteImageStart');
loader = new Image();
loader.crossOrigin = "anonymous";
loader.onload = (function(_this) {
return function() {
var blob, canvas, ctx, dataURL;
canvas = document.createElement('canvas');
canvas.width = loader.width;
canvas.height = loader.height;
ctx = canvas.getContext('2d');
ctx.drawImage(loader, 0, 0, canvas.width, canvas.height);
dataURL = null;
try {
dataURL = canvas.toDataURL('image/png');
blob = dataURLtoBlob(dataURL);
} catch (error) {}
if (dataURL) {
_this._target.trigger('pasteImage', {
blob: blob,
dataURL: dataURL,
width: loader.width,
height: loader.height,
originalEvent: e,
name: name
});
}
return _this._target.trigger('pasteImageEnd');
};
})(this);
loader.onerror = (function(_this) {
return function() {
_this._target.trigger('pasteImageError', {
message: "Failed to get image from: " + src,
url: src
});
return _this._target.trigger('pasteImageEnd');
};
})(this);
return loader.src = src;
};
Paste.prototype._checkImagesInContainer = function(cb) {
var img, j, len, ref, timespan;
timespan = Math.floor(1000 * Math.random());
ref = this._container.find('img');
for (j = 0, len = ref.length; j < len; j++) {
img = ref[j];
img["_paste_marked_" + timespan] = true;
}
return setTimeout((function(_this) {
return function() {
var k, len1, ref1;
ref1 = _this._container.find('img');
for (k = 0, len1 = ref1.length; k < len1; k++) {
img = ref1[k];
if (!img["_paste_marked_" + timespan]) {
cb(img.src);
$(img).remove();
}
}
return _this._target.trigger('_pasteCheckContainerDone');
};
})(this), 1);
};
return Paste;
})();
}).call(this);

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,8 @@
}
})
},
uploadComplete : function (file) {}
uploadComplete : function (attachment) {},
savePost : function (cb) {},
};
})(window);
@@ -377,7 +378,7 @@ function scrollableEditor(el, preview) {
// 表格选择插件
$.fn.tableSelectable = function (options) {
var table = this, s = $.extend({
const table = this, s = $.extend({
checkEl : null,
rowEl : null,
selectAllEl : null,
@@ -385,19 +386,13 @@ function scrollableEditor(el, preview) {
}, options);
function clickRow (t) {
var t = $(t), check = $(s.checkEl, t), checked = check.prop('checked');
const check = $(s.checkEl, t), checked = check.prop('checked');
if (!check.length) {
return;
}
check.prop('checked', !checked);
if (checked) {
t.removeClass('checked');
} else {
t.addClass('checked');
}
}
$(s.rowEl, this).each(function () {
@@ -405,9 +400,9 @@ function scrollableEditor(el, preview) {
clickRow($(this).parents(s.rowEl));
});
}).click(function (e) {
var target = $(e.toElement ? e.toElement : e.target),
const target = $(e.toElement ? e.toElement : e.target),
tagName = target.prop('tagName').toLowerCase();
if ($.inArray(tagName, ['input', 'textarea', 'a', 'button', 'i']) >= 0
&& 'checkbox' != target.attr('type')) {
e.stopPropagation();
@@ -417,27 +412,15 @@ function scrollableEditor(el, preview) {
});
$(s.selectAllEl).click(function () {
var t = $(this), checked = t.prop('checked');
if (checked) {
$(s.rowEl, table).each(function () {
var t = $(this), el = $(s.checkEl, this).prop('checked', true);
if (el.length > 0) {
t.addClass('checked');
}
});
} else {
$(s.rowEl, table).each(function () {
var t = $(this), el = $(s.checkEl, this).prop('checked', false);
if (el.length > 0) {
t.removeClass('checked');
}
});
}
const t = $(this), checked = t.prop('checked');
$(s.rowEl, table).each(function () {
$(s.checkEl, this).prop('checked', !!checked);
});
});
$(s.actionEl).click(function () {
var t = $(this), lang = t.attr('lang');
const t = $(this), lang = t.attr('lang');
if (!lang || confirm(lang)) {
table.parents('form').attr('action', t.attr('href')).submit();

View File

@@ -2,7 +2,7 @@
* Forms
*/
input[type=text], input[type=password], input[type=email],
input[type=text], input[type=url], input[type=password], input[type=email], input[type=number],
textarea {
background: #FFF;
border: 1px solid #D9D9D6;
@@ -22,7 +22,14 @@ textarea {
line-height: 1.5;
}
input[type="radio"], input[type="checkbox"] { margin-right: 3px; }
input[type="radio"], input[type="checkbox"] {
margin-right: 3px;
}
input[type="radio"], input[type="checkbox"],
input[type="radio"] + label, input[type="checkbox"] + label {
vertical-align: middle;
}
input, textarea {
&.text-s { padding: 5px; }

View File

@@ -13,9 +13,12 @@ $color-nav-child-focus: #6DA1BB;
.typecho-head-nav {
padding: 0 10px;
background: $color-nav-bg;
position: relative;
position: sticky;
top: 0;
display: flex;
z-index: 100;
a, button.menu-bar {
a, .menu-bar summary {
padding: 0 20px;
height: 36px;
line-height: 36px;
@@ -28,192 +31,213 @@ $color-nav-child-focus: #6DA1BB;
}
}
button.menu-bar {
.menu-bar {
display: none;
}
#typecho-nav-list {
float: left;
menu {
margin: 0;
padding: 0;
list-style: none;
background: $color-nav-bg;
}
& > ul {
list-style: none;
margin: 0;
padding: 0;
nav {
width: 100%;
& > menu {
display: flex;
position: relative;
float: left;
width: 100%;
&:first-child {
border-left: $border-nav;
}
& > li {
.parent {
a {
display: inline-block;
border-right: $border-nav;
background: $color-nav-bg;
&:first-child {
border-left: $border-nav;
}
}
.child {
position: absolute;
list-style: none;
top: 36px;
display: none;
margin: 0;
padding: 0;
min-width: 160px;
max-width: 240px;
background: $color-nav-btn-hover;
z-index: 250;
> a {
display: block;
border-right: $border-nav;
li {
&.return {
display: none;
}
&:hover, &:focus {
background: $color-nav-btn-hover;
a {
overflow: hidden;
text-overflow : ellipsis;
white-space: nowrap;
display: block;
&:hover,
&:focus {
background: $color-nav-bg;
& + menu {
display: flex;
}
}
}
&.focus a {
color: $color-nav-child-focus;
&:not(.operate) {
&.focus > a {
background: $color-nav-btn-hover;
font-weight: bold;
}
&:hover > a {
background: $color-nav-btn-hover;
}
}
}
.parent a:hover,
&.focus .parent a,
&.root:hover .parent a {
background: $color-nav-btn-hover;
}
&:hover, &:focus-within, &:focus {
menu {
display: flex;
}
}
&.focus .parent a {
font-weight: bold;
}
&.root:hover .child {
display: block;
}
}
}
.operate {
float: right;
a {
display: inline-block;
margin-left: -1px;
border: $border-nav;
border-width: 0 1px;
&:hover {
background-color: $color-nav-btn-hover;
}
}
}
}
@media (max-width: $screen-phone - 1px) {
@keyframes out {
from {left: 0%;}
to {left: -100%;}
}
@keyframes in {
from {left: -100%;}
to {left: 0%;}
}
.typecho-head-nav {
padding: 0;
position: fixed;
bottom: 0;
width: 100%;
z-index: 10;
#typecho-nav-list {
display: none;
}
.operate {
a:last-child {
border-right-width: 0;
}
}
button.menu-bar {
display: inline-block;
border: none;
background: $color-nav-bg;
border-right: $border-nav;
&.focus {
color: $color-nav-text-hover;
& + #typecho-nav-list {
display: block;
float: none;
menu {
position: absolute;
bottom: 36px;
width: 100%;
& > ul {
float: none;
border-bottom: $border-nav;
position: static;
top: 36px;
display: none;
flex-flow: column;
min-width: 160px;
max-width: 240px;
background: $color-nav-btn-hover;
z-index: 250;
& > li {
a {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
&:hover,
&:focus {
background: $color-nav-bg;
}
}
&.focus a {
color: $color-nav-child-focus;
font-weight: bold;
}
}
}
&.operate {
flex: 1;
display: flex;
justify-content: flex-end;
a {
&:hover {
background-color: $color-nav-btn-hover;
}
&:first-child {
border-left: none;
border-left: $border-nav;
}
.parent {
a {
display: block;
border: none;
background: $color-nav-btn-hover;
}
}
}
}
}
}
@include screen(phone, max) {
padding: 0;
flex-flow: column;
.menu-bar {
display: block;
font-size: 14px;
position: sticky;
top: 0;
background: $color-nav-bg;
z-index: 10;
summary {
cursor: pointer;
}
&[open] {
summary {
border-bottom: $border-nav;
}
& ~ menu {
display: flex;
}
}
}
nav {
overflow-y: auto;
width: 100vw;
position: fixed;
top: 0;
background: $color-nav-btn-hover;
&:has(.menu-bar[open]) {
width: 70vw;
height: 100%;
}
& > menu {
display: none;
flex-flow: column;
& > li {
&:first-child {
border: none;
}
> a {
border: none !important;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&:not(.operate) {
&.focus > a {
background: $color-nav-bg;
}
.child {
position: absolute;
bottom: 0;
left: 100%;
top: auto;
z-index: 20;
width: 100%;
max-width: 100%;
min-width: auto;
li {
border-bottom: $border-nav;
&.return {
display: block;
text-align: center;
font-size: 12px;
&:hover > a {
background: $color-nav-bg;
}
a {
color: $color-nav-text-mute;
}
}
}
& > a {
pointer-events: auto;
cursor: pointer;
}
}
&.expanded {
animation: out .15s ease-out forwards;
menu {
position: static;
border: $border-nav;
border-width: 1px 0;
display: flex;
min-width: auto;
max-width: none;
}
&.noexpanded {
animation: in .15s ease-out forwards;
&.operate {
flex-flow: column;
justify-content: flex-start;
a {
background: $color-nav-btn-hover;
&:hover {
background: $color-nav-bg;
}
}
}
}
}
}
}
}
@include screen(phone, max) {
body {
padding-top: 36px;
&:has(.menu-bar[open]) {
overflow: hidden;
}
}
}

View File

@@ -30,6 +30,10 @@
}
.success a { color: #264409; }
.warning {
color: #B94A48;
}
// 气泡
.balloon {
@@ -47,3 +51,28 @@
border-radius: 20px;
}
/** 顶部消息样式 by 70 */
.popup {
display: none;
position: sticky;
margin: 0;
padding: 8px 0;
border: none;
width: 100%;
z-index: 10;
text-align: center;
border-radius: 0;
ul {
list-style: none;
margin: 0;
padding: 0;
text-align: center;
li {
display: inline-block;
margin-right: 10px;
}
}
}

View File

@@ -0,0 +1,61 @@
/**
* 典型配置选项
*/
.typecho-option {
list-style: none;
margin: 1em 0;
padding: 0;
&-submit li {
border-bottom: none;
}
label {
&.typecho-label {
display: block;
margin-bottom: .5em;
font-weight: bold;
}
&.required:after {
content: " *";
color: #B94A48;
}
}
span {
margin-right: 15px;
}
.description {
margin: .5em 0 0;
color: #999;
font-size: .92857em;
}
input.file {
width: 100%;
margin: .7em 0;
}
input.text {
width: 100%;
}
input.num {
width: 60px;
}
textarea {
width: 100%;
height: 100px;
}
.multiline {
display: block;
margin: .3em 0;
&.hidden {
display: none;
}
}
}

View File

@@ -3,34 +3,35 @@
*/
.typecho-pager {
display: flex;
align-items: center;
justify-content: flex-end;
list-style: none;
float: right;
margin: 0;
padding: 0;
line-height: 1;
text-align: center;
zoom: 1;
}
.typecho-pager li {
display: inline-block;
margin: 0 3px;
height: 28px;
line-height: 28px;
}
li {
margin: 0 3px;
height: 28px;
line-height: 28px;
.typecho-pager a {
display: block;
padding: 0 10px;
border-radius: 2px;
}
a {
display: block;
padding: 0 10px;
border-radius: 2px;
.typecho-pager a:hover {
text-decoration: none;
background: #E9E9E6;
}
&:hover {
text-decoration: none;
background: #E9E9E6;
}
}
.typecho-pager li.current a {
background: #E9E9E6;
color: #444;
&.current a {
background: #E9E9E6;
color: #444;
}
}
}

175
admin/src/scss/_table.scss Normal file
View File

@@ -0,0 +1,175 @@
/**
* 表格列表页
*/
/**
* 列表页选项
*/
.typecho-list .typecho-pager {
}
.typecho-list-operate {
display: flex;
margin: 1em 0;
& + .typecho-list-operate {
margin-top: 0;
}
input, button, select {
vertical-align: bottom;
}
input[type="checkbox"] {
vertical-align: text-top;
}
a:hover {
text-decoration: none;
}
> *:nth-child(2) {
flex: 1;
}
.operate, .search {
display: flex;
align-items: center;
}
.operate {
label {
display: flex;
}
> * {
margin-right: 5px;
}
}
> *:nth-child(2) {
justify-content: flex-end;
&.search > * {
margin-left: 5px;
}
}
@include screen(phone, max) {
& {
flex-flow: column;
> *:nth-child(2) {
margin-top: 10px;
justify-content: flex-start;
> *:first-child {
margin-left: 0;
}
}
}
}
}
.operate-delete, .operate-button-delete {
color: #B94A48;
}
.operate-edit {
color: #007700;
}
.operate-reply {
color: #545c30;
}
/**
* 列表表格
*/
/** 增加表格标题 by 70 */
.typecho-list-table-title {
margin: 1em 0;
color: #999;
text-align: center;
}
.typecho-list-table {
width: 100%;
border-collapse: separate;
border-spacing: 0;
background: #FFF;
table-layout: fixed;
border: 30px solid #FFF;
&.deactivate {
color: #999;
}
.right {
text-align: right;
}
th {
padding: 0 10px 10px;
border-bottom: 1px solid #F0F0EC;
text-align: left;
}
td {
padding: 10px;
border-top: 1px solid #F0F0EC;
word-break: break-all;
pre {
overflow: auto;
}
&.none {
color: #999;
text-align: center;
}
}
.status {
margin-left: 5px;
color: #999;
font-size: .92857em;
font-style: normal;
}
tbody tr {
&:hover {
background-color: #F6F6F3;
}
&:has(input[type="checkbox"]:checked) {
background-color: #FFF9E8;
}
}
tr td .hidden-by-mouse {
opacity: 0;
}
tr:hover td .hidden-by-mouse {
opacity: 1;
}
tr td:first-child input[type="checkbox"] {
display: block;
}
@include screen(phone, max) {
& {
border-width: 10px;
th {
padding: 0 5px 5px;
}
td {
padding: 5px;
}
}
}
}

50
admin/src/scss/_tabs.scss Normal file
View File

@@ -0,0 +1,50 @@
/**
* 标签页
*/
.typecho-option-tabs {
list-style: none;
margin: 0;
padding: 0;
font-size: 13px;
display: flex;
&.fix-tabs {
margin: 1em 0;
}
li {
&:first-child a {
border-radius: 2px 0 0 2px;
}
&:last-child a {
border-radius: 0 2px 2px 0;
}
&.current a, &.active a {
background-color: #E9E9E6;
}
a {
display: flex;
justify-content: center;
align-items: center;
margin-right: -1px;
border: 1px solid #D9D9D6;
padding: 0 15px;
height: 26px;
color: #666;
box-sizing: border-box;
> * {
margin: 0 3px;
}
&:hover {
background-color: #E9E9E6;
color: #666;
text-decoration: none;
}
}
}
}

70
admin/src/scss/_tags.scss Normal file
View File

@@ -0,0 +1,70 @@
/**
* 标签列表
*/
.tag-list {
list-style: none;
margin: 0;
padding: 20px;
background-color: #FFF;
display: flex;
flex-wrap: wrap;
.none {
color: #999;
width: 100%;
margin: 0;
text-align: center;
}
&.typecho-list-notable li {
margin: 0 5px 5px 0;
padding: 5px 5px 5px 10px;
cursor: pointer;
display: flex;
align-items: center;
.tag-edit-link {
margin-left: 3px;
visibility: hidden;
display: flex;
align-items: center;
}
&:hover {
background-color: #E9E9E6;
.tag-edit-link {
visibility: visible;
}
}
&:has(input[type="checkbox"]:checked) {
background-color: #FFFBCC;
}
&.size-5 {
font-size: 1em;
}
&.size-10 {
font-size: 1.2em;
}
&.size-20 {
font-size: 1.4em;
}
&.size-30 {
font-size: 1.6em;
}
&.size-0 {
font-size: 1.8em;
}
input {
display: none;
}
}
}

View File

@@ -11,3 +11,29 @@ $screen-phone: 576px;
$screen-tablet: 768px;
$screen-desktop: 992px;
$screen-wide: 1200px;
@function breakpoint($breakpoint) {
@if $breakpoint == 'phone' {
@return $screen-phone;
} @else if $breakpoint == 'tablet' {
@return $screen-tablet;
} @else if $breakpoint == 'desktop' {
@return $screen-desktop;
} @else if $breakpoint == 'wide' {
@return $screen-wide;
} @else {
@return $breakpoint;
}
}
@mixin screen($breakpoint, $type: min) {
@if $type == min {
@media (min-width: breakpoint($breakpoint)) {
@content;
}
} @else {
@media (max-width: breakpoint($breakpoint) - 1) {
@content;
}
}
}

212
admin/src/scss/_write.scss Normal file
View File

@@ -0,0 +1,212 @@
/**
* 编写页面
*/
.typecho-post-area {
.edit-draft-notice {
color: #999;
font-size: .92857em;
a {
color: #B94A48;
}
}
.typecho-label {
display: block;
margin: 1em 0 -0.5em;
font-weight: bold;
}
.submit {
display: flex;
justify-content: space-between;
#auto-save-message {
color: #999;
font-size: .92857em;
}
.left {
display: flex;
align-items: center;
> * {
margin-right: 8px;
}
}
.right {
display: flex;
align-items: center;
justify-content: flex-end;
> * {
margin-left: 8px;
}
}
}
input.title {
font-size: 1.17em;
font-weight: bold;
}
.url-slug {
margin-top: -0.5em;
color: #AAA;
font-size: .92857em;
word-break: break-word;
}
#slug {
padding: 2px;
border: none;
background: #FFFBCC;
color: #666;
}
#text {
resize: none;
}
.description {
margin-top: -0.5em;
color: #999;
font-size: .92857em;
}
/**
* 自定义字段
*/
#custom-field {
margin: 1em 0;
padding: 10px 15px;
background: #FFF;
summary {
font-weight: bold;
cursor: pointer;
&:hover {
color: #467B96;
}
&::marker {
color: #BBB;
}
}
.add {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
.description {
margin-top: 0;
}
}
p.description {
text-align: left;
}
.typecho-label {
margin: 0;
a {
display: block;
color: #444;
&:hover {
color: #467B96;
text-decoration: none;
}
}
}
.fields {
list-style: none;
margin: 10px 0 0 0;
padding: 0;
.field {
display: flex;
padding-bottom: 10px;
border-bottom: 1px solid #F0F0EC;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
.field-name {
display: flex;
input[name="fieldNames[]"] {
height: 27px;
width: 150px;
margin-right: 10px;
}
}
.field-value {
margin-left: 10px;
flex: 1;
display: flex;
textarea[name="fieldValues[]"] {
flex: 1;
margin-right: 10px;
resize: none;
}
}
@include screen(phone, max) {
flex-flow: column;
.field-value {
margin-left: 0;
margin-top: 10px;
}
}
}
}
select { height: 27px; }
}
/**
* 侧边栏
*/
#edit-secondary {
margin-top: 1em;
.category-option ul {
list-style: none;
border: 1px solid #D9D9D6;
padding: 6px 12px;
max-height: 240px;
overflow: auto;
background-color: #FFF;
border-radius: 2px;
li {
margin: 3px 0;
}
}
#advance-panel {
summary {
line-height: 25px;
}
.visibility-option ul,
.allow-option ul {
list-style: none;
padding: 0;
}
}
}
}

View File

@@ -14,111 +14,121 @@
}
}
@media
(-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
@import "editor/*@2x.png";
@include all-editor-sprites();
#wmd-button-bar {
display: flex;
align-items: center;
@mixin editor-button-2x($name) {
&#wmd-#{$name}-button span {
@include editor-sprite(editor-#{$name})
@media
(-webkit-min-device-pixel-ratio: 2),
(min-resolution: 192dpi) {
@import "editor/*@2x.png";
@include all-editor-sprites();
@mixin editor-button-2x($name) {
&#wmd-#{$name}-button span {
@include editor-sprite(editor-#{$name})
}
}
.wmd-button-row {
li {
@include editor-button-2x(bold);
@include editor-button-2x(italic);
@include editor-button-2x(link);
@include editor-button-2x(quote);
@include editor-button-2x(code);
@include editor-button-2x(image);
@include editor-button-2x(olist);
@include editor-button-2x(ulist);
@include editor-button-2x(heading);
@include editor-button-2x(hr);
@include editor-button-2x(more);
@include editor-button-2x(undo);
@include editor-button-2x(redo);
@include editor-button-2x(fullscreen);
@include editor-button-2x(exit-fullscreen);
}
}
}
.wmd-button-row {
flex: 1;
list-style: none;
margin: 0;
padding: 0;
height: 26px;
line-height: 1;
li {
@include editor-button-2x(bold);
@include editor-button-2x(italic);
@include editor-button-2x(link);
@include editor-button-2x(quote);
@include editor-button-2x(code);
@include editor-button-2x(image);
@include editor-button-2x(olist);
@include editor-button-2x(ulist);
@include editor-button-2x(heading);
@include editor-button-2x(hr);
@include editor-button-2x(more);
@include editor-button-2x(undo);
@include editor-button-2x(redo);
@include editor-button-2x(fullscreen);
@include editor-button-2x(exit-fullscreen);
display: inline-block;
margin-right: 4px;
padding: 3px;
cursor: pointer;
vertical-align: middle;
border-radius: 2px;
&:hover {
background-color: #E9E9E6;
}
&.wmd-spacer {
height: 20px;
margin: 0 10px 0 6px;
padding: 0;
width: 1px;
background: #E9E9E6;
cursor: default;
}
span {
display: block;
width: 20px;
height: 20px;
}
@include editor-button(bold);
@include editor-button(italic);
@include editor-button(link);
@include editor-button(quote);
@include editor-button(code);
@include editor-button(image);
@include editor-button(olist);
@include editor-button(ulist);
@include editor-button(heading);
@include editor-button(hr);
@include editor-button(more);
@include editor-button(undo);
@include editor-button(redo);
@include editor-button(fullscreen);
@include editor-button(exit-fullscreen);
}
}
}
.wmd-button-row {
list-style: none;
margin: 0;
padding: 0;
height: 26px;
line-height: 1;
// 撰写预览切换 tab
.wmd-edittab {
font-size: .92857em;
li {
display: inline-block;
margin-right: 4px;
padding: 3px;
cursor: pointer;
vertical-align: middle;
border-radius: 2px;
&:hover {
background-color: #E9E9E6;
}
&.wmd-spacer {
a {
display: inline-block;
padding: 0 8px;
margin-left: 5px;
height: 20px;
margin: 0 10px 0 6px;
padding: 0;
width: 1px;
background: #E9E9E6;
cursor: default;
}
span {
display: block;
width: 20px;
height: 20px;
}
line-height: 20px;
@include editor-button(bold);
@include editor-button(italic);
@include editor-button(link);
@include editor-button(quote);
@include editor-button(code);
@include editor-button(image);
@include editor-button(olist);
@include editor-button(ulist);
@include editor-button(heading);
@include editor-button(hr);
@include editor-button(more);
@include editor-button(undo);
@include editor-button(redo);
@include editor-button(fullscreen);
@include editor-button(exit-fullscreen);
&:hover {
text-decoration: none;
}
&.active {
background: #E9E9E6;
color: #999;
}
}
}
}
#btn-cancel-preview { display: none }
// 撰写预览切换 tab
.wmd-edittab {
float: right;
margin-top: 3px;
font-size: .92857em;
a {
display: inline-block;
padding: 0 8px;
margin-left: 5px;
height: 20px;
line-height: 20px;
&:hover {
text-decoration: none;
}
&.active {
background: #E9E9E6;
color: #999;
}
}
}
// 控制被隐藏的 tab全屏时显示
.wmd-hidetab {
display: none;
@@ -152,6 +162,24 @@
button { margin-right: 10px; }
}
#wmd-editarea {
/* 拖动调整 textarea 大小 */
.resize {
display: block;
margin: 2px auto 0;
padding: 2px 0;
border: 1px solid #D9D9D6;
border-width: 1px 0;
width: 60px;
cursor: row-resize;
i {
display: block;
height: 1px;
background-color: #D9D9D6;
}
}
}
/* 预览 */
#wmd-preview {
background: #FFF;
@@ -318,7 +346,7 @@
#btn-cancel-preview { display: inline-block }
}
@media (max-width: $screen-phone - 1px) {
@include screen(phone, max) {
#wmd-spacer2,
#wmd-olist-button,
#wmd-ulist-button,

View File

@@ -1,20 +1,17 @@
/*
* Bento Grid System
* Bento Grid System (Flexbox Version)
* Source: https://github.com/fenbox/bento
* Version: 1.2.8
* Update: 2013.11.25
* Version: 2.0.0
* Update: 2024.10.23
*/
@import "vars";
// Mixins
%box-sizing {
box-sizing: border-box;
}
// Container
.container {
margin-left: auto;
@@ -22,189 +19,161 @@
padding-left: $gutter-width / 2;
padding-right: $gutter-width / 2;
@extend %box-sizing;
display: flex;
flex-wrap: wrap;
}
// Column group
.row {
margin-right: $gutter-width / -2;
margin-left: $gutter-width / -2;
@extend .clearfix;
display: flex;
flex-wrap: wrap;
width: 100vw;
}
.row [class*="col-"] {
float: left;
min-height: 1px;
padding-right: $gutter-width / 2;
padding-left: $gutter-width / 2;
min-height: 1px;
flex-grow: 1;
@extend %box-sizing;
}
// Flex order replaces push and pull functionality
.row [class*="-push-"],
.row [class*="-pull-"] {
position: relative;
}
/*
* Mobile and up
*/
// Use flex-grow to simulate columns in mobile
@for $index from 1 through $columns {
.col-mb-#{$index} {
width: $column-width * $index;
flex: 0 0 $column-width * $index;
max-width: $column-width * $index;
}
}
/*
* Tablet and up
*/
@media (min-width: $screen-tablet) {
// Tablet and up
@include screen(tablet) {
.container {
max-width: $screen-tablet - ($gutter-width * 2);
}
// Colunms
@for $index from 1 through $columns {
.col-tb-#{$index} {
width: $column-width * $index;
flex: 0 0 $column-width * $index;
max-width: $column-width * $index;
}
}
// Offset
@for $index from 0 through $columns {
.col-tb-offset-#{$index} {
margin-left: $column-width * $index;
}
}
// Pull
@for $index from 0 through $columns {
.col-tb-pull-#{$index} {
right: $column-width * $index;
order: -$index;
}
}
// Push
@for $index from 0 through $columns {
.col-tb-push-#{$index} {
left: $column-width * $index;
order: $index;
}
}
}
/*
* Desktop and up
*/
@media (min-width: $screen-desktop) {
// Desktop and up
@include screen(desktop) {
.container {
max-width: $screen-desktop - ($gutter-width * 2);
}
// Colunms
@for $index from 1 through $columns {
.col-#{$index} {
width: $column-width * $index;
flex: 0 0 $column-width * $index;
max-width: $column-width * $index;
}
}
// Offset
@for $index from 0 through $columns {
.col-offset-#{$index} {
margin-left: $column-width * $index;
}
}
// Pull
@for $index from 0 through $columns {
.col-pull-#{$index} {
right: $column-width * $index;
order: -$index;
}
}
// Push
@for $index from 0 through $columns {
.col-push-#{$index} {
left: $column-width * $index;
order: $index;
}
}
}
/*
* Widescreen and up
*/
@media (min-width: $screen-wide) {
// Widescreen and up
@include screen(wide) {
.container {
max-width: $screen-wide - ($gutter-width * 2);
}
// Colunms
@for $index from 1 through $columns {
.col-wd-#{$index} {
width: $column-width * $index;
flex: 0 0 $column-width * $index;
max-width: $column-width * $index;
}
}
// Offset
@for $index from 0 through $columns {
.col-wd-offset-#{$index} {
margin-left: $column-width * $index;
}
}
// Pull
@for $index from 0 through $columns {
.col-wd-pull-#{$index} {
right: $column-width * $index;
order: -$index;
}
}
// Push
@for $index from 0 through $columns {
.col-wd-push-#{$index} {
left: $column-width * $index;
order: $index;
}
}
}
/*
* Responsive kit
*/
// Hidden in mobile and down
@media (max-width: $screen-phone - 1px) {
// Responsive kit
@include screen(phone, max) {
.kit-hidden-mb {
display: none;
}
}
// Hidden in tablet and down
@media (max-width: $screen-tablet - 1px) {
@include screen(tablet, max) {
.kit-hidden-tb {
display: none;
}
}
// Hidden in descktop and down
@media (max-width: $screen-desktop - 1px) {
@include screen(desktop, max) {
.kit-hidden {
display: none;
}
}
/*
* Clearfix
*/
// Clearfix
.clearfix {
zoom: 1;
&:before, &:after {
&:before,
&:after {
content: " ";
display: table;
}

View File

@@ -19,7 +19,7 @@ html {
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;
background: #F6F6F3;
color: #444;
font-size: 87.5%;
@@ -74,38 +74,15 @@ a.button:hover, a.balloon-button:hover {
@import "buttons";
@import "messages";
@import "pagenavi";
@import "table";
@import "tabs";
@import "tags";
@import "write";
@import "options";
@import "header";
@import "footer";
/** 顶部消息样式 by 70 */
.popup {
display: none;
position: absolute;
top: 0;
left: 0;
margin: 0;
padding: 8px 0;
border: none;
width: 100%;
z-index: 10;
text-align: center;
border-radius: 0;
}
.popup ul {
list-style: none;
margin: 0;
padding: 0;
text-align: center;
}
.popup ul li {
display: inline-block;
margin-right: 10px;
}
/**
* logo 的样式
*/
@@ -120,46 +97,6 @@ a.button:hover, a.balloon-button:hover {
background: transparent url(../img/ajax-loader.gif) no-repeat left center;
}
/**
* 典型配置选项
*/
.typecho-option {
list-style: none;
margin: 1em 0;
padding: 0;
}
.typecho-option li {
}
.typecho-option-submit li {
border-bottom: none;
}
.typecho-option label.typecho-label {
display: block;
margin-bottom: .5em;
font-weight: bold;
}
.typecho-option label.required:after {
content: " *";
color: #B94A48;
}
.typecho-option label.typecho-label+input {
}
.typecho-option span { margin-right: 15px; }
.typecho-option .description {
margin: .5em 0 0;
color: #999;
font-size: .92857em;
}
.typecho-option input.file {
width: 100%;
margin: .7em 0;
}
.front-archive {
padding-left: 1.5em;
}
@@ -198,12 +135,17 @@ a.button:hover, a.balloon-button:hover {
margin-bottom: 25px;
padding: 0 0 35px;
border-bottom: 1px solid #ECECEC;
display: flex;
flex-wrap: wrap;
li {
float: left;
margin-right: 1.5em;
}
.balloon {
margin-top: 2px;
display: flex;
align-items: center;
.balloon {
margin-left: 5px;
}
}
}
@@ -235,43 +177,55 @@ a.button:hover, a.balloon-button:hover {
display: table;
margin: 0 auto;
height: 100%;
}
.typecho-login {
display: table-cell;
padding: 30px 0 100px;
width: 280px;
text-align: center;
vertical-align: middle;
h1 {
margin: 0 0 1em;
.typecho-login {
display: table-cell;
padding: 30px 0 100px;
width: 280px;
text-align: center;
vertical-align: middle;
h1 {
margin: 0 0 1em;
}
.more-link {
margin-top: 2em;
color: #CCC;
a {
margin: 0 3px;
}
}
}
}
.typecho-login .more-link {
margin-top: 2em;
color: #CCC;
}
.typecho-login .more-link a { margin: 0 3px; }
/**
* 标题
*/
.typecho-page-title {
}
.typecho-page-title h2 {
width: 100%;
display: flex;
align-items: center;
margin: 25px 0 10px;
font-size: 1.28571em;
}
.typecho-page-title h2 a {
margin-left: 10px;
padding: 3px 8px;
background: #E9E9E6;
font-size: .8em;
border-radius: 2px;
}
.typecho-page-title h2 a:hover {
text-decoration: none;
h2 {
margin: 0;
font-size: 1.28571em;
}
a {
padding: 3px 8px;
margin-left: 8px;
background: #E9E9E6;
font-size: .8em;
font-weight: bold;
border-radius: 2px;
&:hover {
text-decoration: none;
}
}
}
/**
@@ -283,190 +237,16 @@ a.button:hover, a.balloon-button:hover {
* 主页主体
*/
.typecho-dashboard {
}
.typecho-dashboard ul {
list-style: none;
padding: 0;
}
.typecho-dashboard li {
margin-bottom: 5px;
}
ul {
list-style: none;
padding: 0;
/**
* 标签页
*/
.typecho-option-tabs {
list-style: none;
margin: 1em 0 0;
padding: 0;
font-size: 13px;
text-align: center;
&.fix-tabs {
margin-bottom: 1em;
}
}
.typecho-option-tabs a {
display: block;
margin-right: -1px;
border: 1px solid #D9D9D6;
padding: 0 15px;
height: 26px;
line-height: 26px;
color: #666;
box-sizing: border-box;
}
.typecho-option-tabs a:hover {
background-color: #E9E9E6;
color: #666;
text-decoration: none;
}
.typecho-option-tabs li {
float: left;
&:first-child a {
border-radius: 2px 0 0 2px;
}
&:last-child a {
border-radius: 0 2px 2px 0;
}
}
.typecho-option-tabs.right {
float: right;
}
.typecho-option-tabs li.current a,
.typecho-option-tabs li.active a {
background-color: #E9E9E6;
}
/**
* 表格列表页
*/
/**
* 列表页选项
*/
.typecho-list .typecho-pager {
}
.typecho-list-operate {
margin: 1em 0;
}
.typecho-list-operate input,
.typecho-list-operate button,
.typecho-list-operate select {
vertical-align: bottom;
}
.typecho-list-operate input[type="checkbox"] {
vertical-align: text-top;
}
@media (min-width: $screen-phone) {
.typecho-list-operate {
.operate {
float: left;
}
.search {
float: right;
li {
margin-bottom: 5px;
}
}
}
.typecho-list-operate span.operate-delete, a.operate-delete,
.typecho-list-operate span.operate-button-delete, a.operate-button-delete {
color: #B94A48;
}
a.operate-edit {
color: #007700;
}
a.operate-reply {
color: #545c30;
}
.typecho-list-operate a:hover {
text-decoration: none;
}
/**
* 列表表格
*/
/** 增加表格标题 by 70 */
.typecho-list-table-title {
margin: 1em 0;
color: #999;
text-align: center;
}
.typecho-table-wrap {
padding: 30px;
background: #FFF;
}
.typecho-list-table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
&.deactivate {
color: #999;
}
.right {
text-align: right;
}
th {
padding: 0 10px 10px;
border-bottom: 2px solid #F0F0EC;
text-align: left;
}
td {
padding: 10px;
border-top: 1px solid #F0F0EC;
word-break: break-all;
pre {
overflow: auto;
}
}
.status {
margin-left: 5px;
color: #999;
font-size: .92857em;
font-style: normal;
}
tbody tr:hover td {
background-color: #F6F6F3;
}
tbody tr.checked td {
background-color: #FFF9E8;
}
tr td .hidden-by-mouse {
opacity: 0;
}
tr:hover td .hidden-by-mouse {
opacity: 1;
}
}
.warning {
color: #B94A48;
}
/**
* 评论管理
*/
@@ -502,6 +282,15 @@ a.operate-reply {
max-width: 100%;
}
@include screen(phone, max) {
.comment-edit {
display: flex;
flex-direction: column;
width: 90vw;
}
.comment-edit td:first-child { display: none; }
}
/**
* 评论回复
@@ -511,295 +300,57 @@ a.operate-reply {
display: none;
}
/**
* 模板列表
*/
.typecho-theme-list {
}
img {
margin: 1em 0;
max-width: 100%;
max-height: 240px;
}
.typecho-theme-list .theme-item {
}
cite {
font-style: normal;
color: #999;
}
.typecho-theme-list td {
}
.typecho-theme-list img {
margin: 1em 0;
max-width: 100%;
max-height: 240px;
}
.typecho-theme-list cite {
font-style: normal;
color: #999;
}
.typecho-theme-list tbody tr.current td {
background-color: #FFF9E8;
}
/**
* 后台配置项
*/
.typecho-page-main .typecho-option input.text {
width: 100%;
}
.typecho-page-main .typecho-option input.num {
width: 40px;
}
.typecho-page-main .typecho-option textarea {
width: 100%;
height: 100px;
}
.typecho-page-main .typecho-option .multiline {
display: block;
margin: .3em 0;
&.hidden {
display: none;
tbody tr.current td {
background-color: #FFF9E8;
}
}
/**
* 编辑模板
*/
.typecho-select-theme {
height: 25px;
line-height: 25px;
margin: 15px 0px;
}
.typecho-select-theme h5 {
color: #E47E00;
font-weight: bold;
float: left;
font-size: 14px;
width: 120px;
margin-right: 10px;
}
.typecho-select-theme select {
width: 150px;
}
/**
* 编辑模板(编辑详情)
*/
.typecho-edit-theme ul {
list-style: none;
margin: 0;
padding: 0;
}
.typecho-edit-theme li {
padding: 3px 10px;
}
.typecho-edit-theme .current {
background-color: #E6E6E3;
}
.typecho-edit-theme .current a {
color: #444;
}
.typecho-edit-theme textarea {
font-size: .92857em;
line-height: 1.2;
height: 500px;
}
/**
* 编写页面
*/
.typecho-post-area .edit-draft-notice {
color: #999;
font-size: .92857em;
}
.typecho-post-area .edit-draft-notice a { color: #B94A48; }
.typecho-post-area .typecho-label {
display: block;
margin: 1em 0 -0.5em;
font-weight: bold;
}
.typecho-post-area #auto-save-message {
display: block;
margin-top: 0.5em;
color: #999;
font-size: .92857em;
}
.typecho-post-area .submit .right button {
margin-left: 5px;
}
.typecho-post-area .right {
float: right;
}
.typecho-post-area .left {
float: left;
}
.typecho-post-area input.text {
}
.typecho-post-area .out-date {
border: 1px solid #D3DBB3;
padding: 3px;
background: #fff;
}
.typecho-post-area input.title {
font-size: 1.17em;
font-weight: bold;
}
.typecho-post-area .url-slug {
margin-top: -0.5em;
color: #AAA;
font-size: .92857em;
word-break: break-word;
}
.typecho-post-area #slug {
padding: 2px;
border: none;
background: #FFFBCC;
color: #666;
}
.typecho-post-area #text {
resize: none;
}
#advance-panel {
display: none;
}
#custom-field {
margin: 1em 0;
padding: 10px 15px;
background: #FFF;
&.fold {
table, .description { display: none; }
}
.description {
margin-top: 10px;
text-align: right;
button {
float: left;
}
}
p.description {
text-align: left;
}
.typecho-label {
.typecho-edit-theme {
ul {
list-style: none;
margin: 0;
padding: 0;
li {
padding: 3px 10px;
}
}
.current {
background-color: #E6E6E3;
a {
display: block;
color: #444;
&:hover {
color: #467B96;
text-decoration: none;
}
}
}
table {
margin-top: 10px;
}
td {
padding: 10px 5px;
textarea {
font-size: .92857em;
border-bottom: 1px solid #F0F0EC;
vertical-align: top;
label {
font-size: 1em;
font-weight: normal;
}
line-height: 1.2;
height: 500px;
}
select { height: 27px; }
}
.typecho-post-area .is-draft {
background: #FFF1A8;
}
.typecho-post-option .description {
margin-top: -0.5em;
color: #999;
font-size: .92857em;
}
.category-option ul {
list-style: none;
border: 1px solid #D9D9D6;
padding: 6px 12px;
max-height: 240px;
overflow: auto;
background-color: #FFF;
border-radius: 2px;
}
.category-option li {
margin: 3px 0;
}
.visibility-option ul,
.allow-option ul {
list-style: none;
padding: 0;
}
/**
* 标签列表
*/
.typecho-page-main ul.tag-list {
list-style: none;
margin: 0;
padding: 20px;
background-color: #FFF;
}
.typecho-page-main ul.tag-list li {
display: inline-block;
margin: 0 0 5px 0;
padding: 5px 5px 5px 10px;
cursor: pointer;
}
.typecho-page-main ul.tag-list li:hover {
background-color: #E9E9E6;
}
.typecho-page-main ul.tag-list li input {
display: none;
}
.typecho-page-main ul.tag-list li.checked {
background-color: #FFFBCC;
}
.typecho-page-main ul.tag-list li.size-5 { font-size: 1em; }
.typecho-page-main ul.tag-list li.size-10 { font-size: 1.2em; }
.typecho-page-main ul.tag-list li.size-20 { font-size: 1.4em; }
.typecho-page-main ul.tag-list li.size-30 { font-size: 1.6em; }
.typecho-page-main ul.tag-list li.size-0 { font-size: 1.8em; }
.typecho-page-main .tag-edit-link { visibility: hidden; }
.typecho-page-main li:hover .tag-edit-link { visibility: visible; }
.typecho-attachment-photo {
border: 1px solid #E6E6E3;
max-width: 100%;
@@ -863,39 +414,12 @@ background: #FFF1A8;
*/
.edit-media button { margin-right: 6px; }
/* 拖动调整 textarea 大小 */
.resize {
display: block;
margin: 2px auto 0;
padding: 2px 0;
border: 1px solid #D9D9D6;
border-width: 1px 0;
width: 60px;
cursor: row-resize;
i {
display: block;
height: 1px;
background-color: #D9D9D6;
}
}
/* 拖动排序 */
.tDnD_whileDrag {
background-color: #FFFBCC;
}
@media (max-width: $screen-phone - 1px) {
.typecho-list-operate {
.search {
margin-top: 10px;
}
}
.typecho-table-wrap {
padding: 10px;
margin: 0 -10px;
}
@include screen(phone, max) {
.typecho-option-submit {
button[type="submit"] {
width: 100%;

View File

@@ -1,4 +1,5 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<script src="<?php $options->adminStaticUrl('js', 'purify.js'); ?>"></script>
<script>
(function () {
$(document).ready(function () {

View File

@@ -6,60 +6,43 @@ include 'menu.php';
\Widget\Themes\Files::alloc()->to($files);
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12">
<ul class="typecho-option-tabs fix-tabs clearfix">
<li><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a></li>
<li class="current"><a href="<?php $options->adminUrl('theme-editor.php'); ?>">
<?php if ($options->theme == $files->theme): ?>
<?php _e('编辑当前外观'); ?>
<?php else: ?>
<?php _e('编辑%s外观', ' <cite>' . $files->theme . '</cite> '); ?>
<?php endif; ?>
</a></li>
<?php if (\Widget\Themes\Config::isExists()): ?>
<li><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
<?php endif; ?>
</ul>
</div>
<div class="typecho-edit-theme">
<div class="col-mb-12 col-tb-8 col-9 content">
<form method="post" name="theme" id="theme"
action="<?php $security->index('/action/themes-edit'); ?>">
<label for="content" class="sr-only"><?php _e('编辑源码'); ?></label>
<textarea name="content" id="content" class="w-100 mono"
<?php if (!$files->currentIsWriteable()): ?>readonly<?php endif; ?>><?php echo $files->currentContent(); ?></textarea>
<p class="typecho-option typecho-option-submit">
<?php if ($files->currentIsWriteable()): ?>
<input type="hidden" name="theme" value="<?php echo $files->currentTheme(); ?>"/>
<input type="hidden" name="edit" value="<?php echo $files->currentFile(); ?>"/>
<button type="submit" class="btn primary"><?php _e('保存文件'); ?></button>
<?php else: ?>
<em><?php _e('此文件无法写入'); ?></em>
<?php endif; ?>
</p>
</form>
</div>
<ul class="col-mb-12 col-tb-4 col-3">
<li><strong>模板文件</strong></li>
<?php while ($files->next()): ?>
<li<?php if ($files->current): ?> class="current"<?php endif; ?>>
<a href="<?php $options->adminUrl('theme-editor.php?theme=' . $files->currentTheme() . '&file=' . $files->file); ?>"><?php $files->file(); ?></a>
</li>
<?php endwhile; ?>
</ul>
<?php include 'theme-tabs.php'; ?>
<div class="row typecho-page-main typecho-edit-theme" role="main">
<div class="col-mb-12 col-tb-8 col-9 content">
<form method="post" name="theme" id="theme"
action="<?php $security->index('/action/themes-edit'); ?>">
<label for="content" class="sr-only"><?php _e('编辑源码'); ?></label>
<textarea name="content" id="content" class="w-100 mono"
<?php if (!$files->currentIsWriteable()): ?>readonly<?php endif; ?>><?php echo $files->currentContent(); ?></textarea>
<p class="typecho-option typecho-option-submit">
<?php if ($files->currentIsWriteable()): ?>
<input type="hidden" name="theme" value="<?php echo $files->currentTheme(); ?>"/>
<input type="hidden" name="edit" value="<?php echo $files->currentFile(); ?>"/>
<button type="submit" class="btn primary"><?php _e('保存文件'); ?></button>
<?php else: ?>
<em><?php _e('此文件无法写入'); ?></em>
<?php endif; ?>
</p>
</form>
</div>
<ul class="col-mb-12 col-tb-4 col-3">
<li><strong>模板文件</strong></li>
<?php while ($files->next()): ?>
<li<?php if ($files->current): ?> class="current"<?php endif; ?>>
<a href="<?php $options->adminUrl('theme-editor.php?theme=' . $files->currentTheme() . '&file=' . $files->file); ?>"><?php $files->file(); ?></a>
</li>
<?php endwhile; ?>
</ul>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';
include 'common-js.php';
\Typecho\Plugin::factory('admin/theme-editor.php')->bottom($files);
\Typecho\Plugin::factory('admin/theme-editor.php')->call('bottom', $files);
include 'footer.php';
?>

16
admin/theme-tabs.php Normal file
View File

@@ -0,0 +1,16 @@
<?php if (!defined('__TYPECHO_ADMIN__')) exit; ?>
<ul class="typecho-option-tabs fix-tabs">
<li<?php if ($menu->getCurrentMenuUrl() === 'themes.php'): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a></li>
<?php if (\Widget\Themes\Files::isWriteable()): ?>
<li<?php if ($menu->getCurrentMenuUrl() === 'theme-editor.php'): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('theme-editor.php'); ?>">
<?php if (!isset($files) || $options->theme == $files->theme): ?>
<?php _e('编辑当前外观'); ?>
<?php else: ?>
<?php _e('编辑%s外观', ' <cite>' . $files->theme . '</cite> '); ?>
<?php endif; ?>
</a></li>
<?php endif; ?>
<?php if (\Widget\Themes\Config::isExists()): ?>
<li<?php if ($menu->getCurrentMenuUrl() === 'options-theme.php'): ?> class="current"<?php endif; ?>><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
<?php endif; ?>
</ul>

View File

@@ -4,68 +4,67 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<?php include 'theme-tabs.php'; ?>
<div class="row typecho-page-main" role="main">
<div class="col-mb-12">
<ul class="typecho-option-tabs fix-tabs clearfix">
<li class="current"><a href="<?php $options->adminUrl('themes.php'); ?>"><?php _e('可以使用的外观'); ?></a>
</li>
<?php if (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__): ?>
<li><a href="<?php $options->adminUrl('theme-editor.php'); ?>"><?php _e('编辑当前外观'); ?></a></li>
<table class="typecho-list-table typecho-theme-list">
<colgroup>
<col width="35%"/>
<col/>
</colgroup>
<thead>
<th><?php _e('截图'); ?></th>
<th><?php _e('详情'); ?></th>
</thead>
<tbody>
<?php if ($options->missingTheme): ?>
<tr id="theme-<?php $options->missingTheme; ?>" class="current">
<td colspan="2" class="warning">
<p><strong><?php _e('检测到您之前使用的 "%s" 外观文件不存在,您可以重新上传此外观或者启用其他外观。', $options->missingTheme); ?></strong></p>
<ul>
<li><?php _e('重新上传此外观后刷新当前页面,此提示将会消失。'); ?></li>
<li><?php _e('启用新外观后,当前外观的设置数据将被删除。'); ?></li>
</ul>
</td>
</tr>
<?php endif; ?>
<?php if (\Widget\Themes\Config::isExists()): ?>
<li><a href="<?php $options->adminUrl('options-theme.php'); ?>"><?php _e('设置外观'); ?></a></li>
<?php endif; ?>
</ul>
<div class="typecho-table-wrap">
<table class="typecho-list-table typecho-theme-list">
<colgroup>
<col width="35%"/>
<col/>
</colgroup>
<thead>
<th><?php _e('截图'); ?></th>
<th><?php _e('详情'); ?></th>
</thead>
<tbody>
<?php \Widget\Themes\Rows::alloc()->to($themes); ?>
<?php while ($themes->next()): ?>
<tr id="theme-<?php $themes->name(); ?>"
class="<?php if ($themes->activated): ?>current<?php endif; ?>">
<td valign="top"><img src="<?php $themes->screen(); ?>"
alt="<?php $themes->name(); ?>"/></td>
<td valign="top">
<h3><?php '' != $themes->title ? $themes->title() : $themes->name(); ?></h3>
<cite>
<?php if ($themes->author): ?><?php _e('作者'); ?>: <?php if ($themes->homepage): ?><a href="<?php $themes->homepage() ?>"><?php endif; ?><?php $themes->author(); ?><?php if ($themes->homepage): ?></a><?php endif; ?> &nbsp;&nbsp;<?php endif; ?>
<?php if ($themes->version): ?><?php _e('版本'); ?>: <?php $themes->version() ?><?php endif; ?>
</cite>
<p><?php echo nl2br($themes->description); ?></p>
<?php if ($options->theme != $themes->name): ?>
<p>
<?php if (!defined('__TYPECHO_THEME_WRITEABLE__') || __TYPECHO_THEME_WRITEABLE__): ?>
<a class="edit"
href="<?php $options->adminUrl('theme-editor.php?theme=' . $themes->name); ?>"><?php _e('编辑'); ?></a> &nbsp;
<?php endif; ?>
<a class="activate"
href="<?php $security->index('/action/themes-edit?change=' . $themes->name); ?>"><?php _e('启用'); ?></a>
</p>
<?php endif; ?>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
<?php \Widget\Themes\Rows::alloc()->to($themes); ?>
<?php while ($themes->next()): ?>
<tr id="theme-<?php $themes->name(); ?>"
class="<?php if ($themes->activated && !$options->missingTheme): ?>current<?php endif; ?>">
<td valign="top"><img src="<?php $themes->screen(); ?>"
alt="<?php $themes->name(); ?>"/></td>
<td valign="top">
<h3><?php '' != $themes->title ? $themes->title() : $themes->name(); ?></h3>
<cite>
<?php if ($themes->author): ?><?php _e('作者'); ?>: <?php if ($themes->homepage): ?><a href="<?php $themes->homepage() ?>"><?php endif; ?><?php $themes->author(); ?><?php if ($themes->homepage): ?></a><?php endif; ?> &nbsp;&nbsp;<?php endif; ?>
<?php if ($themes->version): ?><?php _e('版本'); ?>: <?php $themes->version() ?><?php endif; ?>
</cite>
<p><?php echo nl2br($themes->description); ?></p>
<?php if ($options->theme != $themes->name || $options->missingTheme): ?>
<p>
<?php if (\Widget\Themes\Files::isWriteable()): ?>
<a class="edit"
href="<?php $options->adminUrl('theme-editor.php?theme=' . $themes->name); ?>"><?php _e('编辑'); ?></a> &nbsp;
<?php endif; ?>
<a class="activate"
href="<?php $security->index('/action/themes-edit?change=' . $themes->name); ?>"><?php _e('启用'); ?></a>
</p>
<?php endif; ?>
</td>
</tr>
<?php endwhile; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,7 +4,7 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
@@ -29,7 +29,7 @@ include 'menu.php';
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,7 +4,7 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="form">
@@ -13,7 +13,7 @@ include 'menu.php';
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -4,7 +4,7 @@ include 'header.php';
include 'menu.php';
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main" role="main">
@@ -16,9 +16,9 @@ include 'menu.php';
<li><a class="operate-delete" href="<?php $options->adminUrl('profile.php#change-password'); ?>"><?php _e('强烈建议更改你的默认密码'); ?></a></li>
<?php if($user->pass('contributor', true)): ?>
<li><a href="<?php $options->adminUrl('write-post.php'); ?>"><?php _e('撰写第一篇日志'); ?></a></li>
<li><a href="<?php $options->siteUrl(); ?>"><?php _e('查看我的站点'); ?></a></li>
<li><a href="<?php $options->siteUrl(); ?>"><?php $user->pass('administrator', true) ? _e('查看我的站点') : _e('查看网站'); ?></a></li>
<?php else: ?>
<li><a href="<?php $options->siteUrl(); ?>"><?php _e('查看我的站点'); ?></a></li>
<li><a href="<?php $options->siteUrl(); ?>"><?php _e('查看网站'); ?></a></li>
<?php endif; ?>
</ol>
<p><button type="submit" class="btn primary"><?php _e('让我直接开始使用吧 &raquo;'); ?></button></p>
@@ -27,7 +27,7 @@ include 'menu.php';
</div>
</div>
</div>
</div>
</main>
<?php
include 'copyright.php';

View File

@@ -1,5 +1,5 @@
<?php if(!defined('__TYPECHO_ADMIN__')) exit; ?>
<?php \Typecho\Plugin::factory('admin/write-js.php')->write(); ?>
<?php \Typecho\Plugin::factory('admin/write-js.php')->call('write'); ?>
<?php \Widget\Metas\Tag\Cloud::alloc('sort=count&desc=1&limit=200')->to($tags); ?>
<script src="<?php $options->adminStaticUrl('js', 'timepicker.js'); ?>"></script>
@@ -42,12 +42,12 @@ $(document).ready(function() {
Typecho.editorResize('text', '<?php $security->index('/action/ajax?do=editorResize'); ?>');
// tag autocomplete 提示
var tags = $('#tags'), tagsPre = [];
const tags = $('#tags'), tagsPre = [];
if (tags.length > 0) {
var items = tags.val().split(','), result = [];
for (var i = 0; i < items.length; i ++) {
var tag = items[i];
const items = tags.val().split(',');
for (let i = 0; i < items.length; i ++) {
const tag = items[i];
if (!tag) {
continue;
@@ -79,6 +79,9 @@ $(document).ready(function() {
prePopulate : tagsPre,
onResult : function (result, query, val) {
// remove special chars
val = val.replace(/<|>|&|"|'/g, '');
if (!query) {
return result;
}
@@ -87,7 +90,7 @@ $(document).ready(function() {
result = [];
}
if (!result[0] || result[0]['id'] != query) {
if (!result[0] || result[0]['id'] !== query) {
result.unshift({
id : val,
tags : val
@@ -100,17 +103,17 @@ $(document).ready(function() {
// tag autocomplete 提示宽度设置
$('#token-input-tags').focus(function() {
var t = $('.token-input-dropdown'),
const t = $('.token-input-dropdown'),
offset = t.outerWidth() - t.width();
t.width($('.token-input-list').outerWidth() - offset);
});
}
// 缩略名自适应宽度
var slug = $('#slug');
const slug = $('#slug');
if (slug.length > 0) {
var wrap = $('<div />').css({
const wrap = $('<div />').css({
'position' : 'relative',
'display' : 'inline-block'
}),
@@ -126,10 +129,10 @@ $(document).ready(function() {
'minWidth' : '5px',
'position' : 'absolute',
'width' : '100%'
})), originalWidth = slug.width();
}));
function justifySlugWidth() {
var val = slug.val();
const val = slug.val();
justifySlug.text(val.length > 0 ? val : ' ');
}
@@ -137,91 +140,111 @@ $(document).ready(function() {
justifySlugWidth();
}
// 原始的插入图片和文件
Typecho.insertFileToEditor = function (file, url, isImage) {
var textarea = $('#text'), sel = textarea.getSelection(),
html = isImage ? '<img src="' + url + '" alt="' + file + '" />'
: '<a href="' + url + '">' + file + '</a>',
offset = (sel ? sel.start : 0) + html.length;
textarea.replaceSelection(html);
textarea.setSelection(offset, offset);
};
var submitted = false, form = $('form[name=write_post],form[name=write_page]').submit(function () {
submitted = true;
}), formAction = form.attr('action'),
// 处理保存文章的逻辑
const form = $('form[name=write_post],form[name=write_page]'),
idInput = $('input[name=cid]'),
cid = idInput.val(),
draft = $('input[name=draft]'),
draftId = draft.length > 0 ? draft.val() : 0,
btnSave = $('#btn-save').removeAttr('name').removeAttr('value'),
btnSubmit = $('#btn-submit').removeAttr('name').removeAttr('value'),
btnPreview = $('#btn-preview'),
doAction = $('<input type="hidden" name="do" value="publish" />').appendTo(form),
locked = false,
autoSave = $('<span id="auto-save-message"></span>').prependTo('.left');
let cid = idInput.val(),
draftId = draft.length > 0 ? draft.val() : 0,
changed = false,
autoSave = $('<span id="auto-save-message" class="left"></span>').prependTo('.submit'),
written = false,
lastSaveTime = null;
$(':input', form).bind('input change', function (e) {
var tagName = $(this).prop('tagName');
if (tagName.match(/(input|textarea)/i) && e.type == 'change') {
return;
}
changed = true;
form.on('write', function () {
written = true;
form.trigger('datachange');
});
form.bind('field', function () {
changed = true;
form.on('change', function () {
if (written) {
form.trigger('datachange');
}
});
$('button[name=do]').click(function () {
$('input[name=do]').val($(this).val());
});
// 自动检测离开页
$(window).bind('beforeunload', function () {
if (changed && !form.hasClass('submitting')) {
return '<?php _e('内容已经改变尚未保存, 您确认要离开此页面吗?'); ?>';
}
});
// 发送保存请求
function saveData(cb) {
function callback(o) {
Typecho.savePost = function(cb) {
if (!changed) {
cb && cb();
return;
}
const callback = function (o) {
lastSaveTime = o.time;
cid = o.cid;
draftId = o.draftId;
idInput.val(cid);
autoSave.text('<?php _e('已保存'); ?>' + ' (' + o.time + ')').effect('highlight', 1000);
locked = false;
btnSave.removeAttr('disabled');
btnPreview.removeAttr('disabled');
if (!!cb) {
cb(o)
}
}
cb && cb();
};
changed = false;
btnSave.attr('disabled', 'disabled');
btnPreview.attr('disabled', 'disabled');
autoSave.text('<?php _e('正在保存'); ?>');
if (typeof FormData !== 'undefined') {
var data = new FormData(form.get(0));
data.append('do', 'save');
const data = new FormData(form.get(0));
data.append('do', 'save');
form.triggerHandler('submit');
$.ajax({
url: formAction,
processData: false,
contentType: false,
type: 'POST',
data: data,
success: callback
});
} else {
var data = form.serialize() + '&do=save';
$.post(formAction, data, callback, 'json');
$.ajax({
url: form.attr('action'),
processData: false,
contentType: false,
type: 'POST',
data: data,
success: callback,
error: function () {
autoSave.text('<?php _e('保存失败, 请重试'); ?>');
},
complete: function () {
form.trigger('submitted');
}
});
};
<?php if ($options->autoSave): ?>
// 自动保存
let saveTimer = null;
let stopAutoSave = false;
form.on('datachange', function () {
changed = true;
autoSave.text('<?php _e('尚未保存'); ?>' + (lastSaveTime ? ' (<?php _e('上次保存时间'); ?>: ' + lastSaveTime + ')' : ''));
if (saveTimer) {
clearTimeout(saveTimer);
}
}
saveTimer = setTimeout(function () {
!stopAutoSave && Typecho.savePost();
}, 3000);
}).on('submit', function () {
stopAutoSave = true;
}).on('submitted', function () {
stopAutoSave = false;
});
<?php else: ?>
form.on('datachange', function () {
changed = true;
});
<?php endif; ?>
// 计算夏令时偏移
var dstOffset = (function () {
var d = new Date(),
const dstOffset = (function () {
const d = new Date(),
jan = new Date(d.getFullYear(), 0, 1),
jul = new Date(d.getFullYear(), 6, 1),
stdOffset = Math.max(jan.getTimezoneOffset(), jul.getTimezoneOffset());
@@ -236,52 +259,16 @@ $(document).ready(function() {
// 时区
$('<input name="timezone" type="hidden" />').appendTo(form).val(- (new Date).getTimezoneOffset() * 60);
// 自动保存
<?php if ($options->autoSave): ?>
var autoSaveOnce = !!cid;
function autoSaveListener () {
setInterval(function () {
if (changed && !locked) {
locked = true;
saveData();
}
}, 10000);
}
if (autoSaveOnce) {
autoSaveListener();
}
$('#text').bind('input propertychange', function () {
if (!locked) {
autoSave.text('<?php _e('尚未保存'); ?>' + (lastSaveTime ? ' (<?php _e('上次保存时间'); ?>: ' + lastSaveTime + ')' : ''));
}
if (!autoSaveOnce) {
autoSaveOnce = true;
autoSaveListener();
}
});
<?php endif; ?>
// 自动检测离开页
$(window).bind('beforeunload', function () {
if (changed && !submitted) {
return '<?php _e('内容已经改变尚未保存, 您确认要离开此页面吗?'); ?>';
}
});
// 预览功能
var isFullScreen = false;
let isFullScreen = false;
function previewData(cid) {
isFullScreen = $(document.body).hasClass('fullscreen');
$(document.body).addClass('fullscreen preview');
var frame = $('<iframe frameborder="0" class="preview-frame preview-loading"></iframe>')
const frame = $('<iframe frameborder="0" class="preview-frame preview-loading"></iframe>')
.attr('src', './preview.php?cid=' + cid)
.attr('sandbox', 'allow-scripts')
.attr('sandbox', 'allow-same-origin allow-scripts')
.appendTo(document.body);
frame.load(function () {
@@ -292,36 +279,28 @@ $(document).ready(function() {
}
function cancelPreview() {
if (submitted) {
return;
}
if (!isFullScreen) {
$(document.body).removeClass('fullscreen');
}
$(document.body).removeClass('preview');
$('.preview-frame').remove();
};
}
$('#btn-cancel-preview').click(cancelPreview);
$(window).bind('message', function (e) {
if (e.originalEvent.data == 'cancelPreview') {
if (e.originalEvent.data === 'cancelPreview') {
cancelPreview();
}
});
btnPreview.click(function () {
if (changed) {
locked = true;
if (confirm('<?php _e('修改后的内容需要保存后才能预览, 是否保存?'); ?>')) {
saveData(function (o) {
previewData(o.draftId);
Typecho.savePost(function () {
previewData(draftId);
});
} else {
locked = false;
}
} else if (!!draftId) {
previewData(draftId);
@@ -330,43 +309,22 @@ $(document).ready(function() {
}
});
btnSave.click(function () {
doAction.attr('value', 'save');
});
btnSubmit.click(function () {
doAction.attr('value', 'publish');
});
// 控制选项和附件的切换
var fileUploadInit = false;
$('#edit-secondary .typecho-option-tabs li').click(function() {
$('#edit-secondary .typecho-option-tabs li').removeClass('active');
$(this).addClass('active');
$(this).parents('#edit-secondary').find('.tab-content').addClass('hidden');
var selected_tab = $(this).find('a').attr('href'),
selected_el = $(selected_tab).removeClass('hidden');
$('#edit-secondary .typecho-option-tabs li.active').removeClass('active');
$('#edit-secondary .tab-content').addClass('hidden');
if (!fileUploadInit) {
selected_el.trigger('init');
fileUploadInit = true;
}
const activeTab = $(this).addClass('active').find('a').attr('href');
$(activeTab).removeClass('hidden');
return false;
});
// 高级选项控制
$('#advance-panel-btn').click(function() {
$('#advance-panel').toggle();
return false;
});
// 自动隐藏密码框
$('#visibility').change(function () {
var val = $(this).val(), password = $('#post-password');
const val = $(this).val(), password = $('#post-password');
if ('password' == val) {
if ('password' === val) {
password.removeClass('hidden');
} else {
password.addClass('hidden');

View File

@@ -2,164 +2,201 @@
include 'common.php';
include 'header.php';
include 'menu.php';
\Widget\Contents\Page\Edit::alloc()->to($page);
$page = \Widget\Contents\Page\Edit::alloc()->prepare();
$parentPageId = $page->getParent();
$parentPages = [0 => _t('不选择')];
$parents = \Widget\Contents\Page\Admin::allocWithAlias(
'options',
'ignoreRequest=1' . ($request->is('cid') ? '&ignore=' . $request->get('cid') : '')
);
while ($parents->next()) {
$parentPages[$parents->cid] = str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $parents->levels) . $parents->title;
}
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main typecho-post-area" role="form">
<form action="<?php $security->index('/action/contents-page-edit'); ?>" method="post" name="write_page">
<div class="col-mb-12 col-tb-9" role="main">
<?php if ($page->draft): ?>
<?php if ($page->draft['cid'] != $page->cid): ?>
<?php $pageModifyDate = new \Typecho\Date($page->draft['modified']); ?>
<cite
class="edit-draft-notice"><?php _e('当前正在编辑的是保存于%s的草稿, 你可以<a href="%s">删除它</a>', $pageModifyDate->word(),
$security->getIndex('/action/contents-page-edit?do=deleteDraft&cid=' . $page->cid)); ?></cite>
<?php else: ?>
<cite class="edit-draft-notice"><?php _e('当前正在编辑的是未发布的草稿'); ?></cite>
<?php endif; ?>
<input name="draft" type="hidden" value="<?php echo $page->draft['cid'] ?>"/>
<form class="row typecho-page-main typecho-post-area" action="<?php $security->index('/action/contents-page-edit'); ?>" method="post" name="write_page">
<div class="col-mb-12 col-tb-9" role="main">
<?php if ($page->draft): ?>
<?php if ($page->draft['cid'] != $page->cid): ?>
<?php $pageModifyDate = new \Typecho\Date($page->draft['modified']); ?>
<cite
class="edit-draft-notice"><?php _e('你正在编辑的是保存于 %s 的修订版, 你也可以 <a href="%s">删除它</a>', $pageModifyDate->word(),
$security->getIndex('/action/contents-page-edit?do=deleteDraft&cid=' . $page->cid)); ?></cite>
<?php else: ?>
<cite class="edit-draft-notice"><?php _e('当前正在编辑的是未发布的草稿'); ?></cite>
<?php endif; ?>
<input name="draft" type="hidden" value="<?php echo $page->draft['cid'] ?>"/>
<?php endif; ?>
<p class="title">
<label for="title" class="sr-only"><?php _e('标题'); ?></label>
<input type="text" id="title" name="title" autocomplete="off" value="<?php $page->title(); ?>"
placeholder="<?php _e('标题'); ?>" class="w-100 text title"/>
</p>
<?php $permalink = \Typecho\Common::url($options->routingTable['page']['url'], $options->index);
[$scheme, $permalink] = explode(':', $permalink, 2);
$permalink = ltrim($permalink, '/');
$permalink = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $permalink);
if ($page->have()) {
$permalink = str_replace('{cid}', $page->cid, $permalink);
}
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($page->slug) . '" class="mono" />';
?>
<p class="mono url-slug">
<label for="slug" class="sr-only"><?php _e('网址缩略名'); ?></label>
<?php echo preg_replace("/\{slug\}/i", $input, $permalink); ?>
</p>
<p>
<label for="text" class="sr-only"><?php _e('页面内容'); ?></label>
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text"
name="text" class="w-100 mono"><?php echo htmlspecialchars($page->text); ?></textarea>
</p>
<p class="title">
<label for="title" class="sr-only"><?php _e('标题'); ?></label>
<input type="text" id="title" name="title" autocomplete="off" value="<?php $page->title(); ?>"
placeholder="<?php _e('标题'); ?>" class="w-100 text title"/>
</p>
<?php $permalink = \Typecho\Common::url($options->routingTable['page']['url'], $options->index);
[$scheme, $permalink] = explode(':', $permalink, 2);
$permalink = ltrim($permalink, '/');
$permalink = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $permalink);
if ($page->have()) {
$permalink = preg_replace_callback(
"/\{(cid)\}/i",
function ($matches) use ($page) {
$key = $matches[1];
return $page->getRouterParam($key);
},
$permalink
);
}
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($page->slug ?? '') . '" class="mono" />';
?>
<p class="mono url-slug">
<label for="slug" class="sr-only"><?php _e('网址缩略名'); ?></label>
<?php echo preg_replace_callback("/\{(slug|directory)\}/i", function ($matches) use ($input) {
if ($matches[1] == 'slug') {
return $input;
} else {
return '{directory/' . $input . '}';
}
}, $permalink); ?>
</p>
<p>
<label for="text" class="sr-only"><?php _e('页面内容'); ?></label>
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text"
name="text" class="w-100 mono"><?php echo htmlspecialchars($page->text); ?></textarea>
</p>
<?php include 'custom-fields.php'; ?>
<p class="submit clearfix">
<span class="left">
<button type="button" id="btn-cancel-preview" class="btn"><i
class="i-caret-left"></i> <?php _e('取消预览'); ?></button>
</span>
<span class="right">
<input type="hidden" name="cid" value="<?php $page->cid(); ?>"/>
<button type="button" id="btn-preview" class="btn"><i
class="i-exlink"></i> <?php _e('预览页面'); ?></button>
<button type="submit" name="do" value="save" id="btn-save"
class="btn"><?php _e('保存草稿'); ?></button>
<button type="submit" name="do" value="publish" class="btn primary"
id="btn-submit"><?php _e('发布页面'); ?></button>
<?php if ($options->markdown && (!$page->have() || $page->isMarkdown)): ?>
<input type="hidden" name="markdown" value="1"/>
<?php endif; ?>
</span>
</p>
<?php include 'custom-fields.php'; ?>
<p class="submit">
<span class="left">
<button type="button" id="btn-cancel-preview" class="btn"><i
class="i-caret-left"></i> <?php _e('取消预览'); ?></button>
</span>
<span class="right">
<input type="hidden" name="do" value="publish" />
<input type="hidden" name="cid" value="<?php $page->cid(); ?>"/>
<button type="button" id="btn-preview" class="btn"><i
class="i-exlink"></i> <?php _e('预览页面'); ?></button>
<button type="submit" name="do" value="save" id="btn-save"
class="btn"><?php _e('保存草稿'); ?></button>
<button type="submit" name="do" value="publish" class="btn primary"
id="btn-submit"><?php _e('发布页面'); ?></button>
<?php if ($options->markdown && (!$page->have() || $page->isMarkdown)): ?>
<input type="hidden" name="markdown" value="1"/>
<?php endif; ?>
</span>
</p>
<?php \Typecho\Plugin::factory('admin/write-page.php')->content($page); ?>
</div>
<div id="edit-secondary" class="col-mb-12 col-tb-3" role="complementary">
<ul class="typecho-option-tabs clearfix">
<li class="active w-50"><a href="#tab-advance"><?php _e('选项'); ?></a></li>
<li class="w-50"><a href="#tab-files" id="tab-files-btn"><?php _e('附件'); ?></a></li>
</ul>
<?php \Typecho\Plugin::factory('admin/write-page.php')->call('content', $page); ?>
</div>
<div id="edit-secondary" class="col-mb-12 col-tb-3" role="complementary">
<ul class="typecho-option-tabs">
<li class="active w-50"><a href="#tab-advance"><?php _e('选项'); ?></a></li>
<li class="w-50"><a href="#tab-files" id="tab-files-btn"><?php _e('附件'); ?></a></li>
</ul>
<div id="tab-advance" class="tab-content">
<section class="typecho-post-option" role="application">
<label for="date" class="typecho-label"><?php _e('发布日期'); ?></label>
<p><input class="typecho-date w-100" type="text" name="date" id="date" autocomplete="off"
value="<?php $page->have() && $page->created > 0 ? $page->date('Y-m-d H:i') : ''; ?>"/>
</p>
</section>
<div id="tab-advance" class="tab-content">
<section class="typecho-post-option" role="application">
<label for="date" class="typecho-label"><?php _e('发布日期'); ?></label>
<p><input class="typecho-date w-100" type="text" name="date" id="date" autocomplete="off"
value="<?php $page->have() && $page->created > 0 ? $page->date('Y-m-d H:i') : ''; ?>"/>
</p>
</section>
<section class="typecho-post-option">
<label for="order" class="typecho-label"><?php _e('页面顺序'); ?></label>
<p><input type="text" id="order" name="order" value="<?php $page->order(); ?>"
class="w-100"/></p>
<p class="description"><?php _e('为你的自定义页面设定一个序列值以后, 能够使得它们按此值从小到大排列'); ?></p>
</section>
<section class="typecho-post-option">
<label for="order" class="typecho-label"><?php _e('页面顺序'); ?></label>
<p><input type="number" id="order" name="order" value="<?php $page->order(); ?>"
class="w-100"/></p>
<p class="description"><?php _e('为你的自定义页面设定一个序列值以后, 能够使得它们按此值从小到大排列'); ?></p>
</section>
<section class="typecho-post-option">
<label for="template" class="typecho-label"><?php _e('自定义模板'); ?></label>
<section class="typecho-post-option">
<label for="template" class="typecho-label"><?php _e('自定义模板'); ?></label>
<p>
<select name="template" id="template">
<option value=""><?php _e('不选择'); ?></option>
<?php $templates = $page->getTemplates();
foreach ($templates as $template => $name): ?>
<option
value="<?php echo $template; ?>"<?php if ($template == $page->template): ?> selected="true"<?php endif; ?>><?php echo $name; ?></option>
<?php endforeach; ?>
</select>
</p>
<p class="description"><?php _e('如果你为此页面选择了一个自定义模板, 系统将按照你选择的模板文件展现它'); ?></p>
</section>
<section class="typecho-post-option">
<label for="parent" class="typecho-label"><?php _e('父级页面'); ?></label>
<p>
<select name="parent" id="parent">
<?php foreach ($parentPages as $pageId => $pageTitle): ?>
<option
value="<?php echo $pageId; ?>"<?php if ($pageId == ($page->parent ?? $parentPageId)): ?> selected="true"<?php endif; ?>><?php echo $pageTitle; ?></option>
<?php endforeach; ?>
</select>
</p>
<p class="description"><?php _e('如果你设定了父级页面, 此页面将作为子页面呈现'); ?></p>
</section>
<?php \Typecho\Plugin::factory('admin/write-page.php')->call('option', $page); ?>
<details id="advance-panel">
<summary class="btn btn-xs"><?php _e('高级选项'); ?> <i class="i-caret-down"></i></summary>
<section class="typecho-post-option visibility-option">
<label for="visibility" class="typecho-label"><?php _e('公开度'); ?></label>
<p>
<select name="template" id="template">
<option value=""><?php _e('不选择'); ?></option>
<?php $templates = $page->getTemplates();
foreach ($templates as $template => $name): ?>
<option
value="<?php echo $template; ?>"<?php if ($template == $page->template): ?> selected="true"<?php endif; ?>><?php echo $name; ?></option>
<?php endforeach; ?>
<select id="visibility" name="visibility">
<option
value="publish"<?php if ($page->status == 'publish' || !$page->status): ?> selected<?php endif; ?>><?php _e('公开'); ?></option>
<option
value="hidden"<?php if ($page->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
</select>
</p>
<p class="description"><?php _e('如果你为此页面选择了一个自定义模板, 系统将按照你选择的模板文件展现它'); ?></p>
</section>
<?php \Typecho\Plugin::factory('admin/write-page.php')->option($page); ?>
<section class="typecho-post-option allow-option">
<label class="typecho-label"><?php _e('权限控制'); ?></label>
<ul>
<li><input id="allowComment" name="allowComment" type="checkbox" value="1"
<?php if ($page->allow('comment')): ?>checked="true"<?php endif; ?> />
<label for="allowComment"><?php _e('允许评论'); ?></label></li>
<li><input id="allowPing" name="allowPing" type="checkbox" value="1"
<?php if ($page->allow('ping')): ?>checked="true"<?php endif; ?> />
<label for="allowPing"><?php _e('允许被引用'); ?></label></li>
<li><input id="allowFeed" name="allowFeed" type="checkbox" value="1"
<?php if ($page->allow('feed')): ?>checked="true"<?php endif; ?> />
<label for="allowFeed"><?php _e('允许在聚合中出现'); ?></label></li>
</ul>
</section>
<button type="button" id="advance-panel-btn" class="btn btn-xs"><?php _e('高级选项'); ?> <i
class="i-caret-down"></i></button>
<div id="advance-panel">
<section class="typecho-post-option visibility-option">
<label for="visibility" class="typecho-label"><?php _e('公开度'); ?></label>
<p>
<select id="visibility" name="visibility">
<option
value="publish"<?php if ($page->status == 'publish' || !$page->status): ?> selected<?php endif; ?>><?php _e('公开'); ?></option>
<option
value="hidden"<?php if ($page->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
</select>
</p>
</section>
<?php \Typecho\Plugin::factory('admin/write-page.php')->call('advanceOption', $page); ?>
</details>
<?php if ($page->have()): ?>
<?php $modified = new \Typecho\Date($page->modified); ?>
<section class="typecho-post-option">
<p class="description">
<br>&mdash;<br>
<?php _e('本页面由 <a href="%s">%s</a> 创建',
\Typecho\Common::url('manage-pages.php?uid=' . $page->author->uid, $options->adminUrl), $page->author->screenName); ?>
<br>
<?php _e('最后更新于 %s', $modified->word()); ?>
</p>
</section>
<?php endif; ?>
</div><!-- end #tab-advance -->
<section class="typecho-post-option allow-option">
<label class="typecho-label"><?php _e('权限控制'); ?></label>
<ul>
<li><input id="allowComment" name="allowComment" type="checkbox" value="1"
<?php if ($page->allow('comment')): ?>checked="true"<?php endif; ?> />
<label for="allowComment"><?php _e('允许评论'); ?></label></li>
<li><input id="allowPing" name="allowPing" type="checkbox" value="1"
<?php if ($page->allow('ping')): ?>checked="true"<?php endif; ?> />
<label for="allowPing"><?php _e('允许被引用'); ?></label></li>
<li><input id="allowFeed" name="allowFeed" type="checkbox" value="1"
<?php if ($page->allow('feed')): ?>checked="true"<?php endif; ?> />
<label for="allowFeed"><?php _e('允许在聚合中出现'); ?></label></li>
</ul>
</section>
<?php \Typecho\Plugin::factory('admin/write-page.php')->advanceOption($page); ?>
</div>
<?php if ($page->have()): ?>
<?php $modified = new \Typecho\Date($page->modified); ?>
<section class="typecho-post-option">
<p class="description">
<br>&mdash;<br>
<?php _e('本页面由 <a href="%s">%s</a> 创建',
\Typecho\Common::url('manage-pages.php?uid=' . $page->author->uid, $options->adminUrl), $page->author->screenName); ?>
<br>
<?php _e('最后更新于 %s', $modified->word()); ?>
</p>
</section>
<?php endif; ?>
</div><!-- end #tab-advance -->
<div id="tab-files" class="tab-content hidden">
<?php include 'file-upload.php'; ?>
</div><!-- end #tab-files -->
</div>
</form>
</div>
<div id="tab-files" class="tab-content hidden">
<?php include 'file-upload.php'; ?>
</div><!-- end #tab-files -->
</div>
</form>
</div>
</div>
</main>
<?php
include 'copyright.php';
@@ -167,7 +204,7 @@ include 'common-js.php';
include 'form-js.php';
include 'write-js.php';
\Typecho\Plugin::factory('admin/write-page.php')->trigger($plugged)->richEditor($page);
\Typecho\Plugin::factory('admin/write-page.php')->trigger($plugged)->call('richEditor', $page);
if (!$plugged) {
include 'editor-js.php';
}

View File

@@ -2,201 +2,198 @@
include 'common.php';
include 'header.php';
include 'menu.php';
\Widget\Contents\Post\Edit::alloc()->to($post);
$post = \Widget\Contents\Post\Edit::alloc()->prepare();
?>
<div class="main">
<main class="main">
<div class="body container">
<?php include 'page-title.php'; ?>
<div class="row typecho-page-main typecho-post-area" role="form">
<form action="<?php $security->index('/action/contents-post-edit'); ?>" method="post" name="write_post">
<div class="col-mb-12 col-tb-9" role="main">
<?php if ($post->draft): ?>
<?php if ($post->draft['cid'] != $post->cid): ?>
<?php $postModifyDate = new \Typecho\Date($post->draft['modified']); ?>
<cite
class="edit-draft-notice"><?php _e('你正在编辑的是保存于 %s 的草稿, 你也可以 <a href="%s">删除它</a>', $postModifyDate->word(),
$security->getIndex('/action/contents-post-edit?do=deleteDraft&cid=' . $post->cid)); ?></cite>
<?php else: ?>
<cite class="edit-draft-notice"><?php _e('当前正在编辑的是未发布的草稿'); ?></cite>
<?php endif; ?>
<input name="draft" type="hidden" value="<?php echo $post->draft['cid'] ?>"/>
<form class="row typecho-page-main typecho-post-area" action="<?php $security->index('/action/contents-post-edit'); ?>" method="post" name="write_post">
<div class="col-mb-12 col-tb-9" role="main">
<?php if ($post->draft): ?>
<?php if ($post->draft['cid'] != $post->cid): ?>
<?php $postModifyDate = new \Typecho\Date($post->draft['modified']); ?>
<cite
class="edit-draft-notice"><?php _e('你正在编辑的是保存于 %s 的修订版, 你也可以 <a href="%s">删除它</a>', $postModifyDate->word(),
$security->getIndex('/action/contents-post-edit?do=deleteDraft&cid=' . $post->cid)); ?></cite>
<?php else: ?>
<cite class="edit-draft-notice"><?php _e('当前正在编辑的是未发布的草稿'); ?></cite>
<?php endif; ?>
<input name="draft" type="hidden" value="<?php echo $post->draft['cid'] ?>"/>
<?php endif; ?>
<p class="title">
<label for="title" class="sr-only"><?php _e('标题'); ?></label>
<input type="text" id="title" name="title" autocomplete="off" value="<?php $post->title(); ?>"
placeholder="<?php _e('标题'); ?>" class="w-100 text title"/>
</p>
<?php $permalink = \Typecho\Common::url($options->routingTable['post']['url'], $options->index);
[$scheme, $permalink] = explode(':', $permalink, 2);
$permalink = ltrim($permalink, '/');
$permalink = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $permalink);
if ($post->have()) {
$permalink = str_replace([
'{cid}', '{category}', '{year}', '{month}', '{day}'
], [
$post->cid, $post->category, $post->year, $post->month, $post->day
], $permalink);
}
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($post->slug) . '" class="mono" />';
?>
<p class="mono url-slug">
<label for="slug" class="sr-only"><?php _e('网址缩略名'); ?></label>
<?php echo preg_replace("/\{slug\}/i", $input, $permalink); ?>
</p>
<p>
<label for="text" class="sr-only"><?php _e('文章内容'); ?></label>
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text"
name="text" class="w-100 mono"><?php echo htmlspecialchars($post->text); ?></textarea>
</p>
<p class="title">
<label for="title" class="sr-only"><?php _e('标题'); ?></label>
<input type="text" id="title" name="title" autocomplete="off" value="<?php $post->title(); ?>"
placeholder="<?php _e('标题'); ?>" class="w-100 text title"/>
</p>
<?php $permalink = \Typecho\Common::url($options->routingTable['post']['url'], $options->index);
[$scheme, $permalink] = explode(':', $permalink, 2);
$permalink = ltrim($permalink, '/');
$permalink = preg_replace("/\[([_a-z0-9-]+)[^\]]*\]/i", "{\\1}", $permalink);
if ($post->have()) {
$permalink = preg_replace_callback(
"/\{(cid|category|year|month|day)\}/i",
function ($matches) use ($post) {
$key = $matches[1];
return $post->getRouterParam($key);
},
$permalink
);
}
$input = '<input type="text" id="slug" name="slug" autocomplete="off" value="' . htmlspecialchars($post->slug ?? '') . '" class="mono" />';
?>
<p class="mono url-slug">
<label for="slug" class="sr-only"><?php _e('网址缩略名'); ?></label>
<?php echo preg_replace("/\{slug\}/i", $input, $permalink); ?>
</p>
<p>
<label for="text" class="sr-only"><?php _e('文章内容'); ?></label>
<textarea style="height: <?php $options->editorSize(); ?>px" autocomplete="off" id="text"
name="text" class="w-100 mono"><?php echo htmlspecialchars($post->text); ?></textarea>
</p>
<?php include 'custom-fields.php'; ?>
<?php include 'custom-fields.php'; ?>
<p class="submit clearfix">
<span class="left">
<button type="button" id="btn-cancel-preview" class="btn"><i
class="i-caret-left"></i> <?php _e('取消预览'); ?></button>
</span>
<span class="right">
<input type="hidden" name="cid" value="<?php $post->cid(); ?>"/>
<button type="button" id="btn-preview" class="btn"><i
class="i-exlink"></i> <?php _e('预览文章'); ?></button>
<button type="submit" name="do" value="save" id="btn-save"
class="btn"><?php _e('保存草稿'); ?></button>
<button type="submit" name="do" value="publish" class="btn primary"
id="btn-submit"><?php _e('发布文章'); ?></button>
<?php if ($options->markdown && (!$post->have() || $post->isMarkdown)): ?>
<input type="hidden" name="markdown" value="1"/>
<?php endif; ?>
</span>
</p>
<p class="submit">
<span class="left">
<button type="button" id="btn-cancel-preview" class="btn"><i
class="i-caret-left"></i> <?php _e('取消预览'); ?></button>
</span>
<span class="right">
<input type="hidden" name="do" value="publish" />
<input type="hidden" name="cid" value="<?php $post->cid(); ?>"/>
<button type="button" id="btn-preview" class="btn"><i
class="i-exlink"></i> <?php _e('预览文章'); ?></button>
<button type="submit" name="do" value="save" id="btn-save"
class="btn"><?php _e('保存草稿'); ?></button>
<button type="submit" name="do" value="publish" class="btn primary"
id="btn-submit"><?php _e('发布文章'); ?></button>
<?php if ($options->markdown && (!$post->have() || $post->isMarkdown)): ?>
<input type="hidden" name="markdown" value="1"/>
<?php endif; ?>
</span>
</p>
<?php \Typecho\Plugin::factory('admin/write-post.php')->content($post); ?>
</div>
<?php \Typecho\Plugin::factory('admin/write-post.php')->call('content', $post); ?>
</div>
<div id="edit-secondary" class="col-mb-12 col-tb-3" role="complementary">
<ul class="typecho-option-tabs clearfix">
<li class="active w-50"><a href="#tab-advance"><?php _e('选项'); ?></a></li>
<li class="w-50"><a href="#tab-files" id="tab-files-btn"><?php _e('附件'); ?></a></li>
</ul>
<div id="edit-secondary" class="col-mb-12 col-tb-3" role="complementary">
<ul class="typecho-option-tabs">
<li class="active w-50"><a href="#tab-advance"><?php _e('选项'); ?></a></li>
<li class="w-50"><a href="#tab-files" id="tab-files-btn"><?php _e('附件'); ?></a></li>
</ul>
<div id="tab-advance" class="tab-content">
<section class="typecho-post-option" role="application">
<label for="date" class="typecho-label"><?php _e('发布日期'); ?></label>
<p><input class="typecho-date w-100" type="text" name="date" id="date" autocomplete="off"
value="<?php $post->have() && $post->created > 0 ? $post->date('Y-m-d H:i') : ''; ?>"/>
</p>
</section>
<div id="tab-advance" class="tab-content">
<section class="typecho-post-option" role="application">
<label for="date" class="typecho-label"><?php _e('发布日期'); ?></label>
<p><input class="typecho-date w-100" type="text" name="date" id="date" autocomplete="off"
value="<?php $post->have() && $post->created > 0 ? $post->date('Y-m-d H:i') : ''; ?>"/>
</p>
</section>
<section class="typecho-post-option category-option">
<label class="typecho-label"><?php _e('分类'); ?></label>
<?php \Widget\Metas\Category\Rows::alloc()->to($category); ?>
<section class="typecho-post-option category-option">
<label class="typecho-label"><?php _e('分类'); ?></label>
<?php \Widget\Metas\Category\Rows::alloc()->to($category); ?>
<ul>
<?php $categories = array_column($post->categories, 'mid'); ?>
<?php while ($category->next()): ?>
<li><?php echo str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $category->levels); ?><input
type="checkbox" id="category-<?php $category->mid(); ?>"
value="<?php $category->mid(); ?>" name="category[]"
<?php if (in_array($category->mid, $categories)): ?>checked="true"<?php endif; ?>/>
<label
for="category-<?php $category->mid(); ?>"><?php $category->name(); ?></label>
</li>
<?php endwhile; ?>
</ul>
</section>
<section class="typecho-post-option">
<label for="token-input-tags" class="typecho-label"><?php _e('标签'); ?></label>
<p><input id="tags" name="tags" type="text" value="<?php $post->have() ? $post->tags(',', false) : ''; ?>"
class="w-100 text"/></p>
</section>
<?php \Typecho\Plugin::factory('admin/write-post.php')->call('option', $post); ?>
<details id="advance-panel">
<summary class="btn btn-xs"><?php _e('高级选项'); ?> <i class="i-caret-down"></i></summary>
<?php if ($user->pass('editor', true)): ?>
<section class="typecho-post-option visibility-option">
<label for="visibility" class="typecho-label"><?php _e('公开度'); ?></label>
<p>
<select id="visibility" name="visibility">
<?php if ($user->pass('editor', true)): ?>
<option
value="publish"<?php if (($post->status == 'publish' && !$post->password) || !$post->status): ?> selected<?php endif; ?>><?php _e('公开'); ?></option>
<option
value="hidden"<?php if ($post->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
<option
value="password"<?php if (strlen($post->password ?? '') > 0): ?> selected<?php endif; ?>><?php _e('密码保护'); ?></option>
<option
value="private"<?php if ($post->status == 'private'): ?> selected<?php endif; ?>><?php _e('私密'); ?></option>
<?php endif; ?>
<option
value="waiting"<?php if (!$user->pass('editor', true) || $post->status == 'waiting'): ?> selected<?php endif; ?>><?php _e('待审核'); ?></option>
</select>
</p>
<p id="post-password"<?php if (strlen($post->password ?? '') == 0): ?> class="hidden"<?php endif; ?>>
<label for="protect-pwd" class="sr-only">内容密码</label>
<input type="text" name="password" id="protect-pwd" class="text-s"
value="<?php $post->password(); ?>" size="16"
placeholder="<?php _e('内容密码'); ?>" autocomplete="off"/>
</p>
</section>
<?php endif; ?>
<section class="typecho-post-option allow-option">
<label class="typecho-label"><?php _e('权限控制'); ?></label>
<ul>
<?php
if ($post->have()) {
$categories = array_column($post->categories, 'mid');
} else {
$categories = [];
}
?>
<?php while ($category->next()): ?>
<li><?php echo str_repeat('&nbsp;&nbsp;&nbsp;&nbsp;', $category->levels); ?><input
type="checkbox" id="category-<?php $category->mid(); ?>"
value="<?php $category->mid(); ?>" name="category[]"
<?php if (in_array($category->mid, $categories)): ?>checked="true"<?php endif; ?>/>
<label
for="category-<?php $category->mid(); ?>"><?php $category->name(); ?></label>
</li>
<?php endwhile; ?>
<li><input id="allowComment" name="allowComment" type="checkbox" value="1"
<?php if ($post->allow('comment')): ?>checked="true"<?php endif; ?> />
<label for="allowComment"><?php _e('允许评论'); ?></label></li>
<li><input id="allowPing" name="allowPing" type="checkbox" value="1"
<?php if ($post->allow('ping')): ?>checked="true"<?php endif; ?> />
<label for="allowPing"><?php _e('允许被引用'); ?></label></li>
<li><input id="allowFeed" name="allowFeed" type="checkbox" value="1"
<?php if ($post->allow('feed')): ?>checked="true"<?php endif; ?> />
<label for="allowFeed"><?php _e('允许在聚合中出现'); ?></label></li>
</ul>
</section>
<section class="typecho-post-option">
<label for="token-input-tags" class="typecho-label"><?php _e('标签'); ?></label>
<p><input id="tags" name="tags" type="text" value="<?php $post->tags(',', false); ?>"
class="w-100 text"/></p>
<label for="trackback" class="typecho-label"><?php _e('引用通告'); ?></label>
<p><textarea id="trackback" class="w-100 mono" name="trackback" rows="2"></textarea></p>
<p class="description"><?php _e('每一行一个引用地址, 用回车隔开'); ?></p>
</section>
<?php \Typecho\Plugin::factory('admin/write-post.php')->option($post); ?>
<?php \Typecho\Plugin::factory('admin/write-post.php')->call('advanceOption', $post); ?>
</details><!-- end #advance-panel -->
<button type="button" id="advance-panel-btn" class="btn btn-xs"><?php _e('高级选项'); ?> <i
class="i-caret-down"></i></button>
<div id="advance-panel">
<?php if ($user->pass('editor', true)): ?>
<section class="typecho-post-option visibility-option">
<label for="visibility" class="typecho-label"><?php _e('公开度'); ?></label>
<p>
<select id="visibility" name="visibility">
<?php if ($user->pass('editor', true)): ?>
<option
value="publish"<?php if (($post->status == 'publish' && !$post->password) || !$post->status): ?> selected<?php endif; ?>><?php _e('公开'); ?></option>
<option
value="hidden"<?php if ($post->status == 'hidden'): ?> selected<?php endif; ?>><?php _e('隐藏'); ?></option>
<option
value="password"<?php if (strlen($post->password) > 0): ?> selected<?php endif; ?>><?php _e('密码保护'); ?></option>
<option
value="private"<?php if ($post->status == 'private'): ?> selected<?php endif; ?>><?php _e('私密'); ?></option>
<?php endif; ?>
<option
value="waiting"<?php if (!$user->pass('editor', true) || $post->status == 'waiting'): ?> selected<?php endif; ?>><?php _e('待审核'); ?></option>
</select>
</p>
<p id="post-password"<?php if (strlen($post->password) == 0): ?> class="hidden"<?php endif; ?>>
<label for="protect-pwd" class="sr-only">内容密码</label>
<input type="text" name="password" id="protect-pwd" class="text-s"
value="<?php $post->password(); ?>" size="16"
placeholder="<?php _e('内容密码'); ?>" autocomplete="off"/>
</p>
</section>
<?php endif; ?>
<?php if ($post->have()): ?>
<?php $modified = new \Typecho\Date($post->modified); ?>
<section class="typecho-post-option">
<p class="description">
<br>&mdash;<br>
<?php _e('本文由 <a href="%s">%s</a> 撰写',
\Typecho\Common::url('manage-posts.php?uid=' . $post->author->uid, $options->adminUrl), $post->author->screenName); ?>
<br>
<?php _e('最后更新于 %s', $modified->word()); ?>
</p>
</section>
<?php endif; ?>
</div><!-- end #tab-advance -->
<section class="typecho-post-option allow-option">
<label class="typecho-label"><?php _e('权限控制'); ?></label>
<ul>
<li><input id="allowComment" name="allowComment" type="checkbox" value="1"
<?php if ($post->allow('comment')): ?>checked="true"<?php endif; ?> />
<label for="allowComment"><?php _e('允许评论'); ?></label></li>
<li><input id="allowPing" name="allowPing" type="checkbox" value="1"
<?php if ($post->allow('ping')): ?>checked="true"<?php endif; ?> />
<label for="allowPing"><?php _e('允许被引用'); ?></label></li>
<li><input id="allowFeed" name="allowFeed" type="checkbox" value="1"
<?php if ($post->allow('feed')): ?>checked="true"<?php endif; ?> />
<label for="allowFeed"><?php _e('允许在聚合中出现'); ?></label></li>
</ul>
</section>
<section class="typecho-post-option">
<label for="trackback" class="typecho-label"><?php _e('引用通告'); ?></label>
<p><textarea id="trackback" class="w-100 mono" name="trackback" rows="2"></textarea></p>
<p class="description"><?php _e('每一行一个引用地址, 用回车隔开'); ?></p>
</section>
<?php \Typecho\Plugin::factory('admin/write-post.php')->advanceOption($post); ?>
</div><!-- end #advance-panel -->
<?php if ($post->have()): ?>
<?php $modified = new \Typecho\Date($post->modified); ?>
<section class="typecho-post-option">
<p class="description">
<br>&mdash;<br>
<?php _e('本文由 <a href="%s">%s</a> 撰写',
\Typecho\Common::url('manage-posts.php?uid=' . $post->author->uid, $options->adminUrl), $post->author->screenName); ?>
<br>
<?php _e('最后更新于 %s', $modified->word()); ?>
</p>
</section>
<?php endif; ?>
</div><!-- end #tab-advance -->
<div id="tab-files" class="tab-content hidden">
<?php include 'file-upload.php'; ?>
</div><!-- end #tab-files -->
</div>
</form>
</div>
<div id="tab-files" class="tab-content hidden">
<?php include 'file-upload.php'; ?>
</div><!-- end #tab-files -->
</div>
</form>
</div>
</div>
</main>
<?php
include 'copyright.php';
@@ -204,13 +201,13 @@ include 'common-js.php';
include 'form-js.php';
include 'write-js.php';
\Typecho\Plugin::factory('admin/write-post.php')->trigger($plugged)->richEditor($post);
\Typecho\Plugin::factory('admin/write-post.php')->trigger($plugged)->call('richEditor', $post);
if (!$plugged) {
include 'editor-js.php';
}
include 'file-upload-js.php';
include 'custom-fields-js.php';
\Typecho\Plugin::factory('admin/write-post.php')->bottom($post);
\Typecho\Plugin::factory('admin/write-post.php')->call('bottom', $post);
include 'footer.php';
?>

View File

@@ -1,52 +0,0 @@
Version 0.8.1/12.4.1
修复同级子目录下安装多个站点引起的登录失效
增加评论黑名单插件
修复评论接口重用导致启用评论验证插件后后台无法评论的bug
修正年份路由的bug
修正由于flash的cookie丢失bug导致的文件无法上传bug
增加对ini_get的判断
提交对Sina App Engine的兼容性判断
增加对Sina App Engine环境的支持
增加对ini_get的判断
修正新注册用户登录后跳转错误bug
修正对ssl的支持
fix issue 510
修复使用多层代理时, 获取ip地址错误
修正修改文章时上传控件无法载入的问题
修改后台错别字
修正错别字
兼容server不支持http 1.1的情况,典型问题如 sae环境404页面乱码
修正由于SAE更改常用导致的数据库信息无法自动读入的问题
增加上传插件接口
提交Sina App Engine专用的文件上传插件
使用SAE的Storage做持久化存储。
修正SaeUpload插件的说明地址
new version library
只是一些小修正
fix bug report on segmentfault
fix issue 536
fix Issue 541
fix Issue 544
fix Issue 544
fix Issue 540
fix Issue 537
fix Issue 529
fix Issue 532
fix issue 526
文章增加待审核功能下一步给文章增加private属性
更新后台表单样式, 新增文章预览功能
css细节微调
文章增加private属性显示
修正插件显示空白问题, 预览框box修正
修改预览内容样式,修改预览选项位置,高级选项->权限控制增加“允许游客访问”选项,用于私密浏览
fix Issue 545
实现文章公开度:公开、密码保护、私有、未审核
little change
实现功能1,当用户之前有审核通过的评论再次发评论会直接为通过审核可关闭2,未通过审核的评论评论作者可以在前台看到他人不可见3,隐藏功能;
修正后台修改或添加页面状态错误的问题;修正保存私密、审核日志时会新增一篇同样日志的问题
简单增强搜索功能 Issue 480
添加有密码和未发布图标
fix Issue 551
将文章管理页的公开度草稿等信息改为文字
接受插件返回的header

View File

@@ -17,10 +17,10 @@ if (!defined('__TYPECHO_ROOT_DIR__') && !@include_once 'config.inc.php') {
\Widget\Init::alloc();
/** 注册一个初始化插件 */
\Typecho\Plugin::factory('index.php')->begin();
\Typecho\Plugin::factory('index.php')->call('begin');
/** 开始路由分发 */
\Typecho\Router::dispatch();
/** 注册一个结束插件 */
\Typecho\Plugin::factory('index.php')->end();
\Typecho\Plugin::factory('index.php')->call('end');

View File

@@ -54,17 +54,8 @@ function install_get_lang(): string
*/
function install_get_site_url(): string
{
$serverSiteUrl = \Typecho\Request::getInstance()->getServer(
'TYPECHO_SITE_URL',
install_is_cli() ? 'http://localhost' : null
);
if (!empty($serverSiteUrl)) {
return $serverSiteUrl;
} else {
$request = \Typecho\Request::getInstance();
return $request->get('userUrl', $request->getRequestRoot());
}
$request = \Typecho\Request::getInstance();
return install_is_cli() ? $request->getServer('TYPECHO_SITE_URL', 'http://localhost') : $request->getRequestRoot();
}
/**
@@ -214,14 +205,14 @@ function install_get_default_routers(): array
'comment_page' =>
[
'url' => '[permalink:string]/comment-page-[commentPage:digital]',
'widget' => '\Widget\Archive',
'action' => 'render',
'widget' => '\Widget\CommentPage',
'action' => 'action',
],
'feed' =>
[
'url' => '/feed[feed:string:0]',
'widget' => '\Widget\Archive',
'action' => 'feed',
'widget' => '\Widget\Feed',
'action' => 'render',
],
'feedback' =>
[
@@ -250,7 +241,16 @@ function install_get_default_options(): array
if (empty($options)) {
$options = [
'theme' => 'default',
'theme:default' => 'a:2:{s:7:"logoUrl";N;s:12:"sidebarBlock";a:5:{i:0;s:15:"ShowRecentPosts";i:1;s:18:"ShowRecentComments";i:2;s:12:"ShowCategory";i:3;s:11:"ShowArchive";i:4;s:9:"ShowOther";}}',
'theme:default' => json_encode([
'logoUrl' => '',
'sidebarBlock' => [
'ShowRecentPosts',
'ShowRecentComments',
'ShowCategory',
'ShowArchive',
'ShowOther'
]
]),
'timezone' => '28800',
'lang' => install_get_lang(),
'charset' => 'UTF-8',
@@ -265,7 +265,7 @@ function install_get_default_options(): array
'frontArchive' => 0,
'commentsRequireMail' => 1,
'commentsWhitelist' => 0,
'commentsRequireURL' => 0,
'commentsRequireUrl' => 0,
'commentsRequireModeration' => 0,
'plugins' => 'a:0:{}',
'commentDateFormat' => 'F jS, Y \a\t h:i a',
@@ -303,9 +303,9 @@ function install_get_default_options(): array
'commentsAvatar' => 1,
'commentsAvatarRating' => 'G',
'commentsAntiSpam' => 1,
'routingTable' => serialize(install_get_default_routers()),
'actionTable' => 'a:0:{}',
'panelTable' => 'a:0:{}',
'routingTable' => json_encode(install_get_default_routers()),
'actionTable' => json_encode([]),
'panelTable' => json_encode([]),
'attachmentTypes' => '@image@',
'secret' => \Typecho\Common::randString(32, true),
'installed' => 0,
@@ -467,10 +467,10 @@ function install_check(string $type): bool
try {
// check if table exists
$values = $installDb->fetchAll($installDb->select()->from('table.options')
->where('user = 0'));
$installed = $installDb->fetchRow($installDb->select()->from('table.options')
->where('user = 0 AND name = ?', 'installed'));
if ($type == 'db_data' && empty($values)) {
if ($type == 'db_data' && empty($installed['value'])) {
return false;
}
} catch (\Typecho\Db\Adapter\ConnectionException $e) {
@@ -518,7 +518,13 @@ function install_raise_error($error, $config = null)
*/
function install_success($step, ?array $config = null)
{
global $installDb;
if (install_is_cli()) {
if ($step == 3) {
\Typecho\Db::set($installDb);
}
if ($step > 0) {
$method = 'install_step_' . $step . '_perform';
$method();
@@ -708,7 +714,7 @@ function install_step_1()
</p>
<h3><?php _e('许可及协议'); ?></h3>
<ul>
<li><?php _e('Typecho 基于 <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a> 协议发布, 我们允许用户在 GPL 协议许可的范围内使用, 拷贝, 修改和分发此程序.'); ?>
<li><?php _e('Typecho 基于 <a href="https://www.gnu.org/copyleft/gpl.html">GPL</a> 协议发布, 我们允许用户在 GPL 协议许可的范围内使用, 拷贝, 修改和分发此程序.'); ?>
<?php _e('在GPL许可的范围内, 您可以自由地将其用于商业以及非商业用途.'); ?></li>
<li><?php _e('Typecho 软件由其社区提供支持, 核心开发团队负责维护程序日常开发工作以及新特性的制定.'); ?>
<?php _e('如果您遇到使用上的问题, 程序中的 BUG, 以及期许的新功能, 欢迎您在社区中交流或者直接向我们贡献代码.'); ?>
@@ -762,13 +768,13 @@ function install_step_1_perform()
$realUploadDir = \Typecho\Common::url($uploadDir, __TYPECHO_ROOT_DIR__);
$writeable = true;
if (is_dir($realUploadDir)) {
if (!is_writeable($realUploadDir)) {
if (!@chmod($realUploadDir, 0644)) {
if (!is_writable($realUploadDir) || !is_readable($realUploadDir)) {
if (!@chmod($realUploadDir, 0755)) {
$writeable = false;
}
}
} else {
if (!@mkdir($realUploadDir, 0644)) {
if (!@mkdir($realUploadDir, 0755)) {
$writeable = false;
}
}
@@ -927,7 +933,9 @@ function install_step_2_perform()
'dbPassword' => null,
'dbCharset' => 'utf8mb4',
'dbDatabase' => null,
'dbEngine' => 'InnoDB'
'dbEngine' => 'InnoDB',
'dbSslCa' => null,
'dbSslVerify' => 'off',
],
'Pgsql' => [
'dbHost' => 'localhost',
@@ -936,6 +944,7 @@ function install_step_2_perform()
'dbPassword' => null,
'dbCharset' => 'utf8',
'dbDatabase' => null,
'dbSslVerify' => 'off',
],
'SQLite' => [
'dbFile' => __TYPECHO_ROOT_DIR__ . '/usr/' . uniqid() . '.db'
@@ -955,7 +964,9 @@ function install_step_2_perform()
'dbEngine' => $request->getServer('TYPECHO_DB_ENGINE'),
'dbPrefix' => $request->getServer('TYPECHO_DB_PREFIX', 'typecho_'),
'dbAdapter' => $request->getServer('TYPECHO_DB_ADAPTER', install_get_current_db_driver()),
'dbNext' => $request->getServer('TYPECHO_DB_NEXT', 'none')
'dbNext' => $request->getServer('TYPECHO_DB_NEXT', 'none'),
'dbSslCa' => $request->getServer('TYPECHO_DB_SSL_CA'),
'dbSslVerify' => $request->getServer('TYPECHO_DB_SSL_VERIFY', 'off'),
];
} else {
$config = $request->from([
@@ -970,7 +981,9 @@ function install_step_2_perform()
'dbEngine',
'dbPrefix',
'dbAdapter',
'dbNext'
'dbNext',
'dbSslCa',
'dbSslVerify',
]);
}
@@ -1008,6 +1021,8 @@ function install_step_2_perform()
->addRule('dbDatabase', 'required', _t('确认您的配置'))
->addRule('dbEngine', 'required', _t('确认您的配置'))
->addRule('dbEngine', 'enum', _t('确认您的配置'), ['InnoDB', 'MyISAM'])
->addRule('dbSslCa', 'file_exists', _t('确认您的配置'))
->addRule('dbSslVerify', 'enum', _t('确认您的配置'), ['on', 'off'])
->run($config);
break;
case 'Pgsql':
@@ -1019,11 +1034,19 @@ function install_step_2_perform()
->addRule('dbCharset', 'required', _t('确认您的配置'))
->addRule('dbCharset', 'enum', _t('确认您的配置'), ['utf8'])
->addRule('dbDatabase', 'required', _t('确认您的配置'))
->addRule('dbSslVerify', 'enum', _t('确认您的配置'), ['on', 'off'])
->run($config);
break;
case 'SQLite':
$error = (new \Typecho\Validate())
->addRule('dbFile', 'required', _t('确认您的配置'))
->addRule('dbFile', function (string $path) {
$pattern = "/^(\/[._a-z0-9-]+)*[a-z0-9]+\.[a-z0-9]{2,}$/i";
if (strstr(PHP_OS, 'WIN')) {
$pattern = "/(\/[._a-z0-9-]+)*[a-z0-9]+\.[a-z0-9]{2,}$/i";
}
return !!preg_match($pattern, $path);
}, _t('确认您的配置'))
->run($config);
break;
default:
@@ -1036,7 +1059,25 @@ function install_step_2_perform()
}
foreach ($configMap[$type] as $key => $value) {
$dbConfig[strtolower(substr($key, 2))] = $config[$key];
$dbConfig[lcfirst(substr($key, 2))] = $config[$key];
}
// intval port number
if (isset($dbConfig['port'])) {
if (strpos($dbConfig['host'], '/') !== false && $type == 'Mysql') {
$dbConfig['port'] = null;
} else {
$dbConfig['port'] = intval($dbConfig['port']);
}
}
// bool ssl verify
if (isset($dbConfig['sslVerify'])) {
$dbConfig['sslVerify'] = $dbConfig['sslVerify'] == 'on' || !empty($dbConfig['sslCa']);
}
if (isset($dbConfig['file']) && preg_match("/^[a-z0-9]+\.[a-z0-9]{2,}$/i", $dbConfig['file'])) {
$dbConfig['file'] = __DIR__ . '/usr/' . $dbConfig['file'];
}
// check config file
@@ -1049,10 +1090,15 @@ function install_step_2_perform()
$installDb = new \Typecho\Db($config['dbAdapter'], $config['dbPrefix']);
$installDb->addServer($dbConfig, \Typecho\Db::READ | \Typecho\Db::WRITE);
$installDb->query('SELECT 1=1');
} catch (\Typecho\Db\Adapter_Exception $e) {
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装'));
} catch (\Typecho\Db\Adapter\ConnectionException $e) {
$code = $e->getCode();
if (('Mysql' == $type && 1049 == $code) || ('Pgsql' == $type && 7 == $code)) {
install_raise_error(_t('数据库: "%s"不存在,请手动创建后重试', $config['dbDatabase']));
} else {
install_raise_error(_t('对不起, 无法连接数据库, 请先检查数据库配置再继续进行安装: "%s"', $e->getMessage()));
}
} catch (\Typecho\Db\Exception $e) {
install_raise_error(_t('安装程序捕捉到以下错误: " %s ". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
install_raise_error(_t('安装程序捕捉到以下错误: "%s". 程序被终止, 请检查您的配置信息.', $e->getMessage()));
}
$code = install_config_file($config['dbAdapter'], $config['dbPrefix'], $dbConfig);
@@ -1082,12 +1128,14 @@ function install_step_2_perform()
try {
foreach ($tables as $table) {
if ($type == 'Mysql') {
$installDb->query("DROP TABLE IF EXISTS `{$table}`");
} elseif ($type == 'Pgsql') {
$installDb->query("DROP TABLE {$table}");
} elseif ($type == 'SQLite') {
$installDb->query("DROP TABLE {$table}");
switch ($type) {
case 'Mysql':
$installDb->query("DROP TABLE IF EXISTS `{$table}`");
break;
case 'Pgsql':
case 'SQLite':
$installDb->query("DROP TABLE {$table}");
break;
}
}
} catch (\Typecho\Db\Exception $e) {
@@ -1163,7 +1211,7 @@ function install_step_3()
<ul class="typecho-option">
<li>
<label class="typecho-label" for="userUrl"><?php _e('网站地址'); ?></label>
<input autocomplete="new-password" type="text" name="userUrl" id="userUrl" class="text" value="<?php $options->siteUrl(); ?>" />
<input autocomplete="new-password" type="text" name="userUrl" id="userUrl" class="text" value="<?php $options->rootUrl(); ?>" />
<p class="description"><?php _e('这是程序自动匹配的网站路径, 如果不正确请修改它'); ?></p>
</li>
</ul>
@@ -1248,13 +1296,6 @@ function install_step_3_perform()
}
try {
// write options
foreach (install_get_default_options() as $key => $value) {
$installDb->query(
$installDb->insert('table.options')->rows(['name' => $key, 'user' => 0, 'value' => $value])
);
}
// write user
$hasher = new \Utils\PasswordHash(8, true);
$installDb->query(
@@ -1262,7 +1303,7 @@ function install_step_3_perform()
'name' => $config['userName'],
'password' => $hasher->hashPassword($config['userPassword']),
'mail' => $config['userMail'],
'url' => $options->siteUrl,
'url' => $config['userUrl'],
'screenName' => $config['userName'],
'group' => 'administrator',
'created' => \Typecho\Date::time()
@@ -1326,15 +1367,27 @@ function install_step_3_perform()
'cid' => 1, 'created' => \Typecho\Date::time(),
'author' => 'Typecho',
'ownerId' => 1,
'url' => 'http://typecho.org',
'url' => 'https://typecho.org',
'ip' => '127.0.0.1',
'agent' => $options->generator,
'text' => '欢迎加入 Typecho 大家族',
'text' => _t('欢迎加入 Typecho 大家族'),
'type' => 'comment',
'status' => 'approved',
'parent' => 0
])
);
// write options
foreach (install_get_default_options() as $key => $value) {
// mark installing finished
if ($key == 'installed') {
$value = 1;
}
$installDb->query(
$installDb->insert('table.options')->rows(['name' => $key, 'user' => 0, 'value' => $value])
);
}
} catch (\Typecho\Db\Exception $e) {
install_raise_error($e->getMessage());
}
@@ -1351,7 +1404,7 @@ function install_step_3_perform()
$config['userName'],
$config['userPassword'],
\Widget\Security::alloc()->getTokenUrl($loginUrl, $request->getReferer()),
$options->siteUrl
$config['userUrl']
]);
}
@@ -1361,8 +1414,6 @@ function install_step_3_perform()
*/
function install_dispatch()
{
define('__TYPECHO_INSTALL__', true);
// disable root url on cli mode
if (install_is_cli()) {
define('__TYPECHO_ROOT_URL__', 'http://localhost');
@@ -1372,6 +1423,12 @@ function install_dispatch()
$options = \Widget\Options::alloc(install_get_default_options());
\Widget\Init::alloc();
// display version
if (install_is_cli()) {
echo $options->generator . "\n";
echo 'PHP ' . PHP_VERSION . "\n";
}
// install finished yet
if (
install_check('config')
@@ -1435,7 +1492,7 @@ function install_dispatch()
</head>
<body>
<div class="body container">
<h1><a href="http://typecho.org" target="_blank" class="i-logo">Typecho</a></h1>
<h1><a href="https://typecho.org" target="_blank" class="i-logo">Typecho</a></h1>
<?php $method(); ?>
</div>
</body>

View File

@@ -63,4 +63,22 @@
</select>
</li>
</ul>
</details>
<ul class="typecho-option">
<li>
<label class="typecho-label" for="dbSslCa"><?php _e('数据库 SSL 证书'); ?></label>
<input type="text" class="text" name="dbSslCa" id="dbSslCa"/>
<p class="description"><?php _e('如果您的数据库启用了 SSL请填写 CA 证书路径,否则请留空'); ?></p>
</li>
</ul>
<ul class="typecho-option">
<li>
<label class="typecho-label" for="dbSslVerify"><?php _e('启用数据库 SSL 服务端证书验证'); ?></label>
<select name="dbSslVerify" id="dbSslVerify">
<option value="off"><?php _e('不启用'); ?></option>
<option value="on"><?php _e('启用'); ?></option>
</select>
</li>
</ul>
</details>

View File

@@ -6,13 +6,6 @@
<p class="description"><?php _e('您可能会使用 "%s"', 'localhost'); ?></p>
</li>
</ul>
<ul class="typecho-option">
<li>
<label class="typecho-label" for="dbPort"><?php _e('数据库端口'); ?></label>
<input type="text" class="text" name="dbPort" id="dbPort" value="5432"/>
<p class="description"><?php _e('如果您不知道此选项的意义, 请保留默认设置'); ?></p>
</li>
</ul>
<ul class="typecho-option">
<li>
<label class="typecho-label" for="dbUser"><?php _e('数据库用户名'); ?></label>
@@ -34,4 +27,28 @@
</li
</ul>
<input type="hidden" name="dbCharset" value="utf8" />
<details>
<summary>
<strong><?php _e('高级选项'); ?></strong>
</summary>
<ul class="typecho-option">
<li>
<label class="typecho-label" for="dbPort"><?php _e('数据库端口'); ?></label>
<input type="text" class="text" name="dbPort" id="dbPort" value="5432"/>
<p class="description"><?php _e('如果您不知道此选项的意义, 请保留默认设置'); ?></p>
</li>
</ul>
<input type="hidden" name="dbCharset" value="utf8" />
<ul class="typecho-option">
<li>
<label class="typecho-label" for="dbSslVerify"><?php _e('启用数据库 SSL 服务端证书验证'); ?></label>
<select name="dbSslVerify" id="dbSslVerify">
<option value="off"><?php _e('不启用'); ?></option>
<option value="on"><?php _e('启用'); ?></option>
</select>
</li>
</ul>
</details>

Some files were not shown because too many files have changed in this diff Show More