Compare commits
278 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a6c29a01c0 | ||
![]() |
0412ea7cf9 | ||
![]() |
6cd6587f15 | ||
![]() |
f74813cd69 | ||
![]() |
03e8bdfe0b | ||
![]() |
3a8b8ab3d2 | ||
![]() |
31c628d055 | ||
![]() |
1d57194f7f | ||
![]() |
031c75b530 | ||
![]() |
a88129b86c | ||
![]() |
57c07104cb | ||
![]() |
5ccc2b3679 | ||
![]() |
94609ac861 | ||
![]() |
c648f7fe63 | ||
![]() |
d593f58678 | ||
![]() |
a8e85cf28d | ||
![]() |
8520c564e3 | ||
![]() |
7caaa9f7c3 | ||
![]() |
0ad0bc93f3 | ||
![]() |
9312993e47 | ||
![]() |
f114b14c28 | ||
![]() |
c98d6324d7 | ||
![]() |
fce3efdec5 | ||
![]() |
1661c301e1 | ||
![]() |
c890a61456 | ||
![]() |
7e40471ecc | ||
![]() |
7e7888abd6 | ||
![]() |
472a44baea | ||
![]() |
1a84a7dd73 | ||
![]() |
d8eaa2ce1a | ||
![]() |
bdc7f451f9 | ||
![]() |
e86595c25d | ||
![]() |
756f90dd47 | ||
![]() |
bb2da02182 | ||
![]() |
a40965dc5d | ||
![]() |
4b8f60b26f | ||
![]() |
e672ff7011 | ||
![]() |
eba3bb996a | ||
![]() |
8d13aeb1d8 | ||
![]() |
4bed92e236 | ||
![]() |
aeef379c1f | ||
![]() |
291d092b91 | ||
![]() |
befbfca2fc | ||
![]() |
4ecf6be177 | ||
![]() |
f6fea928b2 | ||
![]() |
2ba51b0eaf | ||
![]() |
198e582bd3 | ||
![]() |
177c099f27 | ||
![]() |
a8ab719b1b | ||
![]() |
4c7cbe6591 | ||
![]() |
3513a9b2f9 | ||
![]() |
0d50ca2f6e | ||
![]() |
77bc0a364c | ||
![]() |
74ec6d5cc9 | ||
![]() |
a8a72db90f | ||
![]() |
23d3d8a0d8 | ||
![]() |
93544d1f29 | ||
![]() |
24ac765706 | ||
![]() |
89c4fa18ee | ||
![]() |
3180a931be | ||
![]() |
eeb5a9bfcb | ||
![]() |
651b2242d6 | ||
![]() |
e6048e97ed | ||
![]() |
73392c2fee | ||
![]() |
27b6f7e761 | ||
![]() |
f91761e83d | ||
![]() |
815c4cabb4 | ||
![]() |
50fd905ef8 | ||
![]() |
9c933905c8 | ||
![]() |
ca8e907adf | ||
![]() |
7df47fd4cc | ||
![]() |
ee9440cb1a | ||
![]() |
fab1b46b85 | ||
![]() |
889eba66c9 | ||
![]() |
a4df3fc358 | ||
![]() |
4d6726b7be | ||
![]() |
2eb496fbf1 | ||
![]() |
5e433a0bd0 | ||
![]() |
9caf582088 | ||
![]() |
e735c54cfd | ||
![]() |
d228afc63d | ||
![]() |
a7375a8a01 | ||
![]() |
d5f9db081a | ||
![]() |
2181d44c88 | ||
![]() |
e37b1772dd | ||
![]() |
a4c32dd4d7 | ||
![]() |
f1212164b7 | ||
![]() |
13f29ae616 | ||
![]() |
4ceabbae2e | ||
![]() |
bf5dcfd5cb | ||
![]() |
4dfcd626e0 | ||
![]() |
ace79d82a4 | ||
![]() |
d528834746 | ||
![]() |
27b0980022 | ||
![]() |
35829a96c8 | ||
![]() |
a6ce42f4b1 | ||
![]() |
6300bbf74b | ||
![]() |
1e1e5d609d | ||
![]() |
14ec0136f8 | ||
![]() |
072a456d5c | ||
![]() |
dfe5861f33 | ||
![]() |
998a8833aa | ||
![]() |
2c057fa115 | ||
![]() |
11fd72a645 | ||
![]() |
ea6ed06c69 | ||
![]() |
5d2be11c3f | ||
![]() |
a2eb9db6eb | ||
![]() |
c0f7c4581c | ||
![]() |
eb9efcb6bb | ||
![]() |
6bc85bd8da | ||
![]() |
d19fd8c072 | ||
![]() |
c9e110706c | ||
![]() |
3fd0355e1a | ||
![]() |
77eb53fe18 | ||
![]() |
838bb29a91 | ||
![]() |
f13d9a997b | ||
![]() |
f5b43e6203 | ||
![]() |
ca0dffa5f0 | ||
![]() |
386495b20e | ||
![]() |
a124e675c2 | ||
![]() |
db15491114 | ||
![]() |
2662e6fcb1 | ||
![]() |
8297fa5a00 | ||
![]() |
0913e4fbb4 | ||
![]() |
3e3d98a7a8 | ||
![]() |
91b460362a | ||
![]() |
3a114d80be | ||
![]() |
819da477ad | ||
![]() |
346c61a46c | ||
![]() |
dd8108ba2a | ||
![]() |
f7edfe664d | ||
![]() |
7ae2408fdc | ||
![]() |
31df89f882 | ||
![]() |
66cf087957 | ||
![]() |
f76517b228 | ||
![]() |
cc42bac830 | ||
![]() |
0307007bb3 | ||
![]() |
488e874e83 | ||
![]() |
393e6478fe | ||
![]() |
4ac8874a8a | ||
![]() |
49301c1722 | ||
![]() |
7b0cd592ae | ||
![]() |
2f7c818060 | ||
![]() |
36c6945628 | ||
![]() |
9727ed947d | ||
![]() |
8998662bd6 | ||
![]() |
ca79fc7129 | ||
![]() |
256366b6e7 | ||
![]() |
b0e3809746 | ||
![]() |
5c588f52cb | ||
![]() |
e7f311558f | ||
![]() |
f5faf67c5d | ||
![]() |
c5437b9bfe | ||
![]() |
1593bed754 | ||
![]() |
2290c87df9 | ||
![]() |
df5a58df0b | ||
![]() |
a47e45719e | ||
![]() |
0141995679 | ||
![]() |
caf2b98921 | ||
![]() |
af5f633aa7 | ||
![]() |
766f799f44 | ||
![]() |
b7fb6bcdd9 | ||
![]() |
a8a271d091 | ||
![]() |
79b3be3619 | ||
![]() |
c3517fde58 | ||
![]() |
fb3f5f4673 | ||
![]() |
8a19620201 | ||
![]() |
f744979fa6 | ||
![]() |
d3702ff4b7 | ||
![]() |
0e5ebd6209 | ||
![]() |
f674d4b6f9 | ||
![]() |
9978638266 | ||
![]() |
96950227d1 | ||
![]() |
d4dedecfd1 | ||
![]() |
648d70448b | ||
![]() |
f66b44dd1c | ||
![]() |
532ddb095d | ||
![]() |
bb3918daed | ||
![]() |
712b955b76 | ||
![]() |
8fb86495b6 | ||
![]() |
75f1d3eb66 | ||
![]() |
912ba7952e | ||
![]() |
63b7761575 | ||
![]() |
4e650c35ac | ||
![]() |
55fbbc70ea | ||
![]() |
2f4b77e1bf | ||
![]() |
3d4bff397c | ||
![]() |
77445f575d | ||
![]() |
7d5d89e31c | ||
![]() |
8dbb554df0 | ||
![]() |
903b276e7b | ||
![]() |
4ad5e24b04 | ||
![]() |
5f90468313 | ||
![]() |
3427d630e0 | ||
![]() |
50c58855fe | ||
![]() |
0b8620c68b | ||
![]() |
09e402161e | ||
![]() |
3af8f234fa | ||
![]() |
1c6b4c6037 | ||
![]() |
101de5b213 | ||
![]() |
731938afdb | ||
![]() |
8a7c7bf73d | ||
![]() |
65533b3138 | ||
![]() |
39bab49d13 | ||
![]() |
22ac8e7f3b | ||
![]() |
0ffb49b411 | ||
![]() |
f77546fd21 | ||
![]() |
f21434bb72 | ||
![]() |
d189f7918e | ||
![]() |
f196a6cba0 | ||
![]() |
e3815f6315 | ||
![]() |
0f25f61090 | ||
![]() |
07770cb6dd | ||
![]() |
66962e0b14 | ||
![]() |
6c6e7b1a92 | ||
![]() |
fafc05886e | ||
![]() |
e888653d89 | ||
![]() |
7f89c4bcbb | ||
![]() |
5d1383692d | ||
![]() |
ea2821a2a4 | ||
![]() |
089af76dde | ||
![]() |
3393fd9065 | ||
![]() |
7056e15afa | ||
![]() |
0ec5ab79a6 | ||
![]() |
65c8a38e64 | ||
![]() |
d25c000bb6 | ||
![]() |
980284108d | ||
![]() |
df6b9391f5 | ||
![]() |
4c85542b47 | ||
![]() |
b2f428fd07 | ||
![]() |
38c59f9039 | ||
![]() |
022abe132b | ||
![]() |
befcc65225 | ||
![]() |
52758def3c | ||
![]() |
6c01a3a96e | ||
![]() |
2274ab42f7 | ||
![]() |
8dee533d84 | ||
![]() |
faee1fdb38 | ||
![]() |
0462f15b4b | ||
![]() |
73c5fe0fc9 | ||
![]() |
dd28d8a5ec | ||
![]() |
12d52df888 | ||
![]() |
a5d956f206 | ||
![]() |
1c7dbf36ed | ||
![]() |
d0772caf86 | ||
![]() |
dd0607169a | ||
![]() |
22771dd752 | ||
![]() |
bdfeb8f25d | ||
![]() |
2ca5c489c1 | ||
![]() |
7f8f36ba4d | ||
![]() |
8e6b2fb0fe | ||
![]() |
522d66f0f7 | ||
![]() |
68d44c5663 | ||
![]() |
f02c01ab62 | ||
![]() |
fe34fd0ad4 | ||
![]() |
e6b0dc114b | ||
![]() |
2bc2c2cba3 | ||
![]() |
91e3d58a4a | ||
![]() |
283b307169 | ||
![]() |
d41cf971c5 | ||
![]() |
a673254c0e | ||
![]() |
decad371db | ||
![]() |
7a026c2d6d | ||
![]() |
7038a47c38 | ||
![]() |
6fa681888b | ||
![]() |
b66fc088a2 | ||
![]() |
64fddf7da4 | ||
![]() |
807f490eb5 | ||
![]() |
9b206c15c9 | ||
![]() |
f2f023cf69 | ||
![]() |
14565bd18e | ||
![]() |
347bfbb476 | ||
![]() |
e0b1a0a94f | ||
![]() |
f1a2bbb673 | ||
![]() |
0b9af2a61f | ||
![]() |
a5df46c6f7 | ||
![]() |
0888a8167f | ||
![]() |
efd57e368e |
21
.dockerignore
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Ignore everything
|
||||
**
|
||||
|
||||
# Allow system files and directories
|
||||
!docker-utils/
|
||||
!system/
|
||||
!.htaccess
|
||||
!composer*
|
||||
!index.php
|
||||
|
||||
# Allow content files and directories
|
||||
!cache/
|
||||
!content/
|
||||
!data/
|
||||
!media/
|
||||
!settings/
|
||||
!themes/
|
||||
|
||||
# Ignore unnecessary files inside allowed directories below
|
||||
# This should go after the allowed directories
|
||||
# e.g. docker-utils/test.php
|
1
.github/FUNDING.yml
vendored
|
@ -1 +0,0 @@
|
|||
custom: https://www.paypal.me/typemill
|
28
.gitignore
vendored
|
@ -1,26 +1,24 @@
|
|||
cache/lastCache.txt
|
||||
cache/lastSitemap.txt
|
||||
cache/metatabs.yaml
|
||||
cache/navigation.txt
|
||||
cache/sitemap.xml
|
||||
cache/structure-draft.txt
|
||||
cache/structure-extended.yaml
|
||||
cache/structure.txt
|
||||
content/index.yaml
|
||||
content/00-welcome/index.yaml
|
||||
content/00-welcome/00-setup.yaml
|
||||
content/00-welcome/00-setup-your-website.yaml
|
||||
content/00-welcome/01-write-content.yaml
|
||||
content/00-welcome/02-get-help.yaml
|
||||
content/00-welcome/03-markdown-test.yaml
|
||||
content/00-welcome/02-manage-access.yaml
|
||||
content/00-welcome/03-get-help.yaml
|
||||
content/00-welcome/04-markdown-test.yaml
|
||||
content/01-cyanine-theme/index.yaml
|
||||
content/01-cyanine-theme/00-landingpage.yaml
|
||||
content/01-cyanine-theme/01-colors-and-fonts.yaml
|
||||
content/01-cyanine-theme/02-footer.yaml
|
||||
content/01-cyanine-theme/03-content-elements.yaml
|
||||
settings/settings.yaml
|
||||
settings/users
|
||||
system/vendor
|
||||
plugins/demo
|
||||
cypress
|
||||
data/navigation
|
||||
data/css
|
||||
node_modules
|
||||
plugins/search
|
||||
settings/settings.yaml
|
||||
settings/license.yaml
|
||||
settings/users
|
||||
zips
|
||||
build.php
|
||||
node_modules
|
||||
cypress.json
|
|
@ -1,4 +1,4 @@
|
|||
<IfModule mod_rewrite.c>
|
||||
<IfModule mod_rewrite.c>
|
||||
|
||||
RewriteEngine On
|
||||
|
||||
|
@ -61,9 +61,9 @@ RewriteRule ^(composer\.lock|composer\.json|\.htaccess)$ error [F,L]
|
|||
RewriteRule (^|/)\.(?!well-known\/) index.php [L]
|
||||
|
||||
# Allow access to frontend files in author folder
|
||||
RewriteRule ^(system\/author\/css\/) - [L]
|
||||
RewriteRule ^(system\/author\/img\/) - [L]
|
||||
RewriteRule ^(system\/author\/js\/) - [L]
|
||||
RewriteRule ^(system\/typemill\/author\/css\/) - [L]
|
||||
RewriteRule ^(system\/typemill\/author\/img\/) - [L]
|
||||
RewriteRule ^(system\/typemill\/author\/js\/) - [L]
|
||||
|
||||
# redirect all other direct requests to the following physical folders to the index.php so pages with same name work
|
||||
RewriteRule ^(system|content|data|settings|(media\/files\/)) index.php [QSA,L]
|
||||
|
|
41
Dockerfile
Normal file
|
@ -0,0 +1,41 @@
|
|||
FROM php:8.0-apache
|
||||
|
||||
# Install OS dependencies required
|
||||
RUN apt-get update && apt-get upgrade -y && apt-get install git unzip zlib1g-dev libpng-dev -y
|
||||
|
||||
# Adapt apache config
|
||||
RUN a2enmod rewrite \
|
||||
&& echo "ServerName 127.0.0.1" >> /etc/apache2/apache2.conf
|
||||
|
||||
# Install PHP ext-gd
|
||||
RUN docker-php-ext-install gd
|
||||
|
||||
# Copy app content
|
||||
# Use the .dockerignore file to control what ends up inside the image!
|
||||
WORKDIR /var/www/html
|
||||
COPY . .
|
||||
|
||||
# Install server dependencies
|
||||
RUN chmod +x /var/www/html/docker-utils/install-composer && \
|
||||
/var/www/html/docker-utils/install-composer && \
|
||||
./composer.phar update && \
|
||||
chmod +x /var/www/html/docker-utils/init-server
|
||||
|
||||
# Expose useful volumes (see documentation)
|
||||
VOLUME /var/www/html/settings
|
||||
VOLUME /var/www/html/media
|
||||
VOLUME /var/www/html/cache
|
||||
VOLUME /var/www/html/plugins
|
||||
VOLUME /var/www/html/data
|
||||
|
||||
# Create a default copy of content and theme in case of empty directories binding
|
||||
RUN mkdir -p /var/www/html/content.default/ && \
|
||||
cp -R /var/www/html/content/* /var/www/html/content.default/ && \
|
||||
mkdir -p /var/www/html/themes.default/ && \
|
||||
cp -R /var/www/html/themes/* /var/www/html/themes.default/
|
||||
|
||||
VOLUME /var/www/html/content
|
||||
VOLUME /var/www/html/themes
|
||||
|
||||
# Inject default values if content and themes are mounted with empty directories, adjust rights and start the server
|
||||
CMD ["/var/www/html/docker-utils/init-server"]
|
233
cache/cyanine-custom.css
vendored
|
@ -1,30 +1,205 @@
|
|||
.landingpageintro h1{
|
||||
display: inline-block;
|
||||
background: white;
|
||||
padding: 4px 10px;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.landingpageintro p{
|
||||
display: inline;
|
||||
background: white;
|
||||
line-height: 2.1rem;
|
||||
padding: 6px 4px 4px;
|
||||
}
|
||||
article a[href^="http"]::after,
|
||||
article a[href^="https://"]::after
|
||||
{
|
||||
content: "";
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
margin-left: 4px;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='currentColor' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M8.636 3.5a.5.5 0 0 0-.5-.5H1.5A1.5 1.5 0 0 0 0 4.5v10A1.5 1.5 0 0 0 1.5 16h10a1.5 1.5 0 0 0 1.5-1.5V7.864a.5.5 0 0 0-1 0V14.5a.5.5 0 0 1-.5.5h-10a.5.5 0 0 1-.5-.5v-10a.5.5 0 0 1 .5-.5h6.636a.5.5 0 0 0 .5-.5z'/%3E%3Cpath fill-rule='evenodd' d='M16 .5a.5.5 0 0 0-.5-.5h-5a.5.5 0 0 0 0 1h3.793L6.146 9.146a.5.5 0 1 0 .708.708L15 1.707V5.5a.5.5 0 0 0 1 0v-5z'/%3E%3C/svg%3E");
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
display: inline-block;
|
||||
}
|
||||
a[href^="https://www.electrictoolbox.com"] {
|
||||
background: none;
|
||||
padding-right: 0;
|
||||
.demolink{
|
||||
display:block;
|
||||
font-size: .8em;
|
||||
text-decoration:none;
|
||||
margin-top: 20px;
|
||||
}
|
||||
/*
|
||||
.landingpageintro h1{
|
||||
display: inline-block;
|
||||
background: white;
|
||||
padding: 4px 10px 10px;
|
||||
margin: 15px;
|
||||
}
|
||||
*/
|
||||
.landingpageintro .dim:focus, .landingpageintro .dim:hover {
|
||||
opacity: .8;
|
||||
}
|
||||
.landingpageintro figure {
|
||||
display: block;
|
||||
margin: 0em auto;
|
||||
padding: 0;
|
||||
font-weight: 500;
|
||||
}
|
||||
.landingpageintro figure img {
|
||||
display: inline;
|
||||
vertical-align: baseline;
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
|
||||
.landingpageintro h1{
|
||||
font-size: 2.5em;
|
||||
}
|
||||
|
||||
.landingpageintro p{
|
||||
/* display: inline; */
|
||||
/* background: white; */
|
||||
/* line-height: 2.1rem;
|
||||
padding: 6px 4px 4px; */
|
||||
|
||||
font-weight: 500;
|
||||
}
|
||||
.landingpageintro p a{
|
||||
color: white;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
.introbg.pa4{
|
||||
padding: 0;
|
||||
}
|
||||
@media screen and (min-width:60em) {
|
||||
/*
|
||||
.landingpageintro h1{
|
||||
font-size: 4.5rem;
|
||||
}
|
||||
*/
|
||||
.introbg.pa4{
|
||||
padding: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.landingpageinfo ol{
|
||||
text-align: left;
|
||||
list-style: none;
|
||||
counter-reset: item;
|
||||
}
|
||||
.landingpageinfo ol li{
|
||||
padding:.5rem 0;
|
||||
counter-increment: item;
|
||||
}
|
||||
.landingpageinfo ol li:before {
|
||||
content: counter(item);
|
||||
margin-right: 10px;
|
||||
background: lightseagreen;
|
||||
border-radius: 100%;
|
||||
color: white;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
margin-left: -40px;
|
||||
font-size: .8em;
|
||||
line-height: 30px;
|
||||
width: 30px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.landingpageinfo ol a{
|
||||
color:lightseagreen;
|
||||
}
|
||||
|
||||
#mlb2-10705438.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-block-form .ml-form-embedPermissions,
|
||||
#mlb2-10705438.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody .ml-block-form .ml-form-embedSubmit{
|
||||
float:none;
|
||||
}
|
||||
.ml-form-embedBody{
|
||||
width:100%;
|
||||
background-color:white;
|
||||
}
|
||||
#mlb2-10705438.ml-form-embedContainer .ml-form-embedWrapper .ml-form-embedBody, #mlb2-10705438.ml-form-embedContainer .ml-form-embedWrapper .ml-form-successBody{
|
||||
padding: 40px 40px 40px 40px!important;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 50em) {
|
||||
.ml-form-embedBody{
|
||||
width:60%;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*paddle*/
|
||||
.mt-auto{
|
||||
margin-top:auto;
|
||||
}
|
||||
.paddlebox h2{
|
||||
margin-top:1em;
|
||||
}
|
||||
.paddlebox a,
|
||||
.paddlebox a:link,
|
||||
.paddlebox a:hover,
|
||||
.paddlebox a:focus,
|
||||
.paddlebox a:active,
|
||||
.paddlebox a:visited{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.paddlebox strong{
|
||||
position: relative;
|
||||
background-color: RGBA(32, 178, 170, .2);
|
||||
font-size: 1.2em;
|
||||
padding: 1px;
|
||||
}
|
||||
.paddlebox strong:before{
|
||||
content:"";
|
||||
left:0em;
|
||||
top:0em;
|
||||
border-width:3px;
|
||||
border-style:solid;
|
||||
border-color:lightseagreen;
|
||||
position:absolute;
|
||||
border-right-color:transparent;
|
||||
width:100%;
|
||||
height:1.1em;
|
||||
transform:rotate(2deg);
|
||||
opacity:0.5;
|
||||
border-radius:0.25em;
|
||||
}
|
||||
|
||||
.paddlebox strong:after{
|
||||
content:"";
|
||||
left:0em;
|
||||
top:0em;
|
||||
border-width:4px;
|
||||
border-style:solid;
|
||||
border-color:lightseagreen;
|
||||
border-left-color:transparent;
|
||||
border-top-color:transparent;
|
||||
position:absolute;
|
||||
width:100%;
|
||||
height:1em;
|
||||
transform:rotate(-1deg);
|
||||
opacity:0.5;
|
||||
border-radius:0.25em;
|
||||
}
|
||||
.paddlebox ul{
|
||||
list-style-type: "✓ ";
|
||||
padding-left:1em;
|
||||
}
|
||||
.paddle_button{
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.myclassbox p{
|
||||
background:lightseagreen;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
20% {
|
||||
transform: translateY(-100%);
|
||||
}
|
||||
40% {
|
||||
transform: translateY(-200%);
|
||||
}
|
||||
60% {
|
||||
transform: translateY(-300%);
|
||||
}
|
||||
80% {
|
||||
transform: translateY(-400%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.slide-up {
|
||||
/* animation: slideUp 1s ease-in-out; */
|
||||
animation: slideUp 8s infinite;
|
||||
will-change: transform;
|
||||
animation-delay: 3s;
|
||||
}
|
||||
|
||||
.figureborder figure {
|
||||
border: 1px solid lightgray;
|
||||
}
|
3
cache/securitylog.txt
vendored
|
@ -1,3 +0,0 @@
|
|||
127.0.0.1;2022-05-26 22:14:00;wrong login
|
||||
127.0.0.1;2022-05-26 22:14:07;wrong captcha http://localhost/typemill/tm/login
|
||||
127.0.0.1;2022-05-27 21:33:28;wrong login
|
|
@ -1,32 +1,41 @@
|
|||
{
|
||||
"name": "typemill/typemill",
|
||||
"type": "project",
|
||||
"description": "A crazy simple tool to create web-documentations and online manuals with markdown files.",
|
||||
"keywords": ["documentations","manuals","flat-file","Markdown","php"],
|
||||
"description": "A lightweight flat-file-cms for advanced publishing. Create websites, handbooks, documentations, and transform them into ebooks.",
|
||||
"keywords": ["cms", "vue", "markdown", "slim", "php", "flat-file", "publishing", "documentations", "manuals", "handbooks", "pdf", "epub", "paged media", "paged.js"],
|
||||
"homepage": "https://typemill.net",
|
||||
"license": "MIT",
|
||||
"config": {
|
||||
"vendor-dir": "system/vendor"
|
||||
"vendor-dir": "system/vendor",
|
||||
"allow-plugins": {
|
||||
"composer/installers": true
|
||||
},
|
||||
"platform": {
|
||||
"php": "8.0.0"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
"slim/slim": "~3.7",
|
||||
"twig/twig": "^2.0",
|
||||
"slim/twig-view": "~2.3",
|
||||
"slim/flash": "~0.4",
|
||||
"slim/csrf": "~0.8",
|
||||
"symfony/yaml": "~5.0",
|
||||
"symfony/event-dispatcher": "~4.0",
|
||||
"erusev/parsedown": "~1.4",
|
||||
"php": "^8.0",
|
||||
"slim/slim": "4.*",
|
||||
"slim/psr7": "^1.5",
|
||||
"php-di/php-di": "^6.3",
|
||||
"php-di/slim-bridge": "^3.2",
|
||||
"slim/twig-view": "^3.3",
|
||||
"slim/flash": "^0.4.0",
|
||||
"slim/csrf": "^1.2",
|
||||
"vlucas/valitron": "^1.4",
|
||||
"symfony/yaml": "^5.4",
|
||||
"symfony/event-dispatcher": "^5.4",
|
||||
"erusev/parsedown": "dev-master",
|
||||
"erusev/parsedown-extra": "dev-master",
|
||||
"jbroadway/urlify": "1.1.3",
|
||||
"vlucas/valitron": "dev-master",
|
||||
"laminas/laminas-permissions-acl": "^2.7",
|
||||
"akrabat/proxy-detection-middleware": "^0.4.0",
|
||||
"gregwar/captcha": "1.*"
|
||||
},
|
||||
"laminas/laminas-permissions-acl": "^2.10",
|
||||
"akrabat/proxy-detection-middleware": "^1.0.0",
|
||||
"gregwar/captcha": "master"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Typemill\\": "system/",
|
||||
"Typemill\\": "system/typemill/",
|
||||
"Plugins\\": "plugins/"
|
||||
}
|
||||
},
|
||||
|
|
1377
composer.lock
generated
8
content/.yaml
Normal file
|
@ -0,0 +1,8 @@
|
|||
meta:
|
||||
author: Sebastian
|
||||
created: '2024-09-10'
|
||||
time: 12-43-18
|
||||
navtitle: null
|
||||
modified: '2024-08-01'
|
||||
title: ''
|
||||
description: ''
|
15
content/00-getting-started/00-create-your-first-page.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Create Your First Page
|
||||
|
||||
To create a new page in Typemill, follow these simple steps:
|
||||
|
||||
* Use the **interactive navigation** located on the left side of the screen.
|
||||
* **Enter a page title** for your new page into one of the grey input fields.
|
||||
* **Click the page icon** to create a new page. You can also create a folder if you want to add sub-pages later.
|
||||
|
||||
Here's a quick breakdown of the options.
|
||||
|
||||
* **Folders**: Use folders to organize your website hierarchically. Folders can contain subfolders or pages. Unlike a traditional file system, folders in Typemill can also have content, similar to pages.
|
||||
* **Pages**: Utilize pages for simple content without needing a deeper structure.
|
||||
|
||||
Additionally, you can rearrange your pages by dragging and dropping them within the navigation panel.
|
||||
|
12
content/00-getting-started/00-create-your-first-page.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
meta:
|
||||
navtitle: 'create your first page'
|
||||
title: 'Create Your First Page'
|
||||
description: "To create a new page in Typemill, follow these simple steps: \nUse the interactive navigation located on the left side of the screen. \nEnter a page title for"
|
||||
owner: trendschau
|
||||
author: 'Sebastian Schürmanns'
|
||||
modified: '2024-04-27'
|
||||
created: '2024-04-25'
|
||||
time: 17-24-48
|
||||
hide: false
|
||||
noindex: false
|
||||
template: ''
|
14
content/00-getting-started/01-edit-your-page.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Edit Your Page
|
||||
|
||||
Typemill uses [Markdown](https://typemill.net/writers/markdown) to create content. But don't worry: The visual editor of Typemill will help you write content in a WYSIWYG-style (what you see is what you get). You can also switch to the [raw-markdown-mode](/tm/content/raw/getting-started/edit-your-page) with the sticky 'raw' button located at the bottom right corner of the editor interface.
|
||||
|
||||
The content is organized in blocks, and you can move each content block up and down with drag & drop.
|
||||
|
||||
- **To edit** a content block, simply click on it.
|
||||
- **To add** a new block at the end of the page, use the edit buttons below.
|
||||
- **To add** a new block above this block, use the "add" button that appears when you hover over this block.
|
||||
|
||||
You can add all kinds of content like tables, quotes, images, files, an automatic table of contents (TOC), or YouTube videos. There are also plugins to embed media from other platforms or to use selected HTML tags in content.
|
||||
|
||||
If you are a developer, you can write plugins and integrate nearly everything into the editor with `{::]` shortcodes.
|
||||
|
9
content/00-getting-started/01-edit-your-page.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
meta:
|
||||
owner: trendschau
|
||||
author: 'Sebastian Schürmanns'
|
||||
created: '2024-04-25'
|
||||
time: 17-37-50
|
||||
navtitle: 'edit your page'
|
||||
modified: '2024-04-27'
|
||||
title: 'Edit Your Page'
|
||||
description: 'Typemill uses Markdown to create content. But don''t worry: The visual editor of Typemill will help you write content in a WYSIWYG-style (what you see is what'
|
13
content/00-getting-started/02-edit-the-page-meta.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
# Edit the Page Meta
|
||||
|
||||
You can edit detailed meta-information by switching to the meta-tab at the top of the page. While most of the meta-information should be self-explanatory, let's delve into some details:
|
||||
|
||||
- **Slug**: This is the URL. Changing the slug will alter the URL, potentially affecting indexing in search engines like Google.
|
||||
- **Navigation Title**: Change the title for the navigation.
|
||||
- **Meta Content**: Modify standard meta-tags like title and description. The image will be used when pages are shared on social media platforms and may also appear in the frontend, depending on your theme.
|
||||
- **Author**: The author will appear in the frontend (depending on the theme); the owner has the rights to edit the page.
|
||||
- **Access Rights**: You can restrict access to the page in the frontend. See the example for an [restricted page here](/tm/content/visual/publish-status/restricted).
|
||||
- **Date**: The date of creation, last publication, and a manually set date.
|
||||
- **Reference**: You can create different references for a page, such as a redirect 301 or 302 to another page, copying another page, or linking the page to an external page. These features are demonstrated in the [pages status examples](tm/content/visual/publish-status).
|
||||
- **Visibility**: Hide a page from the navigation and exclude it from the index with a noindex-tag. These features are demonstrated in the [pages status examples](tm/content/visual/publish-status).
|
||||
|
9
content/00-getting-started/02-edit-the-page-meta.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
meta:
|
||||
owner: trendschau
|
||||
author: 'Sebastian Schürmanns'
|
||||
created: '2024-04-25'
|
||||
time: 17-48-32
|
||||
navtitle: 'edit the page meta'
|
||||
modified: '2024-04-27'
|
||||
title: 'Edit the Page Meta'
|
||||
description: 'You can edit detailed meta-information by switching to the meta-tab at the top of the page. While most of the meta-information should be self-explanatory,'
|
17
content/00-getting-started/03-publish-your-page.md
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Publish Your Page
|
||||
|
||||
Is your page ready to go live? Let's publish it! In Typemill, a page can have three different statuses:
|
||||
|
||||
- **Unpublished** (red): The page is not published and not visible in the frontend yet.
|
||||
- **Published** (green): The page is published and visible in the frontend.
|
||||
- **Modified** (orange): The page is published and has changes that have not been published yet.
|
||||
|
||||
You can view and manage the status of the page in the sticky publish bar at the bottom. There, you can:
|
||||
|
||||
- **Publish** a page or publish modifications.
|
||||
- **Discard** modifications and revert content to the published version.
|
||||
- **Unpublish** a published page.
|
||||
- **Delete** a page.
|
||||
|
||||
You can also see the status of all pages in the content navigation on the left side, indicated by the colors red, orange, and green.
|
||||
|
9
content/00-getting-started/03-publish-your-page.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
meta:
|
||||
owner: trendschau
|
||||
author: 'Sebastian Schürmanns'
|
||||
created: '2024-04-25'
|
||||
time: 18-56-38
|
||||
navtitle: 'publish your page'
|
||||
modified: '2024-04-27'
|
||||
title: 'Publish Your Page'
|
||||
description: 'Is your page ready to go live? Let''s publish it! In Typemill, a page can have three different statuses:'
|
8
content/00-getting-started/index.md
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Getting Started with Typemill
|
||||
|
||||
Use this demo-content to familiarize yourself with Typemill.
|
||||
|
||||
Not sure where to start?
|
||||
|
||||
Simply select a topic in the navigation; it will briefly explain what you can do with Typemill.
|
||||
|
13
content/00-getting-started/index.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
meta:
|
||||
navtitle: 'getting started'
|
||||
title: 'Getting Started with Typemill'
|
||||
description: 'Use this demo-content to familiarize yourself with Typemill. Not sure where to start?'
|
||||
owner: trendschau
|
||||
author: 'Sebastian Schürmanns'
|
||||
modified: '2024-05-17'
|
||||
created: '2024-04-25'
|
||||
time: 13-16-58
|
||||
hide: false
|
||||
noindex: false
|
||||
contains: pages
|
||||
template: ''
|
|
@ -1,29 +0,0 @@
|
|||
# Setup Your Website
|
||||
|
||||
Typemill provides detailed settings, and you have access to nearly all settings in the author panel. Learn the basics in this short video:
|
||||
|
||||
{#7yvlwXJL9dc .youtube}
|
||||
|
||||
You will find all configurations and settings under the main navigation point `settings` with the following sub-navigation:
|
||||
|
||||
* System settings
|
||||
* Theme settings
|
||||
* Plugin settings
|
||||
* User settings
|
||||
|
||||
All settings are stored in the `\settings` folder of Typemill. It is not recommended to edit the settings manually, because it might crash the system if done wrong.
|
||||
|
||||
## Developer Settings
|
||||
|
||||
As of version 1.4.0 you will find some advanced developer settings in the author panel under `settings`. See the details below.
|
||||
|
||||
! **Only for devs**
|
||||
!
|
||||
! These options are for developers only. Make sure that you fully understand what happens. For example, you should never activate the error reporting on live systems because this is a security risk.
|
||||
|
||||
* **Error Reporting**: You can switch the error reporting of the slim-framework on and off here. This can be helpful for bug-analysis, but you should NEVER switch it on (or keep it active) on a productive system.
|
||||
* **Twig cache**: You can activate the cache for the twig templates. This will speed up the page rendering a bit, but it can also produce a headace if you changed something in your theme. The best option is to clear the cache if something does not work.
|
||||
* **Clear cache**: This will clear the cache for Twig templates and delete all cache files of Typemill. If you clear the cache, then some details might not work or look strange, for example the navigation is set back to the original state. Everything will work again when the cache has been rebuild. This happens every 10 minutes. If you want to spead up the process, then refresh your browser cache with F12 on windows machines, because it will also trigger the recreation of the Typemill cache.
|
||||
* **Image sizes**: All images in the content area will be resized to 820px width. If you want to change it, then add another value in the width-field. If you additionally add a height for your images, then the images will be resized first and then cropped to the correct aspect ratio.
|
||||
* **Proxy**: If you run Typemill behind a proxy (which is a common usecase in companies), then you can activate the proxy detection. This will read the `X-Forwarded-Proto`, `X-Forwarded-Host` and `X-Forwarded-Port` Headers and return the html with the correct urls. Optionally you can also add a comma separated list of trusted IP-addresses.
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
meta:
|
||||
title: 'Setup Your Website'
|
||||
description: 'Typemill provides detailed settings, and you have access to nearly all settings in the author panel. Learn the basics in this short video:'
|
||||
heroimage: ''
|
||||
heroimagealt: null
|
||||
owner: trendschau
|
||||
author: 'Sebastian Schürmanns'
|
||||
allowedrole: null
|
||||
alloweduser: null
|
||||
manualdate: null
|
||||
modified: '2021-08-01'
|
||||
created: '2021-05-27'
|
||||
time: 21-02-24
|
||||
navtitle: 'setup your website'
|
||||
hide: false
|
|
@ -1,32 +0,0 @@
|
|||
# Manage Access
|
||||
|
||||
Typemill has a build-in system to restrict access to pages or to the whole websites. You can activate both features in the system settings under the section "access rights". If you activate one of the features, then Typemill will use session cookies on all frontend pages. Learn all the details in the following video tutorial:
|
||||
|
||||
{#UW_m-4g1kAA .youtube}
|
||||
|
||||
## Restrict Access for the Website
|
||||
|
||||
This feature is perfect, if you want to lock down the whole website and only grant access for authenticated users. All non-authenticated users will be redirected to the login-page. There are two main use cases for this feature:
|
||||
|
||||
* **Launch the website later**: You want to create your website first and launch it to the public later, for example if you have finished the website design or if you have polished your content.
|
||||
* **Share website internally**: You want to share your typemill website only with certain users, for example with the company stuff or only with the members of your it-unit.
|
||||
|
||||
You can activate the feature with a simple checkbox under "Website Restrictions".
|
||||
|
||||
## Restrict Access for Pages
|
||||
|
||||
If you need a more fine-tuned access and if you want to restrict access only for certain pages, then you can activate the feature "Page Restrictions". If you activate this checkbox, then you will find two new input fields in the meta-tab of each page:
|
||||
|
||||
* **Minimum role for access**: Here you can select a miminum role that the user needs to view the page content. Be aware that the roles have a hierarchy, so if you choose the role "author", then the "editor" will also have access.
|
||||
* **Usernames**: Here you can add one or more usernames (separated with comma) that have access to this page.
|
||||
|
||||
If you don't choose anything of it, then the page has no restrictions and everybody can see the content.
|
||||
|
||||
You have some more features in the settings area:
|
||||
|
||||
* **Cut content**: Per default only the title of a restricted page is visible to the public, the content is hidden. You can change this and cut the content wherever you want with a horizontal line.
|
||||
* **Teaser**: You can add a standard text with markdown that will be displayed instead of the content or after the content is cut.
|
||||
* **Teaser-Box**: You can optionally wrap the teaser in a box.
|
||||
|
||||
You can also combine these features with the registration plugin and this way create a membership website with member-only content.
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
meta:
|
||||
title: 'manage access'
|
||||
description: 'Typemill has a build-in system to restrict access to pages or to the whole websites. You can activate both features in the system settings under the section "access rights". If you activate one of the features, then Typemill will use session cookies on all frontend pages.'
|
||||
owner: trendschau
|
||||
author: 'Sebastian Schürmanns'
|
||||
created: '2021-05-27'
|
||||
time: 20-59-06
|
||||
navtitle: 'manage access'
|
||||
modified: '2021-05-27'
|
|
@ -1,42 +0,0 @@
|
|||
# Write Content
|
||||
|
||||
Typemill provides easy and intuitive authoring tools and we work hard to create a good author experience. With the interactive navigation you can create pages and structure your websites. The visual markdown editor will help you to create content in a wysiwyg mode. The publish bar gives you full control over the status of each page. Watch the following video tutorial to learn all the details.
|
||||
|
||||
{#6I2-uV88GkE .youtube}
|
||||
|
||||
## The Navigation
|
||||
|
||||
You can create, structure and reorder all pages with the navigation on the left side. To structure your content, you can create new folders and files with the "add item" button. To reorder the pages, just drag an item and drop it wherever you want. Play around with it and you will notice, that it works pretty similar to the folder- and file-system of your laptop. And in fact, this is exactly what Typemill does in the background: It stores your content in files and folders on the server.
|
||||
|
||||
However, there are some limitations when you try to reorder elements. For example, you cannot move a complete folder to another folder, because this would change all the urls of the pages inside that folder, which is a nightmare for readers and search engines.
|
||||
|
||||
## The Editor
|
||||
|
||||
You can create and format your content with the Markdown syntax, that is similar to the markup syntax of Wikipedia. If you are not familiar with Markdown, then please read the short [Markdown-tutorial](https://typemill.net/) in the documentation of Typemill. You can learn Markdown in less than 10 minutes and there is no easier and faster way to format your webpage. You will love it!
|
||||
|
||||
Typemill provides two edit modes: The **raw mode** and the **visual mode**. You can switch between the modes in the publish-bar at the bottom of each page. The **raw mode** is the most robust way to create your content, because you write raw markdown into a simple textarea. The **visual mode** uses blocks and transforms each content block into a html-preview immediately. This means that you can directly see and check the formatted result.
|
||||
|
||||
By default Typemill will use the **visual mode**.
|
||||
|
||||
* You can change the default mode in the system settings.
|
||||
* You can also switch each format button on and off in the system settings.
|
||||
|
||||
## The Publish Bar
|
||||
|
||||
The publish bar of Typemill is pretty intuitiv and sticks at the bottom of the screen so that you have always full control of the status of each page. Simply play around with it and you will quickly understand how it works. In short:
|
||||
|
||||
* The green button "online" indicates, that your page is published and visible for your readers.
|
||||
* You can depublish a page by clicking the green "online" button. The button will turn gray with the label "offline" and the page is not visible for your readers anymore.
|
||||
* With the green button "Publish" you can either publish a page that is offline or you can publish some unpublished changes on your page.
|
||||
* The publish-button is gray and disabled, if the page is online and if there are no unpublished changes.
|
||||
* All buttons will change in real time, so you can always exactly see what is going on.
|
||||
* To provide an easy status-overview of the whole website, Typemill marks all pages in the navigation on the left side as published (green), changed (orange) and unpublished (red).
|
||||
|
||||
## Working with Drafts
|
||||
|
||||
Ever tried to revise a published article in WordPress? Yes, it works, but if you click on "save", then all your changes are directly live. Typemill is much more flexible here and allows you to keep your original version live while you work on a **drafted version** in the background. This is how Typemill handles it:
|
||||
|
||||
* In **visual mode**: Typemill stores your changes in a new draft automatically as soon as you save any content-block.
|
||||
* In **raw mode**: To store changes in a new draft, simply click on the "save draft"-button in the publish controller.
|
||||
* You can work on a draft as long as you want without changing the live version. Your changes go live if you click the button "publish".
|
||||
* In visual mode, you can also use the discard-button and go back to the published version.
|
|
@ -1,23 +0,0 @@
|
|||
meta:
|
||||
title: 'Write Content'
|
||||
description: 'Typemill is a simple Flat File Content Management System (CMS). We (the community) work hard to provide the best author experience with easy and intuitive authoring tools. But Typemill is still in early development and it is likely that not everything will work perfectly out of the box.'
|
||||
heroimage: ''
|
||||
heroimagealt: 'Hero Alternative'
|
||||
owner: null
|
||||
author: 'Sebastian Schürmanns'
|
||||
manualdate: null
|
||||
modified: '2021-01-30'
|
||||
created: null
|
||||
time: null
|
||||
navtitle: ''
|
||||
hide: false
|
||||
allowedrole: administrator
|
||||
alloweduser: 'trendschau, testmember'
|
||||
seo:
|
||||
heroimage: media/live/bildschirmfoto-zu-2019-08-30-20-46-29.png
|
||||
heroimagealt: 'My Alt-Text'
|
||||
adamhall:
|
||||
myfield:
|
||||
-
|
||||
key: b
|
||||
value: 'Das muss eine schöne Sache sei'
|
|
@ -1,12 +0,0 @@
|
|||
# Get Help
|
||||
|
||||
If you need any help, then please read the [documentation on typemill.net](https://typemill.net/typemill) first. You can also check these [video-tutorials](https://www.youtube.com/channel/UCyghKiX2kK9QIqTf1WT1Xxw) about the basics to create a typemill website.
|
||||
|
||||
If you found a bug or if you have a question, then please open a new issue on [GitHub](https://github.com/typemill/typemill/issues).
|
||||
|
||||
Do you need professional help, an individual theme or a special plugin? You can hire us at [Trendschau Digital](https://trendschau.net/typemill-development).
|
||||
|
||||
[Contributions](https://github.com/typemill/typemill#contributors--supporters), [donations](https://www.paypal.me/typemill) and [feedback](https://github.com/typemill/typemill/issues) for this open source project are always welcome.
|
||||
|
||||
{.center loading="lazy"}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
meta:
|
||||
title: 'Get Help'
|
||||
description: 'If you need any help, then please read the documentation on typemill.net first. Some short video-tutorials are in work right'
|
||||
heroimage: null
|
||||
heroimagealt: null
|
||||
owner: null
|
||||
author: 'Sebastian Schürmanns'
|
||||
allowedrole: null
|
||||
alloweduser: null
|
||||
manualdate: null
|
||||
modified: '2021-06-13'
|
||||
created: null
|
||||
time: null
|
||||
navtitle: ''
|
||||
hide: false
|
||||
seo:
|
||||
heroimage: media/live/bildschirmfoto-zu-2019-08-30-20-46-29.png
|
||||
heroimagealt: Alt-Text
|
||||
customfields:
|
||||
myfield:
|
||||
bla:
|
||||
- text
|
||||
- test
|
|
@ -1,336 +0,0 @@
|
|||
# Markdown Reference and Test Page
|
||||
|
||||
Markdown is a simple and universal syntax for text formatting. More and more writers switch to markdown, because they can format their text during the writing process without using any format-buttons. Once they are familiar with the markdown syntax, they can write formatted text much easier and faster than with any standard HTML-editor.
|
||||
|
||||
Developers love markdown, because it is much cleaner and saver than HTML. And they can easily convert markdown to a lot of other document formats like HTML and others.
|
||||
|
||||
If you develop a theme for TYPEMILL, please take care that all elements on this page are designed properly.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
To create a table of contents, simply write `[TOC]` in a separate line. It will be replaced with a table of contents like this automatically.
|
||||
|
||||
[TOC]
|
||||
|
||||
## Headlines
|
||||
|
||||
```
|
||||
Headlines are simply done with hash chars like this:
|
||||
# First Level Headline
|
||||
## Second Level Headline
|
||||
### Third Level Headline
|
||||
#### Fourth Level Headline
|
||||
##### Fifth Level Headline
|
||||
###### Sixth Level Headline
|
||||
```
|
||||
|
||||
### Third Level Headline
|
||||
|
||||
A third headline is more decent and lower prioritized than a second level headline.
|
||||
|
||||
#### Fourth Level Headline
|
||||
|
||||
A fourth level headline is more decent and lower prioritized than a third level headline.
|
||||
|
||||
##### Fifth Level Headline
|
||||
|
||||
A fifth level headline is more decent and lower prioritized than a fourth level headline.
|
||||
|
||||
##### Sixth Level Headline
|
||||
|
||||
A sixth level headline is more decent and lower prioritized than a fifths level headline.
|
||||
|
||||
##Paragraph
|
||||
|
||||
````
|
||||
A paragraph is a simple text-block separated with a new line above and below.
|
||||
````
|
||||
|
||||
A paragraph is a simple text-block separated with a new line above and below.
|
||||
|
||||
## Soft Linebreak
|
||||
|
||||
````
|
||||
For a soft linebreak (eg. for dialoges in literature), add two spaces at the end of a line and use a simple return.
|
||||
She said: "Hello"
|
||||
He said: "again"
|
||||
````
|
||||
|
||||
For a soft linebreak (eg. for dialoges in literature), add two spaces at the end of a line and use a simple return.
|
||||
|
||||
She said: "Hello"
|
||||
He said: "again"
|
||||
|
||||
##Emphasis
|
||||
|
||||
````
|
||||
For italic text use one *asterix* or one _underscore_.
|
||||
For bold text use two **asterix** or two __underscores__.
|
||||
````
|
||||
|
||||
For italic text use one *asterix* or one _underscore_.
|
||||
|
||||
For bold text use two **asterix** or two __underscores__.
|
||||
|
||||
##Lists
|
||||
|
||||
````
|
||||
For an unordered list use a dash
|
||||
- like
|
||||
- this
|
||||
Or use one asterix
|
||||
* like
|
||||
* this
|
||||
For an ordered list use whatever number you want and add a dot:
|
||||
1. like
|
||||
1. this
|
||||
````
|
||||
|
||||
For an unordered list use a dash
|
||||
|
||||
- like
|
||||
- this
|
||||
|
||||
Or use one asterix
|
||||
|
||||
* like
|
||||
* this
|
||||
|
||||
For an ordered list use whatever number you want and add a dot:
|
||||
|
||||
1. like
|
||||
2. this
|
||||
|
||||
## Horizontal Rule
|
||||
|
||||
```
|
||||
Easily created for example with three dashes like this:
|
||||
---
|
||||
```
|
||||
|
||||
Easily created for example with three dashes like this:
|
||||
|
||||
---
|
||||
|
||||
##Links
|
||||
|
||||
````
|
||||
This is an ordinary [Link](http://typemill.net).
|
||||
Links can also be [relative](/info).
|
||||
You can link to anchors like this [anchor](#images)
|
||||
You can also add a [title](http://typemill.net "typemill").
|
||||
You can even add [ids or classes](http://typemill.net){#myid .myclass}.
|
||||
Or you can use a shortcut like http://typemill.net.
|
||||
You can even use a download-link like []()
|
||||
````
|
||||
|
||||
This is an ordinary [Link](http://typemill.net).
|
||||
|
||||
Links can also be [relative](/info).
|
||||
|
||||
You can link to anchors like this [anchor](#images)
|
||||
|
||||
You can also add a [title](http://typemill.net "typemill").
|
||||
|
||||
You can even add [ids or classes](http://typemill.net){#myid .myclass}.
|
||||
|
||||
Or you can use a shortcut like http://typemill.net.
|
||||
|
||||
[markdown (PNG, 1.05 KB)](media/files/markdown.png){.tm-download file-png}
|
||||
|
||||
##Images
|
||||
|
||||
````
|
||||
The same rules as with links, but with a !
|
||||

|
||||
*With caption*
|
||||
{#myid .imgClass}
|
||||
*With caption that spans over several lines*
|
||||
{#myid .otherclass width=150px}
|
||||
````
|
||||
|
||||
The same rules as with links, but with a !
|
||||
|
||||
{.center}
|
||||
*With Caption*
|
||||
|
||||
{.center}
|
||||
*With a caption that spans over several lines.*
|
||||
|
||||
{#myid .otherclass width=150px}
|
||||
|
||||
## Linked Images
|
||||
|
||||
````
|
||||
You can link an image with a nested syntax like this:
|
||||
[](https://typemill.net)
|
||||
````
|
||||
|
||||
You can link an image with a nested syntax like this:
|
||||
|
||||
[{.imgClass}](https://typemill.net)
|
||||
|
||||
## Image Position
|
||||
|
||||
````
|
||||
You can controll the image position with the classes .left, .right and .middle like this:
|
||||
{.left}
|
||||
*With caption that spans over several lines*
|
||||
{.right}
|
||||
*With caption that spans over several lines*
|
||||
{.center}
|
||||
*With caption that spans over several lines*
|
||||
````
|
||||
|
||||
{.left}
|
||||
*With caption that spans over several lines*
|
||||
|
||||
The first image should float on the left side of this paragraph. This might not work with all themes. If you are a theme developer, please ensure that you support the image classes "left", "right" and "center". You can add these classes manually in the raw mode or you can assign them in the visual mode when you edit a picture (double click on it to open the dialog). Images in a separate line are rendered with the html5 elements `figure` and `figcapture`.
|
||||
|
||||
{.right}
|
||||
*With caption that spans over several lines*
|
||||
|
||||
The second image should float on the right side of this paragraph. This might not work with all themes. If you are a theme developer, please ensure that you support the image classes "left", "right" and "center". You can add these classes manually in the raw mode or you can assign them in the visual mode when you edit a picture (double click on it to open the dialog). Images in a separate line are rendered with the html5 elements `figure` and `figcapture`.
|
||||
|
||||
{.center}
|
||||
*With caption that spans over several lines*
|
||||
|
||||
The thirds image should be placed above this paragraph and centered to the middle of the content area. This might not work with all themes. If you are a theme developer, please ensure that you support the image classes "left", "right" and "center". You can add these classes manually in the raw mode or you can assign them in the visual mode when you edit a picture (double click on it to open the dialog). Images in a separate line are rendered with the html5 elements `figure` and `figcapture`.
|
||||
|
||||
## Blockquote
|
||||
|
||||
```
|
||||
There are always some women and men with wise words
|
||||
> But I usually don't read them, to be honest.
|
||||
```
|
||||
|
||||
There always some women and men with wise words
|
||||
|
||||
> But I usually don't read them, to be honest.
|
||||
|
||||
##Footnotes
|
||||
|
||||
````
|
||||
You can write footnotes[^1] with markdown.
|
||||
Scroll down to the end of the page[^2] and look for the footnotes.
|
||||
Add the footnote text at the bottom of the page like this:
|
||||
[^1]: Thank you for scrolling.
|
||||
[^2]: This is the end of the page.
|
||||
````
|
||||
|
||||
You can write footnotes[^1] with markdown.
|
||||
|
||||
Scroll down to the end of the page[^2] and look for the footnotes.
|
||||
|
||||
Footnotes won't work with the visual editor right now, so please use the raw mode for them.
|
||||
|
||||
## Abbreviations
|
||||
|
||||
````
|
||||
*[HTML]: Hyper Text Markup Language
|
||||
*[W3C]: World Wide Web Consortium
|
||||
````
|
||||
|
||||
You won't see the abbreviation directly, but if you write HTML or W3C somewhere, then you can see the tooltip with the explanation.
|
||||
|
||||
*[HTML]: Hyper Text Markup Language
|
||||
|
||||
*[W3C]: World Wide Web Consortium
|
||||
|
||||
## Definition List
|
||||
|
||||
````
|
||||
Apple
|
||||
: Pomaceous fruit of plants of the genus Malus in the family Rosaceae.
|
||||
Orange
|
||||
: The fruit of an evergreen tree of the genus Citrus.
|
||||
````
|
||||
|
||||
Apple
|
||||
: Pomaceous fruit of plants of the genus Malus in
|
||||
the family Rosaceae.
|
||||
|
||||
Orange
|
||||
: The fruit of an evergreen tree of the genus Citrus.
|
||||
|
||||
|
||||
|
||||
## Notices
|
||||
|
||||
You can create different notices if you add a '!', '!!', '!!!', '!!!!' before a line. This will wrap the content into a div-class with the classes `notice1`, `notice2`, `notice3` and `notice4`. You can also span notices over several lines. This logic follows some other CMS like Grav, Lektor or Yellow and it is not compatible with other markdown processors or editors.
|
||||
|
||||
! Notice 1
|
||||
!
|
||||
! Please note that you can use **markdown** inside of the notice so you can *format* your text here.
|
||||
|
||||
!! Notice 2
|
||||
!!
|
||||
!! Please note that you can use **markdown** inside of the notice so you can *format* your text here.
|
||||
|
||||
!!! Notice 3
|
||||
!!!
|
||||
!!! Please note that you can use **markdown** inside of the notice so you can *format* your text here.
|
||||
|
||||
## Tables
|
||||
|
||||
````
|
||||
|name |usage |
|
||||
|-----------|-----------|
|
||||
| My Name | For Me |
|
||||
| Your Name | For You |
|
||||
````
|
||||
|
||||
| Name | Usage |
|
||||
| --------- | ------- |
|
||||
| My Name | For Me |
|
||||
| Your Name | For You |
|
||||
|
||||
## Code
|
||||
|
||||
````
|
||||
Let us create some `<?php inlineCode(); ?>` like this
|
||||
````
|
||||
|
||||
Let us create some `<?php inlineCode(); ?>` and now let us check, if a codeblock works:
|
||||
|
||||
````
|
||||
Use four apostroph like this:
|
||||
\````
|
||||
<?php
|
||||
$welcome = 'Hello World!';
|
||||
echo $welcome;
|
||||
?>
|
||||
\````
|
||||
````
|
||||
|
||||
## Math
|
||||
|
||||
Please activate the math-plugin to use mathematical expressions with LaTeX syntax. You can choose between MathJax or the newer KaTeX library. MathJax is included from a CDN, KaTeX is included in the plugin. So if you don't want to fetch code from a CDN, use KaTeX instead. The markdown syntax in TYPEMILL is the same for both libraries.
|
||||
|
||||
````
|
||||
Write inline math with \(...\) or $...$ syntax.
|
||||
inline $x = \int_{0^1}^1(-b \pm \sqrt{b^2-4ac})/(2a)$ math
|
||||
inline \(x = \int_{0^1}^1(-b \pm \sqrt{b^2-4ac})/(2a)\) math
|
||||
````
|
||||
|
||||
inline $x = \int_{0^1}^1(-b \pm \sqrt{b^2-4ac})/(2a)$ math
|
||||
|
||||
inline \(x = \int_{0^1}^1(-b \pm \sqrt{b^2-4ac})/(2a)\) math
|
||||
|
||||
````
|
||||
Write display math with $$...$$ or \[...\] syntax.
|
||||
$$
|
||||
x = \int_{0^1}^1(-b \pm \sqrt{b^2-4ac})/(2a)
|
||||
$$
|
||||
\[
|
||||
x = \int_{0^1}^1(-b \pm \sqrt{b^2-4ac})/(2a)
|
||||
\]
|
||||
````
|
||||
|
||||
$$
|
||||
x = \int_{0^1}^1(-b \pm \sqrt{b^2-4ac})/(2a)
|
||||
$$
|
||||
|
||||
[^1]: Thank you for scrolling.
|
||||
[^2]: This is the end of the page.
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
meta:
|
||||
title: 'Markdown Reference and Test Page'
|
||||
description: 'Markdown is a simple and universal syntax for text formatting. More and more writers switch to markdown, because they can format their text during the writing process without using any format-buttons. '
|
||||
author: 'Sebastian Schürmanns'
|
||||
manualdate: '2020-02-22'
|
||||
modified: '2020-01-20'
|
||||
created: null
|
||||
time: 04-40-32
|
||||
navtitle: ''
|
||||
hide: false
|
||||
ebooks:
|
||||
layout: electric
|
||||
content:
|
||||
-
|
||||
name: 'markdown test'
|
|
@ -1,4 +0,0 @@
|
|||
# Welcome
|
||||
|
||||
Great that you give Typemill a try!! Typemill is a simple Flat File Content Management System (CMS). We (the community) work hard to provide the best author experience with easy and intuitive authoring tools. But Typemill is still in early development and it is likely that not everything will work perfectly out of the box. If you miss something or if you have ideas for improvements, then post a new issue on [GitHub](https://github.com/typemill/typemill/issues).
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
# The Landingpage
|
||||
|
||||
Cyanine provides an optional landingpage with six segments:
|
||||
|
||||
* **Intro** with the content of the home page and an additional link/button.
|
||||
* **Info** with individual markdown content.
|
||||
* **Teaser** with two elements. Each element has a headline, a text and a link/button.
|
||||
* **Contrast** with a headline, text-input and a link/button. The colors are inverted.
|
||||
* **Navigation** with the whole content of the website. You can change the depth of the navigation.
|
||||
* **News** with a link to a news-folder. It will display the three latest news in a card-design. Add a hero-image to each news-entry to show a teaser image.
|
||||
|
||||
You can activate or deactivate the whole landingpage, order all elements and enable/disable each element individually.
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
# Colors and Fonts
|
||||
|
||||
First of all cyanine supports individual logos. If you want to use our logo, then please upload it in the system settings. Cyanine will automatically replace the title text with your logo. You can also upload your own favicon in the system settings.
|
||||
|
||||
Cyanine allows you to change many colors. Please make sure that your color-combinations are readable and accessible. The following colors are editable:
|
||||
|
||||
* **Primary Theme Color**: used for the body background and borders.
|
||||
* **Secondary Theme Color**: used for content background, font-colors on hover and more.
|
||||
* **Primary Font Color**: used for main text.
|
||||
* **Secondary Font Color**: used as contrast color for hovers in navigation and buttons.
|
||||
* **Link Color**: used for text-links. Keep accessibility in mind.
|
||||
* **Thin Border Color**: used for thin borders in navigations and tables.
|
||||
|
||||
You can also change the font-family for
|
||||
|
||||
* headlines
|
||||
* text
|
||||
* buttons and navigations
|
||||
|
||||
Cyanine uses wide spread system fonts with fallbacks:
|
||||
|
||||
* serif
|
||||
* sans-serif
|
||||
* courier
|
||||
* helvetica
|
||||
* avenir
|
||||
* athelas
|
||||
* georgia
|
||||
* times
|
||||
* bodoni
|
||||
* calisto
|
||||
* garamond
|
||||
* baskerville
|
||||
|
||||
If the color- and font-settings are not enough for your purpose, then you can always overwrite the theme-css with your own styles in the theme settings.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
# 3-Column Footer
|
||||
|
||||
Cyanine provides a three column footer at the bottom of each page. You can use markdown for each column. Make sure that you use the correct headline-level (we suggest a headline level 3 or level 4 to keep the logical headline hierarchy in the document). You can, of course, also add link-lists or other elements. Check the website of [Typemill](https://typemill.net) for an example.
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
# Content Elements
|
||||
|
||||
Cyanine provides a lot of other settings for your content area. For example:
|
||||
|
||||
* Add an edit-button for github, gitlab or other plattforms.
|
||||
* Show the author.
|
||||
* Show the publish date.
|
||||
* Show the chapter numbers in the navigation.
|
||||
|
||||
The Cyanine theme supports all content elements like tables, images, notices or downloads. It also supports anchor-links next to headlines, so you can deep link to certain content sections of your page. You can activate the anchors in the system settings of Typemill.
|
|
@ -1,6 +0,0 @@
|
|||
# The Cyanine Theme
|
||||
|
||||
Cyanine is the modern, lightweight and flexible standard theme for Typemill. You can activate a landingpage, setup different content sections for the landingpage and order them like you want. You can also change the colors, fonts and other details. To configure the theme, login to the system (/tm/login), go to the theme settings (/tm/themes) and choose the theme "Cyanine".
|
||||
|
||||
If Cyanine does not fit to your needs, then you can also choose another theme in the [theme store](https://themes.typemill.net) of Typemill.
|
||||
|
1
content/01-publish-status/00-unpublished.txt
Normal file
|
@ -0,0 +1 @@
|
|||
["# Unpublished Page","This is an unpublished page. Unpublished pages are marked red in the navigation and in the publish bar."]
|
6
content/01-publish-status/00-unpublished.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
meta:
|
||||
owner: typemill
|
||||
author: ''
|
||||
created: '2024-03-19'
|
||||
time: 18-40-21
|
||||
navtitle: unpublished
|
4
content/01-publish-status/01-modified.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Modified Page
|
||||
|
||||
This is a modified page. Modified pages are marked orange in the navigation and in the publish bar. Modified pages are published pages that have been modified in the editor. The published page is still online in the original version. You can publish the mofidifications to make them visible in the frontend, or you can discard the changes to restore the published version. If you discard your changes, then your changes are lost and cannot be restored.
|
||||
|
1
content/01-publish-status/01-modified.txt
Normal file
|
@ -0,0 +1 @@
|
|||
["# Modified Page","This is a modified page. Modified pages are marked orange in the navigation and in the publish bar. Modified pages are published pages that have been modified in the editor. The published page is still online in the original version. You can publish the mofidifications to make them visible in the frontend, or you can discard the changes to restore the published version. If you discard your changes, then your changes are lost and cannot be restored.","A page becomes modified if you either:","* Save a block in the visual editor or\n* Save a draft in the raw editor."]
|
9
content/01-publish-status/01-modified.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
meta:
|
||||
owner: typemill
|
||||
author: ''
|
||||
created: '2024-03-19'
|
||||
time: 18-40-27
|
||||
navtitle: modified
|
||||
modified: '2024-03-19'
|
||||
title: 'Modified Page'
|
||||
description: 'This is a modified page. Modified pages are marked orange in the navigation and in the publish bar. Modified pages are published pages that have been modified'
|
4
content/01-publish-status/02-published.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Published Page
|
||||
|
||||
This is a published page. Published pages are marked green in the navigation and in the publish bar. Published pages are visible in the frontend unless they are not restricted. Published pages are visible in the navigation unless they are not hidden. Published pages are added to the xml-sitemap and alowed to crawl unless they are not marked as noindex.
|
||||
|
9
content/01-publish-status/02-published.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
meta:
|
||||
owner: typemill
|
||||
author: ''
|
||||
created: '2024-03-19'
|
||||
time: 18-40-40
|
||||
navtitle: published
|
||||
modified: '2024-03-19'
|
||||
title: 'Published Page'
|
||||
description: 'This is a published page. Published pages are marked green in the navigation and in the publish bar. Published pages are visible in the frontend unless they'
|
6
content/01-publish-status/03-hidden.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Hidden Page
|
||||
|
||||
This is a hidden page. Hidden pages are published pages that are excluded from all navigation elements. You need to know the url to visit a hidden page. Hidden pages are great if you want to check your page in the frontend without beeing visible for visitors directly. Hidden pages are not excluded from the xml-sitemap and they do not have a noindex attribute.
|
||||
|
||||
You can hide pages with a checkbox in the meta-tab (sroll to the bottom).
|
||||
|
11
content/01-publish-status/03-hidden.yaml
Normal file
|
@ -0,0 +1,11 @@
|
|||
meta:
|
||||
navtitle: hidden
|
||||
title: 'Hidden Page'
|
||||
description: 'This is a hidden page. Hidden pages are published pages that are excluded from all navigation elements. You need to know the url to visit a hidden page. Hidden'
|
||||
owner: typemill
|
||||
author: ''
|
||||
modified: '2024-03-19'
|
||||
created: '2024-03-19'
|
||||
time: 18-49-34
|
||||
hide: true
|
||||
noindex: false
|
4
content/01-publish-status/04-noindex.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Noindex Page
|
||||
|
||||
This page is excluded from the xml-sitemap (see url of the xml-sitemap in the system settings) and the page has a noindex-attribute to stop robots from crawling and indexing. You can activate the noindex in the meta-tab (scroll to the bottom).
|
||||
|
11
content/01-publish-status/04-noindex.yaml
Normal file
|
@ -0,0 +1,11 @@
|
|||
meta:
|
||||
navtitle: noindex
|
||||
title: 'Noindex Page'
|
||||
description: 'This page is excluded from the xml-sitemap (see url of the xml-sitemap in the system settings) and the page has a noindex-attribute to stop robots from'
|
||||
owner: typemill
|
||||
author: ''
|
||||
modified: '2024-03-19'
|
||||
created: '2024-03-19'
|
||||
time: 18-54-12
|
||||
noindex: true
|
||||
hide: false
|
11
content/01-publish-status/05-restricted.md
Normal file
|
@ -0,0 +1,11 @@
|
|||
# Restricted Page
|
||||
|
||||
This is a restricted page (to activate the feature please read the paragraph below). Restricted pages are published pages that require an authentication to see the content. You can cut the content with a hr-line, everything below this line is not visible in frontend for unauthenticated users.
|
||||
|
||||
---
|
||||
|
||||
You can configure page restrictions in the system settings. Open the tab "restrictions" and choose the options. You can restrict the whole website or you can restrict certain pages. To restrict certain pages, go to the meta-tab of a page and scroll down to the section "Access & Rights". There you have two options:
|
||||
|
||||
* You can choose a userrole that should have access to the content.
|
||||
* Or you can add one or several usernames who should have access to the content.
|
||||
|
12
content/01-publish-status/05-restricted.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
meta:
|
||||
navtitle: restricted
|
||||
owner: typemill
|
||||
author: ''
|
||||
allowedrole: member
|
||||
created: '2024-03-19'
|
||||
time: 18-56-07
|
||||
hide: false
|
||||
noindex: false
|
||||
modified: '2024-03-19'
|
||||
title: 'Restricted Page'
|
||||
description: 'This is a restricted page. Restricted pages are published pages that require an authentication to see the content. You can cut the content with a hr-line,'
|
4
content/01-publish-status/06-redirect-301.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Redirect 301
|
||||
|
||||
This page redirects to the page "published" with a 301 permanent redirect. You can choose this option in the meta-tab, section "References".
|
||||
|
13
content/01-publish-status/06-redirect-301.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
meta:
|
||||
navtitle: 'redirect 301'
|
||||
owner: typemill
|
||||
author: ''
|
||||
created: '2024-03-19'
|
||||
time: 19-00-58
|
||||
reference: /publish-status/published
|
||||
referencetype: redirect301
|
||||
hide: false
|
||||
noindex: false
|
||||
modified: '2024-03-19'
|
||||
title: 'Redirect 301'
|
||||
description: 'This page redirects to another page with a 301 permanent redirect. You can choose this option in the meta-tab, section "References".'
|
4
content/01-publish-status/07-redirect-302.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Redirect 302
|
||||
|
||||
This page redirects to the page "published" with a 302 temporary redirect. You can choose this option in the meta-tab, section "References".
|
||||
|
13
content/01-publish-status/07-redirect-302.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
meta:
|
||||
navtitle: 'redirect 302'
|
||||
owner: typemill
|
||||
author: ''
|
||||
created: '2024-03-19'
|
||||
time: 19-02-36
|
||||
reference: /publish-status/published
|
||||
referencetype: redirect302
|
||||
hide: false
|
||||
noindex: false
|
||||
modified: '2024-03-19'
|
||||
title: 'Redirect 302'
|
||||
description: 'This page redirects to the published page with a 302 temporary redirect. You can choose this option in the meta-tab, section "References".'
|
4
content/01-publish-status/08-copy.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Copy
|
||||
|
||||
You can copy the content of another page to this page. This is helpful in some cases if you want to reference the content in several other navigation points on the website. You can edit the referenced page and all referenced sites will show that content. You can copy the page of another page in the meta-tab, section "references".
|
||||
|
13
content/01-publish-status/08-copy.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
meta:
|
||||
navtitle: copy
|
||||
owner: typemill
|
||||
author: ''
|
||||
created: '2024-03-19'
|
||||
time: 19-03-54
|
||||
reference: /publish-status/published
|
||||
referencetype: copy
|
||||
hide: false
|
||||
noindex: false
|
||||
modified: '2024-03-19'
|
||||
title: Copy
|
||||
description: 'You can copy the content of another page to this page. This is helpful in some cases if you want to reference the content in several other navigation points on'
|
4
content/01-publish-status/09-link.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# External link
|
||||
|
||||
You can link to an external page in the navigation with the reference feature in the meta-tab. Just choose "link" and add the url to the external page.
|
||||
|
13
content/01-publish-status/09-link.yaml
Normal file
|
@ -0,0 +1,13 @@
|
|||
meta:
|
||||
navtitle: link
|
||||
title: 'External link'
|
||||
description: 'You can link to an external page in the navigation with the reference feature in the meta-tab. Just choose "link" and add the url to the external page.'
|
||||
owner: typemill
|
||||
author: ''
|
||||
modified: '2024-03-19'
|
||||
created: '2024-03-19'
|
||||
time: 19-07-05
|
||||
reference: 'https://typemill.net'
|
||||
referencetype: outlink
|
||||
hide: false
|
||||
noindex: false
|
14
content/01-publish-status/index.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Publish Status
|
||||
|
||||
In Typemill you can save drafts, publish pages, unpublish pages, and delete pages with a sticky publish panel at the bottom of each page. For published pages, you can also save modifications, discard modifications and publish modifications.
|
||||
|
||||
The current status of the page is indicated with colors in the publish panel and in the navigation. This way, an author can always see the status of each page and the current state of the whole website.
|
||||
|
||||
* **Save a draft**: The page is not published and not accessible in the frontend. The status color is red.
|
||||
* **Publish a page**: The page is published and accessible in the frontend. The status color is green.
|
||||
* **Unpublish a page**: The page is not accessible in the frontend and only accessible in the author interface. The status color is red again.
|
||||
* **Delete a page**: The page is completely deleted in frontend and in the author interface.
|
||||
* **Save modivications**: The page is published and accessible in the frontend. The modified draft is only visible in the author interface. The status color is orange.
|
||||
* **Discard modifications**: The modifications are deleted and the live version is restored in the author interface. The status color is green again.
|
||||
* **Publish modifications**: The modifications are published to the live version. The status color is green again.
|
||||
|
12
content/01-publish-status/index.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
meta:
|
||||
navtitle: 'page status'
|
||||
title: 'Publish Status'
|
||||
description: 'In Typemill you can save drafts, publish pages, unpublish pages, and delete pages with a sticky publish panel at the bottom of each page. For published pages,'
|
||||
owner: typemill
|
||||
author: ''
|
||||
modified: '2024-03-19'
|
||||
created: '2024-03-19'
|
||||
time: 18-40-10
|
||||
contains: pages
|
||||
hide: false
|
||||
noindex: false
|
22
content/02-news/202405171834-fast-websites.md
Normal file
|
@ -0,0 +1,22 @@
|
|||
# Fast Websites
|
||||
|
||||
Typemill is a lightweight, flat-file CMS specifically designed for efficient web publishing. It excels in creating documentation, manuals, knowledge bases, wikis, and eBooks. Its performance-driven architecture ensures rapid page loading and a streamlined user experience.
|
||||
|
||||
## Performance Features
|
||||
|
||||
1. **Full Points for Google Page Speed**: Typemill websites typically achieve perfect scores on Google PageSpeed Insights without additional optimizations. This is due to its optimized code, lightweight architecture, and refined frontend code.
|
||||
2. **SEO Benefits**: The excellent performance makes Typemill a great choice for SEO. Additionally, it offers an SEO plugin that integrates data from Google Search Console, providing valuable insights for optimizing content.
|
||||
3. **Efficient Workflow**: With its simple approach and excellent user experience, website managers and authors can accomplish tasks quickly and efficiently.
|
||||
|
||||
## Benefits
|
||||
|
||||
- **Quick Setup and Maintenance**: Typemill's straightforward installation and lack of a database simplify setup and maintenance.
|
||||
- **Scalability**: The flat-file approach ensures consistent performance even as the site grows.
|
||||
- **SEO Friendly**: Fast loading times and SEO tools contribute to better search engine rankings, improving visibility.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Typemill is an ideal choice for small to medium-sized websites focused on documentation and knowledge management. Its flat-file structure, lightweight design, and optimized performance make it a robust solution for fast and reliable web publishing.
|
||||
|
||||
For more information, visit [Typemill](https://typemill.net).
|
||||
|
12
content/02-news/202405171834-fast-websites.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
meta:
|
||||
navtitle: 'Fast Websites'
|
||||
title: 'Fast Websites'
|
||||
description: 'Typemill is a lightweight, flat-file CMS specifically designed for efficient web publishing. It excels in creating documentation, manuals, knowledge bases,'
|
||||
heroimage: ''
|
||||
owner: trendschau
|
||||
author: 'Sebastian Schürmanns'
|
||||
modified: '2024-05-17'
|
||||
created: '2024-05-17'
|
||||
time: 18-34-46
|
||||
hide: false
|
||||
noindex: false
|
33
content/02-news/202405171843-reports-and-handbooks.md
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Reports and Handbooks
|
||||
|
||||
Small organizations often face the challenge of producing and publishing annual reports, impact reports, and other essential documents efficiently. Typemill offers an excellent solution by enabling users to create content once and publish it both as a website and a PDF. This not only saves time but also reduces costs, making it an ideal choice for small organizations.
|
||||
|
||||
## Save Time: Write Once, Publish Twice
|
||||
|
||||
One of the standout features of Typemill is its ability to streamline the reporting process. By creating your report in Typemill, you can effortlessly generate both a web-based version and a PDF version from the same source. This dual-publishing capability is particularly beneficial for:
|
||||
|
||||
- **Annual Reports**: Showcase your organization's yearly achievements online and provide a downloadable PDF for stakeholders.
|
||||
- **Impact Reports**: Highlight the impact of your projects with an engaging web presentation and a formal PDF document.
|
||||
|
||||
## Cost-Effective Solution
|
||||
|
||||
Using Typemill helps small organizations save money by minimizing the need for separate tools and platforms for web and print publishing. The simple and intuitive interface ensures that staff can quickly learn and use the system, further reducing training and operational costs.
|
||||
|
||||
## Versatile Use Cases
|
||||
|
||||
Beyond reporting, Typemill is perfect for creating various handbooks and company documents. Some additional use cases include:
|
||||
|
||||
- **Employee Handbooks**: Develop comprehensive, web-based employee manuals that are easy to update and accessible to all staff members.
|
||||
- **Company Policies and Procedures**: Maintain a centralized repository of policies and procedures that can be viewed online and downloaded as needed.
|
||||
- **Training Manuals**: Create detailed training materials that are available both as interactive web pages and printable PDFs.
|
||||
|
||||
## Templates for Speed
|
||||
|
||||
Typemill allows you to load pre-made reporting templates and store your own templates to further speed up the reporting process. This feature ensures consistency and saves time, enabling you to focus more on content creation and less on formatting.
|
||||
|
||||
## Conclusion
|
||||
|
||||
For small organizations and companies looking to optimize their reporting and documentation processes, Typemill offers an efficient, cost-effective solution. Its ability to produce both web and PDF versions of reports from a single source not only saves time but also ensures consistency across formats. Additionally, its versatility in creating various handbooks and company documents makes it an invaluable tool for any small organization.
|
||||
|
||||
Explore more about Typemill and how it can benefit your organization at [Typemill](https://typemill.net).
|
||||
|
12
content/02-news/202405171843-reports-and-handbooks.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
meta:
|
||||
navtitle: 'Reports and Handbooks'
|
||||
title: 'Reports and Handbooks'
|
||||
description: 'Small organizations often face the challenge of producing and publishing annual reports, impact reports, and other essential documents efficiently. Typemill'
|
||||
heroimage: ''
|
||||
owner: trendschau
|
||||
author: 'Sebastian Schürmanns'
|
||||
modified: '2024-05-17'
|
||||
created: '2024-05-17'
|
||||
time: 18-43-57
|
||||
hide: false
|
||||
noindex: false
|
18
content/02-news/202405171855-documentations-and-manuals.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Documentations and Manuals
|
||||
|
||||
Small companies often need to create comprehensive documentation and manuals for both digital and physical products. Typemill offers an ideal solution, allowing you to effortlessly produce manuals as both PDFs and websites.
|
||||
|
||||
## Intuitive Authoring Experience
|
||||
|
||||
Typemill is designed with non-technical writers in mind, featuring an intuitive author interface and a WYSIWYG-style Markdown editor. This makes it easy for anyone to create and maintain high-quality documentation.
|
||||
|
||||
## Versatility and Efficiency
|
||||
|
||||
Whether you’re documenting a software application or a physical product, Typemill enables you to manage your content efficiently and publish it in multiple formats. This versatility ensures that your documentation is always accessible and up-to-date.
|
||||
|
||||
### Conclusion
|
||||
|
||||
Typemill stands out among many tools for documentation and manuals due to its ease of use and powerful features. It's the perfect choice for small companies looking to streamline their documentation process.
|
||||
|
||||
Explore more about Typemill and how it can benefit your organization at [Typemill](https://typemill.net).
|
||||
|
12
content/02-news/202405171855-documentations-and-manuals.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
meta:
|
||||
navtitle: 'Documentations and Manuals'
|
||||
title: 'Documentations and Manuals'
|
||||
description: 'Small companies often need to create comprehensive documentation and manuals for both digital and physical products. Typemill offers an ideal solution,'
|
||||
heroimage: media/live/favicon-180x180.png
|
||||
owner: trendschau
|
||||
author: 'Sebastian Schürmanns'
|
||||
modified: '2024-05-17'
|
||||
created: '2024-05-17'
|
||||
time: 18-55-26
|
||||
hide: false
|
||||
noindex: false
|
4
content/02-news/index.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
# News or Blog
|
||||
|
||||
You can add one or many news- or blog-sections to your website. Simply create a new folder and change the content of the folder from "pages" to "posts" in the meta-tab. You can also transform a folder with pages into a folder with posts and vice versa. The only difference between posts and pages is the sorting: Pages are sorted alphabetically, while posts are sorted by the publish date. Posts are visible as a list. They are not included in the navigation on the left side.
|
||||
|
12
content/02-news/index.yaml
Normal file
|
@ -0,0 +1,12 @@
|
|||
meta:
|
||||
navtitle: news
|
||||
title: 'Blog or News'
|
||||
description: 'You can add one or many blog- or news-sections to your website. Just create a new folder and change the content of the folder from "pages" to "posts" in the'
|
||||
owner: typemill
|
||||
author: ''
|
||||
modified: '2024-03-19'
|
||||
created: '2024-03-19'
|
||||
time: 19-12-31
|
||||
hide: false
|
||||
noindex: false
|
||||
contains: posts
|
|
@ -1,6 +1,6 @@
|
|||
# Typemill
|
||||
|
||||
The open-source flat-file cms for text-driven websites. Create handbooks, documentations, manuals, web-novels, traditional websites, and more.
|
||||
Typemill is a lightweight, flat-file CMS designed for simple, fast, and flexible website and eBook creation using Markdown. Create handbooks, documentations, manuals, reports, traditional websites, online novels, and more.
|
||||
|
||||
{#6i2-uv88gke .youtube}
|
||||
Stay in the loop and subscribe to the [Typemill newsletter](https://typemill.net/news)!
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
flatfilecms:
|
||||
title: 'Flat File CMS for simple projects'
|
||||
cover: media/live/cover-report.png
|
||||
description: 'Another publication from cmsstash that will uncover the secrets of database-less web publishing. Read about all flat file cms and make an informed choice.'
|
||||
downloadlabel: ''
|
||||
downloadurl: ''
|
||||
firstbuttonlabel: ''
|
||||
firstbuttonurl: ''
|
||||
secondbuttonlabel: ''
|
||||
secondbuttonurl: ''
|
||||
downloadlabel1: 'Download now'
|
||||
downloadlabel2: 'Buy on amazon'
|
||||
enterprisecms:
|
||||
title: 'Das CMS Drupal: Open Source für Enterprise'
|
||||
cover: ''
|
||||
description: ''
|
||||
downloadlabel: ''
|
||||
downloadurl: ''
|
||||
firstbuttonlabel: ''
|
||||
firstbuttonurl: ''
|
||||
secondbuttonlabel: ''
|
||||
secondbuttonurl: ''
|
6
data/security/securitylog.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
127.0.0.1;2024-03-25 21:48:49;login: wrong password
|
||||
127.0.0.1;2024-04-20 12:51:39;login: wrong password
|
||||
127.0.0.1;2024-04-21 19:24:11;login: invalid data
|
||||
127.0.0.1;2024-04-22 14:38:20;loginlink: loginlink for user member is not activated.
|
||||
127.0.0.1;2024-04-23 11:16:24;loginlink: invalid data
|
||||
127.0.0.1;2024-09-01 13:59:35;login: invalid data
|
5
docker-utils/init-server
Normal file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
find /var/www/html/content -type d -empty -exec cp -R /var/www/html/content.default/* /var/www/html/content \;
|
||||
find /var/www/html/themes -type d -empty -exec cp -R /var/www/html/themes.default/* /var/www/html/themes \;
|
||||
chown -R www-data:www-data /var/www/html/
|
||||
apache2-foreground
|
17
docker-utils/install-composer
Normal file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh
|
||||
|
||||
EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')"
|
||||
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
|
||||
|
||||
if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
|
||||
then
|
||||
>&2 echo 'ERROR: Invalid installer checksum'
|
||||
rm composer-setup.php
|
||||
exit 1
|
||||
fi
|
||||
|
||||
php composer-setup.php --quiet
|
||||
RESULT=$?
|
||||
rm composer-setup.php
|
||||
exit $RESULT
|
|
@ -2,6 +2,4 @@
|
|||
|
||||
require __DIR__ . '/system/vendor/autoload.php';
|
||||
|
||||
require __DIR__ . '/system/system.php';
|
||||
|
||||
$app->run();
|
||||
require __DIR__ . '/system/typemill/system.php';
|
|
@ -1,2 +1,4 @@
|
|||
media/files/preview.pdf: member
|
||||
media/files/ebook.epub: author
|
||||
media/files/typemill-v2-navigation.gif: member
|
||||
media/files/markdown.png: member
|
||||
media/files/wordpress-test.txt: contributor
|
||||
media/files/publii-test.txt: editor
|
||||
|
|
BIN
media/live/youtube-7yvlwxjl9dc-1.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
media/live/youtube-7yvlwxjl9dc-2.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
media/live/youtube-7yvlwxjl9dc.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
media/original/youtube-7yvlwxjl9dc-1.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
media/original/youtube-7yvlwxjl9dc-2.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
media/original/youtube-7yvlwxjl9dc.jpg
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
media/thumbs/youtube-7yvlwxjl9dc-1.jpg
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
media/thumbs/youtube-7yvlwxjl9dc-2.jpg
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
media/thumbs/youtube-7yvlwxjl9dc.jpg
Normal file
After Width: | Height: | Size: 3.7 KiB |
1539
package-lock.json
generated
|
@ -18,6 +18,7 @@
|
|||
},
|
||||
"homepage": "https://github.com/typemill/typemill#readme",
|
||||
"devDependencies": {
|
||||
"fs-extra": "^10.0.1"
|
||||
"fs-extra": "^10.0.1",
|
||||
"tailwindcss": "^3.1.6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
17
plugins/demo/DemoController.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Plugins\demo;
|
||||
|
||||
class demoController
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return die('I am the admin controller');
|
||||
}
|
||||
|
||||
public function wrong()
|
||||
{
|
||||
return die('I am the admin controller');
|
||||
}
|
||||
|
||||
}
|
12
plugins/demo/Text.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
namespace Plugins\Demo;
|
||||
|
||||
class Text
|
||||
{
|
||||
public function getText()
|
||||
{
|
||||
return 'I am the twig function';
|
||||
}
|
||||
|
||||
}
|
3
plugins/demo/css/demo.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
body{
|
||||
background: #000;
|
||||
}
|
400
plugins/demo/demo.php
Normal file
|
@ -0,0 +1,400 @@
|
|||
<?php
|
||||
|
||||
namespace Plugins\demo;
|
||||
|
||||
use Typemill\Plugin;
|
||||
use Typemill\Models\Validation;
|
||||
use Plugins\demo\demoController;
|
||||
use Plugins\Demo\Text;
|
||||
use Psr\Http\Message\ServerRequestInterface as Request;
|
||||
use Psr\Http\Message\ResponseInterface as Response;
|
||||
|
||||
class demo extends Plugin
|
||||
{
|
||||
# you can add a licence check here
|
||||
public static function setPremiumLicense()
|
||||
{
|
||||
# return false;
|
||||
return 'MAKER';
|
||||
# return 'BUSINESS';
|
||||
}
|
||||
|
||||
# you can subscribe to the following events
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return [
|
||||
|
||||
# all pages fired from system file
|
||||
'onSettingsLoaded' => ['onSettingsLoaded', 0],
|
||||
'onPluginsLoaded' => ['onPluginsLoaded', 0],
|
||||
'onSessionSegmentsLoaded' => ['onSessionSegmentsLoaded', 0],
|
||||
'onRolesPermissionsLoaded' => ['onRolesPermissionsLoaded', 0],
|
||||
'onResourcesLoaded' => ['onResourcesLoaded', 0],
|
||||
|
||||
# admin area fired from navigation model
|
||||
'onSystemnaviLoaded' => ['onSystemnaviLoaded', 0],
|
||||
|
||||
# all pages fired from controller
|
||||
'onTwigLoaded' => ['onTwigLoaded', 0],
|
||||
|
||||
# only content pages fired from parsedown extension and controllerApiShortcode????
|
||||
'onShortcodeFound' => ['onShortcodeFound', 0],
|
||||
|
||||
# frontend pages fired from ControllerWebFrontend
|
||||
'onPagetreeLoaded' => ['onPagetreeLoaded', 0],
|
||||
'onBreadcrumbLoaded' => ['onBreadcrumbLoaded', 0],
|
||||
'onItemLoaded' => ['onItemLoaded', 0],
|
||||
'onMarkdownLoaded' => ['onMarkdownLoaded', 0],
|
||||
'onMetaLoaded' => ['onMetaLoaded', 0],
|
||||
'onRestrictionsLoaded' => ['onRestrictionsLoaded', 0],
|
||||
'onContentArrayLoaded' => ['onContentArrayLoaded', 0],
|
||||
'onHtmlLoaded' => ['onHtmlLoaded', 0],
|
||||
'onPageReady' => ['onPageReady', 0]
|
||||
];
|
||||
}
|
||||
|
||||
# you can add new routes for public, api, or admin-area
|
||||
public static function addNewRoutes()
|
||||
{
|
||||
return [
|
||||
|
||||
# add a frontend route with a form
|
||||
[
|
||||
'httpMethod' => 'get',
|
||||
'route' => '/demo',
|
||||
'name' => 'demo.frontend',
|
||||
'class' => 'Plugins\demo\DemoController:index',
|
||||
# optionallly restrict page:
|
||||
# 'resource' => 'account',
|
||||
# 'privilege' => 'view'
|
||||
],
|
||||
|
||||
# add a frontend route to receive form data
|
||||
[
|
||||
'httpMethod' => 'post',
|
||||
'route' => '/demo',
|
||||
'name' => 'demo.send',
|
||||
'class' => 'Plugins\demo\DemoController:formdata',
|
||||
# optionallly restrict page:
|
||||
# 'resource' => 'account',
|
||||
# 'privilege' => 'view'
|
||||
],
|
||||
|
||||
# add an admin route
|
||||
[
|
||||
'httpMethod' => 'get',
|
||||
'route' => '/tm/demo',
|
||||
'name' => 'demo.admin',
|
||||
'class' => 'Typemill\Controllers\ControllerWebSystem:blankSystemPage',
|
||||
'resource' => 'system',
|
||||
'privilege' => 'view'
|
||||
],
|
||||
|
||||
# add an api route
|
||||
[
|
||||
'httpMethod' => 'get',
|
||||
'route' => '/api/v1/demo',
|
||||
'name' => 'demo.api',
|
||||
'class' => 'Plugins\demo\demo:getDemoData',
|
||||
'resource' => 'system',
|
||||
'privilege' => 'view'
|
||||
],
|
||||
|
||||
# add an api route
|
||||
[
|
||||
'httpMethod' => 'post',
|
||||
'route' => '/api/v1/demo',
|
||||
'name' => 'demo.api',
|
||||
'class' => 'Plugins\demo\demo:storeDemoData',
|
||||
'resource' => 'system',
|
||||
'privilege' => 'view'
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
# you can add new middleware function, for example
|
||||
public static function addNewMiddleware()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
# settings are read only, you do not need to return anything
|
||||
public function onSettingsLoaded($settings)
|
||||
{
|
||||
$data = $settings->getData();
|
||||
|
||||
# you also have access to settings from container through
|
||||
# $this->getSettings()
|
||||
|
||||
# or access to the plugin settings (optionally with pluginname)
|
||||
# $this->getPluginSettings()
|
||||
|
||||
}
|
||||
|
||||
|
||||
# use this if you have any dependencies with other plugins and want to check if they are active
|
||||
public function onPluginsLoaded($plugins)
|
||||
{
|
||||
$pluginnames = $plugins->getData();
|
||||
|
||||
$plugins->setData($pluginnames);
|
||||
}
|
||||
|
||||
|
||||
# you can add a new session segment in frontend, for example if you add frontend fomrs
|
||||
public function onSessionSegmentsLoaded($segments)
|
||||
{
|
||||
$arrayOfSegments = $segments->getData();
|
||||
|
||||
$segments->setData($arrayOfSegments);
|
||||
}
|
||||
|
||||
|
||||
# add new roles and permission
|
||||
public function onRolesPermissionsLoaded($rolespermissions)
|
||||
{
|
||||
$data = $rolespermissions->getData();
|
||||
|
||||
$rolespermissions->setData($data);
|
||||
}
|
||||
|
||||
|
||||
# add new resources for roles and permissions
|
||||
public function onResourcesLoaded($resources)
|
||||
{
|
||||
$data = $resources->getData();
|
||||
|
||||
$resources->setData($data);
|
||||
}
|
||||
|
||||
|
||||
# add new navi-items into the system area
|
||||
public function onSystemnaviLoaded($navidata)
|
||||
{
|
||||
$this->addSvgSymbol('<symbol id="icon-download" viewBox="0 0 24 24"><path d="M20 15v4c0 0.276-0.111 0.525-0.293 0.707s-0.431 0.293-0.707 0.293h-14c-0.276 0-0.525-0.111-0.707-0.293s-0.293-0.431-0.293-0.707v-4c0-0.552-0.448-1-1-1s-1 0.448-1 1v4c0 0.828 0.337 1.58 0.879 2.121s1.293 0.879 2.121 0.879h14c0.828 0 1.58-0.337 2.121-0.879s0.879-1.293 0.879-2.121v-4c0-0.552-0.448-1-1-1s-1 0.448-1 1zM13 12.586v-9.586c0-0.552-0.448-1-1-1s-1 0.448-1 1v9.586l-3.293-3.293c-0.391-0.391-1.024-0.391-1.414 0s-0.391 1.024 0 1.414l5 5c0.092 0.092 0.202 0.166 0.324 0.217s0.253 0.076 0.383 0.076c0.256 0 0.512-0.098 0.707-0.293l5-5c0.391-0.391 0.391-1.024 0-1.414s-1.024-0.391-1.414 0z"></path></symbol>');
|
||||
|
||||
$navi = $navidata->getData();
|
||||
|
||||
$navi['Demo'] = ['title' => 'Demo','routename' => 'demo.admin', 'icon' => 'icon-download', 'aclresource' => 'system', 'aclprivilege' => 'view'];
|
||||
|
||||
# if the use visits the system page of the plugin
|
||||
if(trim($this->route,"/") == 'tm/demo')
|
||||
{
|
||||
# set the navigation item active
|
||||
$navi['Demo']['active'] = true;
|
||||
|
||||
# add the system application
|
||||
$this->addJS('/demo/js/systemdemo.js');
|
||||
}
|
||||
|
||||
$navidata->setData($navi);
|
||||
}
|
||||
|
||||
|
||||
# the twig function is for everything you want to add and render in frontend
|
||||
public function onTwigLoaded()
|
||||
{
|
||||
if($this->editorroute)
|
||||
{
|
||||
$this->addJS('/demo/js/editordemo.js');
|
||||
}
|
||||
|
||||
# get the twig-object
|
||||
# $twig = $this->getTwig();
|
||||
|
||||
# get the twig-template-loader
|
||||
# $loader = $twig->getLoader();
|
||||
# $loader->addPath(__DIR__ . '/templates');
|
||||
|
||||
# return $twig->render($this->container['response'], '/demo.twig', ['data' => 'data']);
|
||||
|
||||
# you can add assets to all twig-views
|
||||
# $this->addInlineJS("console.info('my inline script;')");
|
||||
# $this->addJS('/demo/js/script.js');
|
||||
|
||||
# you can add styles to all twig-views
|
||||
# $this->addInlineCSS('h1{color:red;}');
|
||||
# $this->addCSS('/demo/css/demo.css');
|
||||
|
||||
# you can add your own global variables to all twig-views.
|
||||
# $this->addTwigGlobal('text', new Text());
|
||||
|
||||
# you can add your own filter function to twig.
|
||||
# $this->addTwigFilter('rot13', function ($string) {
|
||||
# return str_rot13($string);
|
||||
# });
|
||||
|
||||
# you can add your own function to a twig-views *
|
||||
# $this->addTwigFunction('myName', function(){
|
||||
# return 'My name is ';
|
||||
# });
|
||||
}
|
||||
|
||||
|
||||
# add a shortcode function to enhance the content area with new features
|
||||
public function onShortcodeFound($shortcode)
|
||||
{
|
||||
# read the data of the shortcode
|
||||
$shortcodeArray = $shortcode->getData();
|
||||
|
||||
# register your shortcode
|
||||
if(is_array($shortcodeArray) && $shortcodeArray['name'] == 'registershortcode')
|
||||
{
|
||||
$shortcodeArray['data']['contactform'] = [];
|
||||
|
||||
$shortcode->setData($shortcodeArray);
|
||||
}
|
||||
|
||||
# check if it is the shortcode name that we where looking for
|
||||
if(is_array($shortcodeArray) && $shortcodeArray['name'] == 'contactform')
|
||||
{
|
||||
# we found our shortcode, so stop firing the event to other plugins
|
||||
$shortcode->stopPropagation();
|
||||
|
||||
# get the public forms for the plugin
|
||||
$contactform = $this->generateForm('demo.send');
|
||||
# add to a page
|
||||
# add as shortcode
|
||||
# create new page
|
||||
|
||||
# and return a html-snippet that replaces the shortcode on the page.
|
||||
$shortcode->setData($contactform);
|
||||
}
|
||||
}
|
||||
|
||||
# returns an array of item-objects, that represents the neavigation
|
||||
public function onPagetreeLoaded($pagetree)
|
||||
{
|
||||
$data = $pagetree->getData();
|
||||
|
||||
$pagetree->setData($data);
|
||||
}
|
||||
|
||||
# returns array of item objects that represent the breadcrumb
|
||||
public function onBreadcrumbLoaded($breadcrumb)
|
||||
{
|
||||
$data = $breadcrumb->getData();
|
||||
|
||||
$breadcrumb->setData($data);
|
||||
}
|
||||
|
||||
# returns the item of the current page
|
||||
public function onItemLoaded($item)
|
||||
{
|
||||
$data = $item->getData();
|
||||
|
||||
$item->setData($data);
|
||||
}
|
||||
|
||||
# returns the markdown of the current page
|
||||
public function onMarkdownLoaded($markdown)
|
||||
{
|
||||
$data = $markdown->getData();
|
||||
|
||||
$markdown->setData($data);
|
||||
}
|
||||
|
||||
# returns the metadata (array) of the current page
|
||||
public function onMetaLoaded($meta)
|
||||
{
|
||||
$data = $meta->getData();
|
||||
|
||||
$meta->setData($data);
|
||||
}
|
||||
|
||||
# returns array with restriced role, defaultcontent and full markdown array
|
||||
public function onRestrictionsLoaded($restrictions)
|
||||
{
|
||||
$data = $restrictions->getData();
|
||||
|
||||
$restrictions->setData($data);
|
||||
}
|
||||
|
||||
# returns the full content with ormats as an array
|
||||
public function onContentArrayLoaded($contentArray)
|
||||
{
|
||||
$data = $contentArray->getData();
|
||||
|
||||
$contentArray->setData($data);
|
||||
}
|
||||
|
||||
# returns the full content as html
|
||||
public function onHtmlLoaded($html)
|
||||
{
|
||||
$data = $html->getData();
|
||||
|
||||
$html->setData($data);
|
||||
}
|
||||
|
||||
|
||||
# add a new page into the system area
|
||||
public function onPageReady($data)
|
||||
{
|
||||
/*
|
||||
# admin stuff
|
||||
if($this->adminroute && $this->route == 'tm/demo')
|
||||
{
|
||||
$this->addJS('/ebookproducts/js/vue-ebookproducts.js');
|
||||
|
||||
$pagedata = $data->getData();
|
||||
|
||||
$twig = $this->getTwig();
|
||||
$loader = $twig->getLoader();
|
||||
$loader->addPath(__DIR__ . '/templates');
|
||||
|
||||
# fetch the template and render it with twig
|
||||
$content = $twig->fetch('/ebookproducts.twig', []);
|
||||
|
||||
$pagedata['content'] = $content;
|
||||
|
||||
$data->setData($pagedata);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
#########################################
|
||||
# Add methods for new routes #
|
||||
#########################################
|
||||
|
||||
# gets the centrally stored ebook-data for ebook-plugin in settings-area
|
||||
public function getDemoData(Request $request, Response $response, $args)
|
||||
{
|
||||
# gets file from /data/demo automatically, use getPluginData or getPluginYamlData
|
||||
$formdata = $this->getPluginYamlData('demotest.yaml');
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'formdata' => $formdata
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
|
||||
# gets the centrally stored ebook-data for ebook-plugin in settings-area
|
||||
public function storeDemoData(Request $request, Response $response, $args)
|
||||
{
|
||||
$params = $request->getParsedBody();
|
||||
|
||||
# gets file from /data/demo automatically, use getPluginData or getPluginYamlData
|
||||
$result = $this->storePluginYamlData('demotest.yaml', $params['formdata']);
|
||||
|
||||
if($result !== true)
|
||||
{
|
||||
$response->getBody()->write(json_encode([
|
||||
'errors' => $result,
|
||||
'message' => 'please correct the errors in the form.'
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json')->withStatus(422);
|
||||
}
|
||||
|
||||
$response->getBody()->write(json_encode([
|
||||
'data' => $result,
|
||||
'message' => 'data stored successfully.'
|
||||
]));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
}
|
1
plugins/demo/demo.twig
Normal file
|
@ -0,0 +1 @@
|
|||
<h1>Hello</h1>
|
186
plugins/demo/demo.yaml
Normal file
|
@ -0,0 +1,186 @@
|
|||
name: Demo Plugin
|
||||
version: 1.0.0
|
||||
description: Demonstrates the power of Typemill Plugins
|
||||
author: Sebastian Schürmanns
|
||||
homepage: http://typemill.net
|
||||
license: MAKER
|
||||
dependencies:
|
||||
- register
|
||||
- mail
|
||||
|
||||
settings:
|
||||
theme: 'edgeless'
|
||||
message: 'You can enter a message here.'
|
||||
website: 'http://typemill.net'
|
||||
background: '#ffffff'
|
||||
|
||||
forms:
|
||||
fields:
|
||||
|
||||
text:
|
||||
type: text
|
||||
label: Text Input
|
||||
|
||||
message:
|
||||
type: textarea
|
||||
label: Message
|
||||
placeholder: 'Message for cookie-popup'
|
||||
required: true
|
||||
|
||||
code:
|
||||
type: codearea
|
||||
label: Code your stuff
|
||||
spellcheck: false
|
||||
|
||||
theme:
|
||||
type: select
|
||||
label: Select
|
||||
placeholder: 'Add name of theme'
|
||||
required: true
|
||||
options:
|
||||
edgeless: Edgeless
|
||||
block: Block
|
||||
classic: Classic
|
||||
mail: PHP Mail
|
||||
|
||||
userrole:
|
||||
type: select
|
||||
label: Which role should a new user get?
|
||||
dataset: userroles
|
||||
description: The standard userrole is "member". A member can only edit his account. Be careful if you select other roles.
|
||||
|
||||
number:
|
||||
type: number
|
||||
label: Number
|
||||
|
||||
date:
|
||||
type: date
|
||||
label: Date
|
||||
|
||||
email:
|
||||
type: email
|
||||
label: Email
|
||||
description: Please help me here.
|
||||
|
||||
tel:
|
||||
type: tel
|
||||
label: Phone number
|
||||
description: Please help me here.
|
||||
|
||||
pass:
|
||||
type: password
|
||||
label: Password
|
||||
description: Please help me here.
|
||||
|
||||
website:
|
||||
type: url
|
||||
label: Add valid url
|
||||
placeholder: 'Add valid URL'
|
||||
help: Please help me here or make me cry. I don't think that this is a good Idea, but we will see. Otherwise we will get this done.
|
||||
required: true
|
||||
|
||||
background:
|
||||
type: color
|
||||
label: Color
|
||||
placeholder: 'Add hex color value like #ffffff'
|
||||
required: true
|
||||
|
||||
singlecheckbox:
|
||||
type: checkbox
|
||||
label: Simple checkbox
|
||||
checkboxlabel: Please check me
|
||||
|
||||
multiplecheckbox:
|
||||
type: checkboxlist
|
||||
label: Multiple Checkboxes
|
||||
options:
|
||||
first: First
|
||||
second: Second
|
||||
third: Third
|
||||
fourth: Fourth
|
||||
|
||||
radio:
|
||||
type: radio
|
||||
label: Radio
|
||||
options:
|
||||
red: Red
|
||||
green: Green
|
||||
blue: Blue
|
||||
yellow: Yellow
|
||||
|
||||
mediaimage:
|
||||
type: image
|
||||
label: Upload image
|
||||
description: Please only upload some stuff you like.
|
||||
|
||||
metatabs:
|
||||
demo:
|
||||
fields:
|
||||
demoimage:
|
||||
type: image
|
||||
label: Image Field Demo
|
||||
description: Maximum size for an image is 5 MB. Hero images are not supported by all themes.
|
||||
demoimagealt:
|
||||
type: text
|
||||
label: Alt-Text for Hero-Image
|
||||
democheckbox:
|
||||
type: checkboxlist
|
||||
label: Multiple Checkboxes
|
||||
options:
|
||||
first: First
|
||||
second: Second
|
||||
third: Third
|
||||
fourth: Fourth
|
||||
democustomfield:
|
||||
type: customfields
|
||||
label: try it out
|
||||
data: array
|
||||
|
||||
system:
|
||||
fields:
|
||||
title:
|
||||
type: text
|
||||
label: Title of your eBook
|
||||
subtitle:
|
||||
type: text
|
||||
label: Subtitle of your eBook
|
||||
author:
|
||||
type: text
|
||||
label: Author
|
||||
edition:
|
||||
type: text
|
||||
label: Edition
|
||||
flytitle:
|
||||
type: checkbox
|
||||
label: Fly title
|
||||
checkboxlabel: Add a fly title after the cover.
|
||||
|
||||
public:
|
||||
fields:
|
||||
|
||||
name:
|
||||
type: text
|
||||
label: name_label
|
||||
required: true
|
||||
class: 'tm-input'
|
||||
|
||||
email:
|
||||
type: email
|
||||
label: email_label
|
||||
required: true
|
||||
class: 'tm-input'
|
||||
|
||||
subject:
|
||||
type: text
|
||||
label: subject_label
|
||||
required: true
|
||||
class: 'tm-input'
|
||||
|
||||
message:
|
||||
type: textarea
|
||||
label: message_label
|
||||
required: true
|
||||
class: 'tm-textarea'
|
||||
|
||||
legalnotice:
|
||||
type: paragraph
|
48
plugins/demo/js/editordemo.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
app.component('tab-demo', {
|
||||
props: ['item', 'formData', 'formDefinitions', 'saved', 'errors', 'message', 'messageClass'],
|
||||
template: `<section class="dark:bg-stone-700 dark:text-stone-200">
|
||||
<form>
|
||||
<div v-for="(fieldDefinition, fieldname) in formDefinitions.fields">
|
||||
<fieldset class="flex flex-wrap justify-between border-2 border-stone-200 p-4 my-8" v-if="fieldDefinition.type == 'fieldset'">
|
||||
<legend class="text-lg font-medium">{{ fieldDefinition.legend }}</legend>
|
||||
<component v-for="(subfieldDefinition, subfieldname) in fieldDefinition.fields"
|
||||
:key="subfieldname"
|
||||
:is="selectComponent(subfieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="subfieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[subfieldname]"
|
||||
v-bind="subfieldDefinition">
|
||||
</component>
|
||||
</fieldset>
|
||||
<component v-else
|
||||
:key="fieldname"
|
||||
:is="selectComponent(fieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="fieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[fieldname]"
|
||||
v-bind="fieldDefinition">
|
||||
</component>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<div class="block w-full h-8 my-1">
|
||||
<transition name="fade">
|
||||
<div v-if="message" :class="messageClass" class="text-white px-3 py-1 transition duration-100">{{ $filters.translate(message) }}</div>
|
||||
</transition>
|
||||
</div>
|
||||
<input type="submit" @click.prevent="saveInput()" :value="$filters.translate('save')" class="w-full p-3 my-1 bg-stone-700 dark:bg-stone-600 hover:bg-stone-900 hover:dark:bg-stone-900 text-white cursor-pointer transition duration-100">
|
||||
</div>
|
||||
</form>
|
||||
</section>`,
|
||||
methods: {
|
||||
selectComponent: function(type)
|
||||
{
|
||||
return 'component-' + type;
|
||||
},
|
||||
saveInput: function()
|
||||
{
|
||||
this.$emit('saveform');
|
||||
},
|
||||
}
|
||||
})
|
112
plugins/demo/js/systemdemo.js
Normal file
|
@ -0,0 +1,112 @@
|
|||
const app = Vue.createApp({
|
||||
template: `<Transition name="initial" appear>
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold mb-4">{{ plugin.name }}</h1>
|
||||
<form class="w-full my-8">
|
||||
<div v-for="(fieldDefinition, fieldname) in plugin.system.fields">
|
||||
<fieldset class="flex flex-wrap justify-between border-2 border-stone-200 p-4 my-8" v-if="fieldDefinition.type == 'fieldset'">
|
||||
<legend class="text-lg font-medium">{{ fieldDefinition.legend }}</legend>
|
||||
<component v-for="(subfieldDefinition, subfieldname) in fieldDefinition.fields"
|
||||
:key="subfieldname"
|
||||
:is="selectComponent(subfieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="subfieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[subfieldname]"
|
||||
v-bind="subfieldDefinition">
|
||||
</component>
|
||||
</fieldset>
|
||||
<component v-else
|
||||
:key="fieldname"
|
||||
:is="selectComponent(fieldDefinition.type)"
|
||||
:errors="errors"
|
||||
:name="fieldname"
|
||||
:userroles="userroles"
|
||||
:value="formData[fieldname]"
|
||||
v-bind="fieldDefinition">
|
||||
</component>
|
||||
</div>
|
||||
<div class="my-5">
|
||||
<div :class="messageClass" class="block w-full h-8 px-3 py-1 my-1 text-white transition duration-100">{{ $filters.translate(message) }}</div>
|
||||
<input type="submit" @click.prevent="save()" :value="$filters.translate('save')" class="w-full p-3 my-1 bg-stone-700 hover:bg-stone-900 text-white cursor-pointer transition duration-100">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</Transition>`,
|
||||
data() {
|
||||
return {
|
||||
plugin: data.plugin,
|
||||
formData: {'title': 'bla'},
|
||||
message: false,
|
||||
messageClass: '',
|
||||
errors: {},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
eventBus.$on('forminput', formdata => {
|
||||
this.formData[formdata.name] = formdata.value;
|
||||
});
|
||||
|
||||
var self = this;
|
||||
|
||||
tmaxios.get('/api/v1/demo',{
|
||||
params: {
|
||||
'url': data.urlinfo.route,
|
||||
}
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
if(response.data.formdata)
|
||||
{
|
||||
self.formData = response.data.formdata;
|
||||
}
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
methods: {
|
||||
selectComponent: function(type)
|
||||
{
|
||||
return 'component-'+type;
|
||||
},
|
||||
save: function()
|
||||
{
|
||||
this.reset();
|
||||
|
||||
var self = this;
|
||||
|
||||
tmaxios.post('/api/v1/demo',{
|
||||
'formdata': this.formData
|
||||
})
|
||||
.then(function (response)
|
||||
{
|
||||
self.messageClass = 'bg-teal-500';
|
||||
self.message = response.data.message;
|
||||
})
|
||||
.catch(function (error)
|
||||
{
|
||||
self.messageClass = 'bg-rose-500';
|
||||
self.message = error.response.data.message;
|
||||
if(error.response.data.errors !== undefined)
|
||||
{
|
||||
self.errors = error.response.data.errors;
|
||||
}
|
||||
});
|
||||
},
|
||||
reset: function()
|
||||
{
|
||||
this.errors = {};
|
||||
this.message = '';
|
||||
this.messageClass = '';
|
||||
}
|
||||
},
|
||||
})
|
1
plugins/demo/templates/demo.twig
Normal file
|
@ -0,0 +1 @@
|
|||
I am twig
|
1
plugins/search
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit d97fe18149958053a52e17ace38d486aea97433d
|
165
readme.md
|
@ -1,138 +1,89 @@
|
|||
# About TYPEMILL
|
||||
# Typemill: A Flat File CMS for Publishers
|
||||
|
||||
TYPEMILL is a lightweight flat file cms for micro-publishers. You can use it for documentations, manuals, special interest websites, and any other information-driven web-project. You can also enhance Typemill with plugins and generate professional e-books in pdf-format with it. The website http://typemill.net runs with Typemill.
|
||||
Typemill is a lightweight, flat-file CMS designed for simple, fast, and flexible website and eBook creation using Markdown.
|
||||
|
||||

|
||||

|
||||
|
||||
## Features
|
||||
With a focus on content and text, it perfectly fits use cases such as documentations, manuals, and other text-heavy websites.
|
||||
|
||||
* Website with markdown-files.
|
||||
* Visual markdown editor (VUE.js) and raw markdown mode.
|
||||
* Flexible drag & drop navigation.
|
||||
* Markdown extras with
|
||||
* table of contents (TOC)
|
||||
* tables
|
||||
* footnotes
|
||||
* abbreviations
|
||||
* definition lists
|
||||
* notices
|
||||
* math (with plugin)
|
||||
* figures with captions
|
||||
* Media library with images and files.
|
||||
* System configurations.
|
||||
* User management.
|
||||
* Flexible form management with YAML-files.
|
||||
* Flexible access rights.
|
||||
* Themes (with TWIG).
|
||||
* Plugins (with symfony event dispatcher).
|
||||
## Key Features (Selection)
|
||||
|
||||
Some plugin highlights are:
|
||||
* No database required (flat-file approach).
|
||||
* High performance, with a modern tech stack including Vue.js, Tailwind CSS, and Slim PHP.
|
||||
* Lightweight, with a gzip size of about 2MB.
|
||||
* Markdown editing with a visual block editor or a raw markdown editor.
|
||||
* Easy extendible with plugins, themes, and page-tabs.
|
||||
* Generation of ebooks (pdf, epub) with an ebook-plugin.
|
||||
* Flexible form-generation.
|
||||
* API-architecture and headless mode.
|
||||
|
||||
* **Ebooks**: Generate one or many professional pdf books from your typemill website.
|
||||
* **Register**: Let users register to your website and give them access to pro-content.
|
||||
* **Subscribe** (in work): Sell subscriptions for premium content with traditional pdf-invoices.
|
||||
## Resources
|
||||
|
||||
* Download and Documentation: [Typemill Website](https://typemill.net)
|
||||
* Plugins: [Typemill Plugins](https://plugins.typemill.net)
|
||||
* Themes: [Typemill Themes](https://themes.typemill.net)
|
||||
* Book Layouts: [Typemill Book Layouts](https://books.typemill.net)
|
||||
* Issues and Bug Reports: [GitHub Issues](https://github.com/typemill/typemill/issues)
|
||||
* Discussions: [GitHub Discussions](https://github.com/typemill/typemill/discussions)
|
||||
* Newsletter: [Typemill Newsletter](https://typemill.net/news)
|
||||
|
||||
## Requirements
|
||||
|
||||
* PHP 7+
|
||||
* Apache server
|
||||
* mod_rewrite and htaccess
|
||||
To run Typemill, you need the following:
|
||||
|
||||
If you run a linux system, then please double check that mod_rewrite and htaccess are active!!!
|
||||
* Web server (Apache, not tested on other servers).
|
||||
* PHP 8.0 or higher.
|
||||
* Standard PHP libraries like mod_rewrite, gd-image, mbstring, fileinfo, session, iconv, and more.
|
||||
|
||||
## Installation
|
||||
|
||||
Download TYPEMILL from the [TYPEMILL website](http://typemill.net), unzip the files and you are done.
|
||||
Check installations with different setups on [typemill.net](https://typemill.net/getting-started/installation)
|
||||
|
||||
If you are a developer, you can also clone this repository. To do so, open your command line, go to your project folder (e.g. htdocs) and type:
|
||||
### Using ZIP File and FTP
|
||||
|
||||
git clone git://github.com/trendschau/typemill.git
|
||||
1. Download and unpack the latest version of Typemill as a zip file from [Typemill Website](https://typemill.net).
|
||||
2. Upload all files to your server.
|
||||
3. Visit your new website at `www.your-typemill-website.com/tm/setup` and create an admin user.
|
||||
4. Log in and start publishing.
|
||||
|
||||
The GitHub-version has no vendor-folder, so you have to update and include all libraries and dependencies with composer. To do so, open your command line, go to your TYPEMILL folder and type:
|
||||
### Using GitHub and Composer
|
||||
|
||||
composer update
|
||||
Clone this repository:
|
||||
|
||||
If you did not use composer before, please go to the [composer website](http://getcomposer.org) and start to learn.
|
||||
```
|
||||
git clone https://github.com/typemill/typemill.git
|
||||
```
|
||||
|
||||
To run TYPEMILL on a **live** system, simply upload the files to your server
|
||||
Then update composer to load the libraries:
|
||||
|
||||
## Make Folders Writable.
|
||||
```
|
||||
composer update
|
||||
```
|
||||
|
||||
Make sure that the following folders and all their files are writable (permission 774 recursively):
|
||||
### Using Docker
|
||||
|
||||
* cache
|
||||
* content
|
||||
* media
|
||||
* settings
|
||||
See description on [typemill.net](https://typemill.net/getting-started/installation/docker)
|
||||
|
||||
You can use your ftp-software for that.
|
||||
## Folder Permissions
|
||||
|
||||
## Setup
|
||||
Ensure that the following folders are writable:
|
||||
|
||||
If you visit your website first, then you will be redirected to the `/setup` page. Please create an initial user and configure your system in the author panel.
|
||||
* `/cache`
|
||||
* `/content`
|
||||
* `/data`
|
||||
* `/media`
|
||||
* `/settings`
|
||||
|
||||
## Login
|
||||
## Tech Stack
|
||||
|
||||
You can find your login screen under `/tm/login` or simply go to `/setup` and you will be redirected to the login-page, if the setup has been finished.
|
||||
* PHP (Slim Framework Version 4)
|
||||
* JavaScript (Vue.js Version 3)
|
||||
* CSS (Tailwind)
|
||||
|
||||
## Documentation
|
||||
## Security Issues
|
||||
|
||||
You can read the full documentation for writers, for theme developers and for plugin developers on the [TYPEMILL website](http://typemill.net).
|
||||
If you discover a potential security issue related to Typemill, please report it via email to security@typemill.net, and we'll address it promptly.
|
||||
|
||||
## Licence
|
||||
## License
|
||||
|
||||
TYPEMILL is published under MIT licence. Please check the licence of the included libraries, too.
|
||||
|
||||
## Contributors & Supporters
|
||||
|
||||
* [Severo Iuliano](https://github.com/iusvar) manages the internationalization i18n.
|
||||
* [Eziquel Bruni](https://github.com/EzequielBruni) edits the typemill documentation.
|
||||
* [Ricky](https://github.com/rbertram90) developed the discard functionality.
|
||||
* [vodaris](https://www.vodaris.de) sponsored the development of the search plugin.
|
||||
* Translations:
|
||||
* Dutch: [svanlaere](https://github.com/svanlaere)
|
||||
* French: [Olivier Crouzet](https://github.com/oliviercrouzet)
|
||||
* German: [trendschau](https://github.com/trendschau)
|
||||
* Italian: [Severo Iuliano](https://github.com/iusvar)
|
||||
* Russian: [Hide-me](https://github.com/hide-me)
|
||||
|
||||
## IMPORTANT: How to Contribute
|
||||
|
||||
Contributions are highly welcome. Please follow these rules:
|
||||
|
||||
* If you plan bigger changes, then please create an issue first so we can discuss it.
|
||||
* Fork the "DEVELOP" branch from typemill. Never use the master branch, because it is protected and only contains tested releases.
|
||||
* Do your changes.
|
||||
* After that pull the recent develop branch again to get the latest changes.
|
||||
* Then make a pull request for the DEVELOP branch.
|
||||
|
||||
You can check the [roadmap for Typemill](https://github.com/typemill/typemill/issues/35) and scroll through the issues. I will mark issues in future that are easy to start with or where help is highly appreciated.
|
||||
|
||||
Here are some contribution-ideas for non-coder:
|
||||
|
||||
* Share Typemill with social media.
|
||||
* Write about Typemill.
|
||||
* Improve the documentation.
|
||||
* Find bugs and errors (open a new issue on github for it).
|
||||
* Describe some missing features and explain, why they are important for other users.
|
||||
|
||||
Some ideas for devs:
|
||||
|
||||
* Fix a bug.
|
||||
* Create or port a theme, especially for documentations, knowlegde bases or web-books.
|
||||
* Create a fancy plugin.
|
||||
* An auto-update functionality for the core system, for plugins and for themes is highly welcome.
|
||||
* Improve the accessibility of html and css.
|
||||
* Write autotests with Cypress.
|
||||
|
||||
For hints, questions, problems and support, please open up a new issue on GitHub.
|
||||
|
||||
## Support
|
||||
|
||||
This is an open source project. I love it and I spend about 20 hours a week on it (starting in 2017). There is no business model right now, but you can support this project with a donation or simply [hire me](https://trendschau.net) for implementations.
|
||||
|
||||
Donate: https://www.paypal.me/typemill
|
||||
|
||||
## Follow
|
||||
|
||||
Twitter: https://twitter.com/typemill
|
||||
Typemill is an open-source project published under the MIT License. Plugins, themes, and services are published under MIT and commercial licenses.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
''
|
9
settings/public_key.pem
Normal file
|
@ -0,0 +1,9 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuyT54vacgBn6HbzCQ2q4
|
||||
Bkxpp9ULqNrFckkoXRbp/NQK7d0jB8ah0NdElkWkUcZf6ax01a4DO7bfD81mF/wQ
|
||||
djtXn7UoCBkE/wyrFfZ/A9FGAnXekosogguWFTpctN7mFsDoX07RfDrvrXq020hb
|
||||
uZPpX/XQrPs6e6N8m9plDzAcqiZdx9XdvvZlzXnqQTNLcPsnQhzVMrxwGKJ5DTez
|
||||
/YwaZoK3UrzWdcsW+teIG9uacIrK4txVJ/i0+65p7iY1BeKxljdU2Daouo8ObgFV
|
||||
2jy5YTwJvIi5DJjupXb6V6C9mX3yfViul+30t8BMPDD+lf1Rx7Zp6fraYtx/ZDAo
|
||||
swIDAQAB
|
||||
-----END PUBLIC KEY-----
|
|
@ -1,305 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Typemill;
|
||||
|
||||
use Typemill\Models\ProcessImage;
|
||||
|
||||
class Assets
|
||||
{
|
||||
public $baseUrl;
|
||||
|
||||
public function __construct($baseUrl)
|
||||
{
|
||||
$this->baseUrl = $baseUrl;
|
||||
$this->JS = array();
|
||||
$this->CSS = array();
|
||||
$this->inlineJS = array();
|
||||
$this->inlineCSS = array();
|
||||
$this->editorJS = array();
|
||||
$this->editorCSS = array();
|
||||
$this->editorInlineJS = array();
|
||||
$this->svgSymbols = array();
|
||||
$this->meta = array();
|
||||
$this->imageUrl = false;
|
||||
$this->imageFolder = 'original';
|
||||
}
|
||||
|
||||
public function setUri($uri)
|
||||
{
|
||||
$this->uri = $uri;
|
||||
}
|
||||
|
||||
public function setBaseUrl($baseUrl)
|
||||
{
|
||||
$this->baseUrl = $baseUrl;
|
||||
}
|
||||
|
||||
public function image($url)
|
||||
{
|
||||
$this->imageUrl = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function resize($width,$height)
|
||||
{
|
||||
$pathinfo = pathinfo($this->imageUrl);
|
||||
$extension = strtolower($pathinfo['extension']);
|
||||
$imageName = $pathinfo['filename'];
|
||||
|
||||
$desiredSizes = ['custom' => []];
|
||||
|
||||
$resize = '-';
|
||||
|
||||
if(is_int($width) && $width < 10000)
|
||||
{
|
||||
$resize .= $width;
|
||||
$desiredSizes['custom']['width'] = $width;
|
||||
}
|
||||
|
||||
$resize .= 'x';
|
||||
|
||||
if(is_int($height) && $height < 10000)
|
||||
{
|
||||
$resize .= $height;
|
||||
$desiredSizes['custom']['height'] = $height;
|
||||
}
|
||||
|
||||
$processImage = new ProcessImage($desiredSizes);
|
||||
|
||||
$processImage->checkFolders('images');
|
||||
|
||||
$imageNameResized = $imageName . $resize;
|
||||
$imagePathResized = $processImage->customFolder . $imageNameResized . '.' . $extension;
|
||||
$imageUrlResized = 'media/custom/' . $imageNameResized . '.' . $extension;
|
||||
|
||||
if(!file_exists( $imagePathResized ))
|
||||
{
|
||||
# if custom version does not exist, use original version for resizing
|
||||
$imageFolder = ($this->imageFolder == 'original') ? $processImage->originalFolder : $processImage->customFolder;
|
||||
|
||||
$imagePath = $imageFolder . $pathinfo['basename'];
|
||||
|
||||
$resizedImage = $processImage->generateSizesFromImageFile($imageUrlResized, $imagePath);
|
||||
|
||||
$savedImage = $processImage->saveImage($processImage->customFolder, $resizedImage['custom'], $imageNameResized, $extension);
|
||||
|
||||
if(!$savedImage)
|
||||
{
|
||||
# return old image url without resize
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
# set folder to custom, so that the next method uses the correct (resized) version
|
||||
$this->imageFolder = 'custom';
|
||||
|
||||
$this->imageUrl = $imageUrlResized;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function grayscale()
|
||||
{
|
||||
$pathinfo = pathinfo($this->imageUrl);
|
||||
$extension = strtolower($pathinfo['extension']);
|
||||
$imageName = $pathinfo['filename'];
|
||||
|
||||
$processImage = new ProcessImage([]);
|
||||
|
||||
$processImage->checkFolders('images');
|
||||
|
||||
$imageNameGrayscale = $imageName . '-grayscale';
|
||||
$imagePathGrayscale = $processImage->customFolder . $imageNameGrayscale . '.' . $extension;
|
||||
$imageUrlGrayscale = 'media/custom/' . $imageNameGrayscale . '.' . $extension;
|
||||
|
||||
if(!file_exists( $imagePathGrayscale ))
|
||||
{
|
||||
# if custom-version does not exist, use live-version for grayscale-manipulation.
|
||||
$imageFolder = ($this->imageFolder == 'original') ? $processImage->liveFolder : $processImage->customFolder;
|
||||
|
||||
$imagePath = $imageFolder . $pathinfo['basename'];
|
||||
|
||||
$grayscaleImage = $processImage->grayscale($imagePath, $extension);
|
||||
|
||||
$savedImage = $processImage->saveImage($processImage->customFolder, $grayscaleImage, $imageNameGrayscale, $extension);
|
||||
|
||||
if(!$savedImage)
|
||||
{
|
||||
# return old image url without resize
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
# set folder to custom, so that the next method uses the correct (resized) version
|
||||
$this->imageFolder = 'custom';
|
||||
|
||||
$this->imageUrl = $imageUrlGrayscale;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function src()
|
||||
{
|
||||
# when we finish it, we shoud reset all settings
|
||||
$imagePath = $this->baseUrl . '/' . $this->imageUrl;
|
||||
$this->imageUrl = false;
|
||||
$this->imageFolder = 'original';
|
||||
|
||||
return $imagePath;
|
||||
}
|
||||
|
||||
public function addCSS($CSS)
|
||||
{
|
||||
$CSSfile = $this->getFileUrl($CSS);
|
||||
|
||||
if($CSSfile)
|
||||
{
|
||||
$this->CSS[] = '<link rel="stylesheet" href="' . $CSSfile . '" />';
|
||||
}
|
||||
}
|
||||
|
||||
public function addInlineCSS($CSS)
|
||||
{
|
||||
$this->inlineCSS[] = '<style>' . $CSS . '</style>';
|
||||
}
|
||||
|
||||
public function addJS($JS)
|
||||
{
|
||||
$JSfile = $this->getFileUrl($JS);
|
||||
|
||||
if($JSfile)
|
||||
{
|
||||
$this->JS[] = '<script src="' . $JSfile . '"></script>';
|
||||
}
|
||||
|
||||
# print_r($this->JS);
|
||||
}
|
||||
|
||||
public function addInlineJS($JS)
|
||||
{
|
||||
$this->inlineJS[] = '<script>' . $JS . '</script>';
|
||||
}
|
||||
|
||||
public function activateVue()
|
||||
{
|
||||
$vueUrl = '<script src="' . $this->baseUrl . '/system/author/js/vue.min.js"></script>';
|
||||
if(!in_array($vueUrl, $this->JS))
|
||||
{
|
||||
$this->JS[] = $vueUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public function activateAxios()
|
||||
{
|
||||
$axiosUrl = '<script src="' . $this->baseUrl . '/system/author/js/axios.min.js"></script>';
|
||||
if(!in_array($axiosUrl, $this->JS))
|
||||
{
|
||||
$this->JS[] = $axiosUrl;
|
||||
|
||||
$axios = '<script>const myaxios = axios.create({ baseURL: \'' . $this->baseUrl . '\' });</script>';
|
||||
$this->JS[] = $axios;
|
||||
}
|
||||
}
|
||||
|
||||
public function activateTachyons()
|
||||
{
|
||||
$tachyonsUrl = '<link rel="stylesheet" href="' . $this->baseUrl . '/system/author/css/tachyons.min.css" />';
|
||||
if(!in_array($tachyonsUrl, $this->CSS))
|
||||
{
|
||||
$this->CSS[] = $tachyonsUrl;
|
||||
}
|
||||
}
|
||||
|
||||
public function addSvgSymbol($symbol)
|
||||
{
|
||||
$this->svgSymbols[] = $symbol;
|
||||
}
|
||||
|
||||
# add JS to enhance the blox-editor in author area
|
||||
public function addEditorJS($JS)
|
||||
{
|
||||
$JSfile = $this->getFileUrl($JS);
|
||||
|
||||
if($JSfile)
|
||||
{
|
||||
$this->editorJS[] = '<script src="' . $JSfile . '"></script>';
|
||||
}
|
||||
}
|
||||
|
||||
public function addEditorInlineJS($JS)
|
||||
{
|
||||
$this->editorInlineJS[] = '<script>' . $JS . '</script>';
|
||||
}
|
||||
|
||||
public function addEditorCSS($CSS)
|
||||
{
|
||||
$CSSfile = $this->getFileUrl($CSS);
|
||||
|
||||
if($CSSfile)
|
||||
{
|
||||
$this->editorCSS[] = '<link rel="stylesheet" href="' . $CSSfile . '" />';
|
||||
}
|
||||
}
|
||||
|
||||
public function addMeta($key,$meta)
|
||||
{
|
||||
$this->meta[$key] = $meta;
|
||||
}
|
||||
|
||||
public function renderEditorJS()
|
||||
{
|
||||
return implode("\n", $this->editorJS) . implode("\n", $this->editorInlineJS);
|
||||
}
|
||||
|
||||
public function renderEditorCSS()
|
||||
{
|
||||
return implode("\n", $this->editorCSS);
|
||||
}
|
||||
|
||||
public function renderCSS()
|
||||
{
|
||||
return implode("\n", $this->CSS) . implode("\n", $this->inlineCSS);
|
||||
}
|
||||
|
||||
public function renderJS()
|
||||
{
|
||||
return implode("\n", $this->JS) . implode("\n", $this->inlineJS);
|
||||
}
|
||||
|
||||
public function renderSvg()
|
||||
{
|
||||
return implode('', $this->svgSymbols);
|
||||
}
|
||||
|
||||
public function renderMeta()
|
||||
{
|
||||
$metaLines = '';
|
||||
foreach($this->meta as $meta)
|
||||
{
|
||||
$metaLines .= "\n";
|
||||
$metaLines .= $meta;
|
||||
}
|
||||
return $metaLines;
|
||||
}
|
||||
/**
|
||||
* Checks, if a string is a valid internal or external ressource like js-file or css-file
|
||||
* @params $path string
|
||||
* @return string or false
|
||||
*/
|
||||
public function getFileUrl($path)
|
||||
{
|
||||
# check system path of file without parameter for fingerprinting
|
||||
$internalFile = __DIR__ . '/../plugins' . strtok($path, "?");
|
||||
|
||||
if(file_exists($internalFile))
|
||||
{
|
||||
return $this->baseUrl . '/plugins' . $path;
|
||||
}
|
||||
|
||||
return $path;
|
||||
|
||||
if(fopen($path, "r"))
|
||||
{
|
||||
return $path;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,340 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Typemill\Controllers;
|
||||
|
||||
use Typemill\Models\Folder;
|
||||
use Typemill\Models\WriteMeta;
|
||||
use Typemill\Models\WriteYaml;
|
||||
use Typemill\Models\Validation;
|
||||
|
||||
class ControllerAuthor extends ControllerShared
|
||||
{
|
||||
# holds the params from request
|
||||
protected $params;
|
||||
|
||||
# holds the slim-uri-object from request
|
||||
protected $uri;
|
||||
|
||||
# holds the errors to output in frontend
|
||||
protected $errors = false;
|
||||
|
||||
# holds informations about the homepage
|
||||
protected $homepage;
|
||||
|
||||
# hold the page-item as an object
|
||||
protected $item;
|
||||
|
||||
# hold the breadcrumb as an object
|
||||
protected $breadcrumb;
|
||||
|
||||
# holds the path to the requested file
|
||||
protected $path = false;
|
||||
|
||||
# holds the content of the page
|
||||
protected $content;
|
||||
|
||||
# holds the ownership (my content or not my content)
|
||||
protected $mycontent = false;
|
||||
|
||||
# author
|
||||
protected function getValidator()
|
||||
{
|
||||
return new Validation();
|
||||
}
|
||||
|
||||
# author
|
||||
protected function validateEditorInput()
|
||||
{
|
||||
$validate = new Validation();
|
||||
$vResult = $validate->editorInput($this->params);
|
||||
|
||||
if(is_array($vResult))
|
||||
{
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
|
||||
if(isset($message[0])){
|
||||
$this->errors['errors']['message'] = $message[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
# author
|
||||
protected function validateBlockInput()
|
||||
{
|
||||
$validate = new Validation();
|
||||
$vResult = $validate->blockInput($this->params);
|
||||
|
||||
if(is_array($vResult))
|
||||
{
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
|
||||
if(isset($message[0]))
|
||||
{
|
||||
$this->errors['errors']['message'] = $message[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
# author
|
||||
protected function validateNavigationSort()
|
||||
{
|
||||
$validate = new Validation();
|
||||
$vResult = $validate->navigationSort($this->params);
|
||||
|
||||
if(is_array($vResult))
|
||||
{
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
|
||||
if(isset($message[0])){
|
||||
$this->errors['errors']['message'] = $message[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
# author
|
||||
protected function validateNaviItem()
|
||||
{
|
||||
$validate = new Validation();
|
||||
$vResult = $validate->navigationItem($this->params);
|
||||
|
||||
if(is_array($vResult))
|
||||
{
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
|
||||
if(isset($message[0]))
|
||||
{
|
||||
$this->errors['errors']['message'] = $message[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
# author
|
||||
protected function validateBaseNaviItem()
|
||||
{
|
||||
$validate = new Validation();
|
||||
$vResult = $validate->navigationBaseItem($this->params);
|
||||
|
||||
if(is_array($vResult))
|
||||
{
|
||||
$message = reset($vResult);
|
||||
$this->errors = ['errors' => $vResult];
|
||||
|
||||
if(isset($message[0]))
|
||||
{
|
||||
$this->errors['errors']['message'] = $message[0];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function setHomepage($args)
|
||||
{
|
||||
$contentFolder = Folder::scanFolderFlat($this->settings['rootPath'] . $this->settings['contentFolder']);
|
||||
|
||||
if(in_array('index.md', $contentFolder))
|
||||
{
|
||||
$md = true;
|
||||
$status = 'published';
|
||||
}
|
||||
if(in_array('index.txt', $contentFolder))
|
||||
{
|
||||
$txt = true;
|
||||
$status = 'unpublished';
|
||||
}
|
||||
if(isset($txt) && isset($md))
|
||||
{
|
||||
$status = 'modified';
|
||||
}
|
||||
|
||||
$active = false;
|
||||
if($this->params['url'] == '/' || (is_array($args) && empty($args)))
|
||||
{
|
||||
$active = 'active';
|
||||
}
|
||||
|
||||
$this->homepage = ['status' => $status, 'active' => $active];
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function setItem()
|
||||
{
|
||||
# home is only set by backend controller, not by api calls
|
||||
$home = isset($this->homepage['active']) ? $this->homepage['active'] : false;
|
||||
|
||||
# search for the url in the structure
|
||||
$item = Folder::getItemForUrl($this->structureDraft, $this->params['url'], $this->uri->getBaseUrl(), NULL, $home);
|
||||
|
||||
if($item)
|
||||
{
|
||||
$this->item = $item;
|
||||
return true;
|
||||
}
|
||||
|
||||
$this->errors = ['errors' => ['message' => 'requested page-url not found']];
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
# determine if you want to write to published file (md) or to draft (txt)
|
||||
protected function setItemPath($fileType)
|
||||
{
|
||||
$this->path = $this->item->pathWithoutType . '.' . $fileType;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function setPublishStatus()
|
||||
{
|
||||
$this->item->published = false;
|
||||
$this->item->drafted = false;
|
||||
|
||||
if(file_exists($this->settings['rootPath'] . $this->settings['contentFolder'] . $this->item->pathWithoutType . '.md'))
|
||||
{
|
||||
$this->item->published = true;
|
||||
|
||||
# add file-type in case it is a folder
|
||||
$this->item->fileType = "md";
|
||||
}
|
||||
|
||||
if(file_exists($this->settings['rootPath'] . $this->settings['contentFolder'] . $this->item->pathWithoutType . '.txt'))
|
||||
{
|
||||
$this->item->drafted = true;
|
||||
|
||||
# add file-type in case it is a folder
|
||||
$this->item->fileType = "txt";
|
||||
}
|
||||
|
||||
if(!$this->item->drafted && !$this->item->published && $this->item->elementType == "folder")
|
||||
{
|
||||
# set txt as default for a folder, so that we can create an index.txt for a folder.
|
||||
$this->item->fileType = "txt";
|
||||
}
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function setContent()
|
||||
{
|
||||
# if the file exists
|
||||
if($this->item->published OR $this->item->drafted)
|
||||
{
|
||||
$content = $this->writeCache->getFile($this->settings['contentFolder'], $this->path);
|
||||
if($this->item->fileType == 'txt')
|
||||
{
|
||||
# decode the json-draft to an array
|
||||
$content = json_decode($content);
|
||||
}
|
||||
}
|
||||
elseif($this->item->elementType == "folder")
|
||||
{
|
||||
$content = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errors = ['errors' => ['message' => 'requested file not found']];
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->content = $content;
|
||||
return true;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function checkContentOwnership()
|
||||
{
|
||||
# get page meta
|
||||
$writeMeta = new writeMeta();
|
||||
$pagemeta = $writeMeta->getPageMeta($this->settings, $this->item);
|
||||
|
||||
# check ownership
|
||||
if(isset($pagemeta['meta']['owner']) && $pagemeta['meta']['owner'] && $pagemeta['meta']['owner'] !== '' )
|
||||
{
|
||||
$allowedusers = array_map('trim', explode(",", $pagemeta['meta']['owner']));
|
||||
if(isset($_SESSION['user']) && in_array($_SESSION['user'], $allowedusers))
|
||||
{
|
||||
$this->mycontent = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function deleteContentFiles($fileTypes, $folder = false)
|
||||
{
|
||||
$basePath = $this->settings['rootPath'] . $this->settings['contentFolder'];
|
||||
|
||||
foreach($fileTypes as $fileType)
|
||||
{
|
||||
if(file_exists($basePath . $this->item->pathWithoutType . '.' . $fileType) && !unlink($basePath . $this->item->pathWithoutType . '.' . $fileType) )
|
||||
{
|
||||
$this->errors = ['message' => 'We could not delete the file, please check, if the file is writable.'];
|
||||
}
|
||||
}
|
||||
|
||||
if($this->errors)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
# only backoffice
|
||||
protected function deleteContentFolder()
|
||||
{
|
||||
$basePath = $this->settings['rootPath'] . $this->settings['contentFolder'];
|
||||
$path = $basePath . $this->item->path;
|
||||
|
||||
if(file_exists($path))
|
||||
{
|
||||
$files = array_diff(scandir($path), array('.', '..'));
|
||||
|
||||
# check if there are published pages or folders inside, then stop the operation
|
||||
foreach ($files as $file)
|
||||
{
|
||||
if(is_dir(realpath($path) . DIRECTORY_SEPARATOR . $file))
|
||||
{
|
||||
$this->errors = ['message' => 'Please delete the sub-folder first.'];
|
||||
}
|
||||
|
||||
if(substr($file, -3) == '.md' && $file != 'index.md')
|
||||
{
|
||||
$this->errors = ['message' => 'Please unpublish all pages in the folder first.'];
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->errors)
|
||||
{
|
||||
foreach ($files as $file)
|
||||
{
|
||||
unlink(realpath($path) . DIRECTORY_SEPARATOR . $file);
|
||||
}
|
||||
return rmdir($path);
|
||||
}
|
||||
|
||||
# delete all files from the extended file
|
||||
$this->deleteFromExtended();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|